1. Extending and Scripting PDT
William Candillon {wcandillon@elv.telecom-lille1.eu}
PHP London meeting, June 2009
2. Who am I ?
• Engineering student at Telecom Lille 1
• ETH Zurich: XQuery runtime in C++
• Aspect PHP Development Toolkit:
http://apdt.googlecode.com
3. Who are you ?
• What is your favorite IDE?
• VIM?
• Netbeans?
• Komodo?
• PHPEd?
• PDT / Zend Studio?
4. The Long Tail
Support
PHP
XDebug
PEAR How to scale?
PHP Unit
Zend framework
frameworks
Business libraries
test/build systems
Development rules
General Specific
5. Eclipse galaxy
Frameworks Languages and modeling
ECF
GEF
OCL
ALF EMF
DTK
WTP UML
GMF
DTP
PDE
MTJ RCP
Eclipse
EPF SVN
J2EE
Applications
JDT MAVEN
TPTP
CDT ANT
PDT MYLYN Development tasks
Programming RDT
AJDT
languages
APDT
Plug-ins ecosystem (+ 1000)
6. Architecture
Un autre
Eclipse Platform Help Outil
Java Workbench
Development
Tools JFace
(JDT) Team
SWT
Votre
Outil
Debug
Plug-in
Workspace
Development
Environment
(PDE)
Update
Notre
Equinox (OSGI) Outil
JVM
7. PHP Development Toolkit
• Developped by Zend and IBM since 2006
• December 2008: version 2.0
• Second most popular project on eclipse.org
• 100% under the EPL (Eclipse Public License)
• Build on top of DLTK (Dynamic Language Toolkit)
8. Objectives
• De-facto standard for PHP developments
• Providing extension points and APIs to support
PHP tools...
• ...from the last hot PHP framework to the best
practices of your company!
14. Code refactoring
• Abstract model of a PHP program
• AST representation of source code
• Tree walking and manipulation
• Extensible type inference engine
16. Use case
• Objective: ensuring a simple development rule
• Never trust your inputs!
• Finding and fixing the bug...
• ...in the coolest manner
17. Step 1
• Strategy: extending PDT building process with our
own build participant
• Registering the contribution
18. Step 2
• Build participant factory
public class BuildParticipantFactory implements IBuildParticipantFactory {
public IBuildParticipant createBuildParticipant(IScriptProject project){
return new XSSProtectionParticipant();
}
}
• Build participant
public void build(IBuildContext context) throws CoreException{
ISourceModule sourceModule = context.getSourceModule();
ModuleDeclaration moduleDeclaration =
SourceParserUtil.getModuleDeclaration(sourceModule); Traverse the PHP AST
try {
moduleDeclaration.traverse(new XSSValidationVisitor(context));
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, ExamplePlugin.PLUGIN_ID, quot;An error
has occurred while invoking XSS validatorquot;, e));
}
}
19. Step 3
Module
Declaration
• Trasverse the AST
........
• If the node is safe, don’t visit child nodes
public boolean visit(PHPCallExpression node) throws Exception {
if (node.getReceiver() == null) { // if this is a function call, not method
String funcName = node.getName();
if (quot;issetquot;.equalsIgnoreCase(funcName)) {
Call
}
return false; Expression
return false;
}
........
• Check variable references of globals
protected boolean isURLParemeterVariable(VariableReference s) {
String name = s.getName();
return (quot;$_GETquot;.equals(name) || quot;$_POSTquot;.equals(name)); Variable
}
Reference
public boolean visit(ArrayVariableReference s) throws Exception {
if(isURLParemeterVariable(s)) {
context.getProblemReporter().reportProblem(new DefaultProblem(context.getFile().getName(),
quot;Unsafe use of quot; + s.getName() + quot;: possible XSS attackquot;,
XSSProblem.UNSAFE_GLOBAL_REFERENCE.ordinal(),
new String[0], ProblemSeverities.Error, s.sourceStart(), s.sourceEnd(),
context.getLineTracker().getLineNumberOfOffset(s.sourceStart()))
);
20. Result
• Invalid PHP project
• Mission accomplished!
21. Let’s digg it
• PHP Quick Fix
• Quick Fix proposal interface
public interface IQuickFixProcessor
{
boolean hasCorrections(ISourceModule, int problemId);
IScriptCompletionProposal[] getCorrections(IInvocationContext, IProblemLocation[]);
}
22. Result
• hasCorrection() checks if correction are availables
• getCorrection() returns a collection of corrections
• apply(document), performs the AST rewriting
23. Programming is hard...
• ...Go scripting!
• PHP Developpers need to extend Eclipse
• Without getting close to Java
• In a dynamic manner
• Eclipse e4, the next generation of Eclipse
• Provides support for JavaScript bundles
• Dynamic execution and deployment model
• Usage: Task automation, glue between plugins,
scripting workflows, etc.
24. The recipie
• Extension Registry
• JavaScript source and Java bridge
function helloworld() {
var object = {
run: function (action){
Packages.org.eclipse.jface.dialogs.MessageDialog.openInformation(
this.window.getShell(),
'TestJavascriptPlugin', 'Hello, Eclipse world');
},
dispose: function(){},
init: function(window) { this.window = window },
selectionChanged: function(action, selection){}
};
return new JavaAdapter(Packages.org.eclipse.ui.IWorkbenchWindowActionDelegate, o);
}
25. Dynamic deployment
• JavaScript Plug-in Development Environment
(http://jspde.googlecode.com)
• Support JavaScript Plugins
• Dynamic deployment
26. Conclusion
• Extension mechanisms to integrate:
• PHP frameworks and tools
• Development workflows
• PHP 5.3 support
• Towards customized PDT distribution
• Writing PHP plugins with PHP ?
27. Resources
• PDT website
• Extending and Scripting PDT tutorial
• Eclipse e4, JavaScript support
• PDT adopter’s
• Aspect PHP Development Toolkit
• Smarty