diff --git a/build.gradle b/build.gradle index 802fbff9e..46e5c8257 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ def javaVersion = '1.6'; -def projectVersion = '0.6.4'; +def projectVersion = '0.6.5'; buildscript { repositories { diff --git a/docs b/docs index 5cc90ada3..99e969dde 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit 5cc90ada326906cda3c8fac420971aab25dffd9f +Subproject commit 99e969dde3e2e7d8503346c010cbfb3a2b8bc811 diff --git a/jphp-jsoup-ext/build.gradle b/jphp-jsoup-ext/build.gradle index 2dd946ad6..fa3d2dec0 100644 --- a/jphp-jsoup-ext/build.gradle +++ b/jphp-jsoup-ext/build.gradle @@ -2,5 +2,9 @@ dependencies { compile project(':jphp-runtime') - compile 'org.jsoup:jsoup:1.8.1' + compile 'org.jsoup:jsoup:1.8.2' + + testCompile 'junit:junit:4.+' + testCompile project(':jphp-zend-ext') + testCompile project(':jphp-core').sourceSets.test.output } \ No newline at end of file diff --git a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/JsoupExtension.java b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/JsoupExtension.java index 0334b5e4a..68e8d4d38 100644 --- a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/JsoupExtension.java +++ b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/JsoupExtension.java @@ -12,7 +12,7 @@ import php.runtime.memory.support.MemoryOperation; public class JsoupExtension extends Extension { - public static final String NAMESPACE = "php\\jsoup\\"; + public static final String NS = "php\\jsoup"; @Override public Status getStatus() { diff --git a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapConnection.java b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapConnection.java index 74b5cc9c8..0de2f968d 100644 --- a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapConnection.java +++ b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapConnection.java @@ -14,21 +14,11 @@ import static org.jsoup.Connection.Response; import static php.runtime.annotation.Reflection.*; -@Name(JsoupExtension.NAMESPACE + "Connection") -@WrapInterface(WrapConnection.Methods.class) +@Abstract +@Name("Connection") +@Namespace(JsoupExtension.NS) public class WrapConnection extends BaseWrapper { - public static final String METHOD_POST = "POST"; - public static final String METHOD_GET = "GET"; - - public WrapConnection(Environment env, Connection object) { - super(env, object); - } - - public WrapConnection(Environment env, ClassEntity clazz) { - super(env, clazz); - } - - public interface Methods { + public interface WrappedInterface { Connection url(String url); Connection userAgent(String userAgent); Connection timeout(int millis); @@ -50,4 +40,15 @@ public interface Methods { Response response(); Connection response(Response response); } + + public static final String METHOD_POST = "POST"; + public static final String METHOD_GET = "GET"; + + public WrapConnection(Environment env, Connection object) { + super(env, object); + } + + public WrapConnection(Environment env, ClassEntity clazz) { + super(env, clazz); + } } diff --git a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapConnectionRequest.java b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapConnectionRequest.java index d6bd4c13e..2d35f9590 100644 --- a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapConnectionRequest.java +++ b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapConnectionRequest.java @@ -2,27 +2,20 @@ import org.develnext.jphp.ext.jsoup.JsoupExtension; import php.runtime.annotation.Reflection; +import php.runtime.annotation.Reflection.Abstract; +import php.runtime.annotation.Reflection.Namespace; import php.runtime.env.Environment; import php.runtime.lang.BaseWrapper; import php.runtime.reflection.ClassEntity; -import java.util.Collection; - import static org.jsoup.Connection.Request; import static php.runtime.annotation.Reflection.Name; -@Name(JsoupExtension.NAMESPACE + "ConnectionRequest") -@Reflection.WrapInterface(WrapConnectionRequest.Methods.class) +@Abstract +@Name("ConnectionRequest") +@Namespace(JsoupExtension.NS) public class WrapConnectionRequest extends BaseWrapper { - public WrapConnectionRequest(Environment env, Request object) { - super(env, object); - } - - public WrapConnectionRequest(Environment env, ClassEntity clazz) { - super(env, clazz); - } - - public interface Methods { + public interface WrappedInterface { public int timeout(); public Request timeout(int millis); @@ -38,4 +31,12 @@ public interface Methods { public boolean ignoreContentType(); public Request ignoreContentType(boolean ignoreContentType); } + + public WrapConnectionRequest(Environment env, Request object) { + super(env, object); + } + + public WrapConnectionRequest(Environment env, ClassEntity clazz) { + super(env, clazz); + } } diff --git a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapConnectionResponse.java b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapConnectionResponse.java index 542e72ed8..0ec996f9f 100644 --- a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapConnectionResponse.java +++ b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapConnectionResponse.java @@ -2,23 +2,20 @@ import org.develnext.jphp.ext.jsoup.JsoupExtension; import org.jsoup.Connection; -import org.jsoup.nodes.Document; -import php.runtime.Memory; import php.runtime.annotation.Reflection; +import php.runtime.annotation.Reflection.Abstract; +import php.runtime.annotation.Reflection.Namespace; +import php.runtime.annotation.Reflection.WrapInterface; import php.runtime.env.Environment; import php.runtime.lang.BaseWrapper; -import php.runtime.memory.BinaryMemory; -import php.runtime.memory.LongMemory; -import php.runtime.memory.StringMemory; import php.runtime.reflection.ClassEntity; -import java.io.IOException; - import static php.runtime.annotation.Reflection.Name; -import static php.runtime.annotation.Reflection.Signature; -@Name(JsoupExtension.NAMESPACE + "ConnectionResponse") -@Reflection.WrapInterface(Connection.Response.class) +@Abstract +@Name("ConnectionResponse") +@Namespace(JsoupExtension.NS) +@WrapInterface(Connection.Response.class) public class WrapConnectionResponse extends BaseWrapper { public WrapConnectionResponse(Environment env, Connection.Response object) { super(env, object); diff --git a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapDocument.java b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapDocument.java index 14aa4855e..45264c4f3 100644 --- a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapDocument.java +++ b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapDocument.java @@ -1,28 +1,24 @@ package org.develnext.jphp.ext.jsoup.classes; import org.develnext.jphp.ext.jsoup.JsoupExtension; -import org.jsoup.Connection; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; import php.runtime.annotation.Reflection; +import php.runtime.annotation.Reflection.Abstract; +import php.runtime.annotation.Reflection.Namespace; +import php.runtime.annotation.Reflection.Signature; import php.runtime.env.Environment; import php.runtime.lang.BaseWrapper; import php.runtime.reflection.ClassEntity; import static php.runtime.annotation.Reflection.Name; -@Name(JsoupExtension.NAMESPACE + "Document") -@Reflection.WrapInterface(WrapDocument.Methods.class) +@Abstract +@Name("Document") +@Namespace(JsoupExtension.NS) public class WrapDocument extends BaseWrapper { - public WrapDocument(Environment env, Document object) { - super(env, object); - } - - public WrapDocument(Environment env, ClassEntity clazz) { - super(env, clazz); - } - - public interface Methods { + public interface WrappedInterface { String location(); Element head(); @@ -40,4 +36,17 @@ public interface Methods { Element clone(); } + + public WrapDocument(Environment env, Document object) { + super(env, object); + } + + public WrapDocument(Environment env, ClassEntity clazz) { + super(env, clazz); + } + + @Signature + public Elements select(String query) { + return getWrappedObject().select(query); + } } diff --git a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapElement.java b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapElement.java index c0d7a0dae..aa5e135e4 100644 --- a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapElement.java +++ b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapElement.java @@ -1,10 +1,12 @@ package org.develnext.jphp.ext.jsoup.classes; import org.develnext.jphp.ext.jsoup.JsoupExtension; -import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import php.runtime.annotation.Reflection; +import php.runtime.annotation.Reflection.Abstract; +import php.runtime.annotation.Reflection.Namespace; +import php.runtime.annotation.Reflection.Signature; import php.runtime.env.Environment; import php.runtime.env.TraceInfo; import php.runtime.lang.BaseWrapper; @@ -17,8 +19,9 @@ import static php.runtime.annotation.Reflection.Name; -@Name(JsoupExtension.NAMESPACE + "Element") -@Reflection.WrapInterface(WrapElement.Methods.class) +@Abstract +@Name("Element") +@Namespace(JsoupExtension.NS) public class WrapElement extends BaseWrapper implements ICloneableObject { public WrapElement(Environment env, Element object) { super(env, object); @@ -33,7 +36,17 @@ public WrapElement __clone(Environment environment, TraceInfo traceInfo) { return new WrapElement(environment, __wrappedObject.clone()); } - interface Methods { + @Signature + public String attr(String name) { + return getWrappedObject().attr(name); + } + + @Signature + public void attr(String name, String value) { + getWrappedObject().attr(name, value); + } + + interface WrappedInterface { String nodeName(); String tagName(); @@ -43,8 +56,6 @@ interface Methods { String id(); - Element attr(String attributeKey, String attributeValue); - Map dataset(); Element parent(); diff --git a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapElements.java b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapElements.java index b6959d4d0..5db19fb0d 100644 --- a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapElements.java +++ b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapElements.java @@ -5,11 +5,13 @@ import org.jsoup.select.Elements; import php.runtime.Memory; import php.runtime.annotation.Reflection; +import php.runtime.annotation.Reflection.Abstract; +import php.runtime.annotation.Reflection.Namespace; +import php.runtime.annotation.Reflection.Signature; import php.runtime.env.Environment; import php.runtime.lang.BaseWrapper; import php.runtime.lang.ForeachIterator; -import php.runtime.lang.spl.Traversable; -import php.runtime.lang.spl.iterator.IteratorAggregate; +import php.runtime.memory.LongMemory; import php.runtime.memory.ObjectMemory; import php.runtime.reflection.ClassEntity; @@ -17,39 +19,11 @@ import static php.runtime.annotation.Reflection.Name; -@Name(JsoupExtension.NAMESPACE + "Elements") -@Reflection.WrapInterface(WrapElements.Methods.class) -public class WrapElements extends BaseWrapper implements Iterable { - public WrapElements(Environment env, Elements wrappedObject) { - super(env, wrappedObject); - } - - public WrapElements(Environment env, ClassEntity clazz) { - super(env, clazz); - } - - @Override - public Iterator iterator() { - final Iterator iterator = getWrappedObject().iterator(); - return new Iterator() { - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public Memory next() { - return new ObjectMemory(new WrapElement(getEnvironment(), iterator.next())); - } - - @Override - public void remove() { - iterator.remove(); - } - }; - } - - interface Methods { +@Abstract +@Name("Elements") +@Namespace(JsoupExtension.NS) +public class WrapElements extends BaseWrapper implements php.runtime.lang.spl.iterator.Iterator { + interface WrappedInterface { String attr(String attributeKey); boolean hasAttr(String attributeKey); Elements attr(String attributeKey, String attributeValue); @@ -86,4 +60,76 @@ interface Methods { Element first(); Element last(); } + + protected Iterator iterator; + protected WrapElement iteratorValue = null; + protected int iteratorIndex = 0; + + public WrapElements(Environment env, Elements wrappedObject) { + super(env, wrappedObject); + + iterator = wrappedObject.iterator(); + + if (iterator.hasNext()) { + iteratorValue = new WrapElement(env, iterator.next()); + } + } + + public WrapElements(Environment env, ClassEntity clazz) { + super(env, clazz); + } + + @Override + @Signature + public Memory current(Environment env, Memory... args) { + return ObjectMemory.valueOf(iteratorValue); + } + + @Override + @Signature + public Memory key(Environment env, Memory... args) { + return iteratorValue == null ? Memory.FALSE : LongMemory.valueOf(iteratorIndex); + } + + @Override + @Signature + public Memory next(Environment env, Memory... args) { + if (iterator.hasNext()) { + iteratorValue = new WrapElement(env, iterator.next()); + iteratorIndex += 1; + } else { + iteratorValue = null; + } + + return Memory.NULL; + } + + @Override + @Signature + public Memory rewind(Environment env, Memory... args) { + iterator = getWrappedObject().iterator(); + if (iterator.hasNext()) { + iteratorValue = new WrapElement(env, iterator.next()); + } + + iteratorIndex = 0; + + return Memory.NULL; + } + + @Override + @Signature + public Memory valid(Environment env, Memory... args) { + return iteratorValue != null ? Memory.TRUE : Memory.FALSE; + } + + @Override + public ForeachIterator getNewIterator(Environment env, boolean getReferences, boolean getKeyReferences) { + return ObjectMemory.valueOf(this).getNewIterator(env, getReferences, getKeyReferences); + } + + @Override + public ForeachIterator getNewIterator(Environment env) { + return ObjectMemory.valueOf(this).getNewIterator(env); + } } diff --git a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapJsoup.java b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapJsoup.java index 6596be9d7..3a76eec7c 100644 --- a/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapJsoup.java +++ b/jphp-jsoup-ext/src/main/java/org/develnext/jphp/ext/jsoup/classes/WrapJsoup.java @@ -3,29 +3,56 @@ import org.develnext.jphp.ext.jsoup.JsoupExtension; import org.jsoup.Connection; import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; import php.runtime.Memory; +import php.runtime.annotation.Reflection; +import php.runtime.annotation.Reflection.Namespace; import php.runtime.env.Environment; +import php.runtime.ext.core.classes.stream.Stream; import php.runtime.lang.BaseObject; -import php.runtime.memory.ObjectMemory; import php.runtime.reflection.ClassEntity; -import static php.runtime.annotation.Reflection.Arg; +import java.io.IOException; +import java.io.InputStream; + import static php.runtime.annotation.Reflection.Name; import static php.runtime.annotation.Reflection.Signature; -@Name(JsoupExtension.NAMESPACE + "Jsoup") +@Name("Jsoup") +@Namespace(JsoupExtension.NS) final public class WrapJsoup extends BaseObject { public WrapJsoup(Environment env, ClassEntity clazz) { super(env, clazz); } @Signature - private Memory __construct(Environment env, Memory... args) { - return Memory.NULL; + private void __construct() { + // nop. } @Signature public static Connection connect(String url) { return Jsoup.connect(url); } + + @Signature + public static Document parse(Environment env, Memory source, String encoding, String baseUri) throws IOException { + InputStream is = Stream.getInputStream(env, source); + + try { + return Jsoup.parse(is, encoding, baseUri); + } finally { + Stream.closeStream(env, is); + } + } + + @Signature + public static Document parseText(String text) { + return Jsoup.parse(text); + } + + @Signature + public static Document parseText(String text, String baseUri) { + return Jsoup.parse(text, baseUri); + } } diff --git a/jphp-jsoup-ext/src/main/resources/JPHP-INF/sdk/php/jsoup/Connection.php b/jphp-jsoup-ext/src/main/resources/JPHP-INF/sdk/php/jsoup/Connection.php index 76a1fb5e8..4bedbd606 100644 --- a/jphp-jsoup-ext/src/main/resources/JPHP-INF/sdk/php/jsoup/Connection.php +++ b/jphp-jsoup-ext/src/main/resources/JPHP-INF/sdk/php/jsoup/Connection.php @@ -5,54 +5,141 @@ * Class Connection * @package php\jsoup */ -class Connection { +abstract class Connection +{ const METHOD_POST = 'POST'; - const METHOD_GET = 'GET'; + const METHOD_GET = 'GET'; /** * @param array $data * @return Connection */ - public function data(array $data) { } + public function data(array $data) + { + } /** * @param array $data * @return Connection */ - public function cookies(array $data) { } + public function cookies(array $data) + { + } /** * @param array $data * @return Connection */ - public function headers(array $data) { } + public function headers(array $data) + { + } /** * @param string $url * @return Connection */ - public function url($url) { } + public function url($url) + { + } /** * @param string $method POST or GET * @return Connection */ - public function method($method) { } + public function method($method) + { + } + + /** + * @param string $userAgent + * @return Connection + */ + public function userAgent($userAgent) + { + } + + /** + * @param int $bytes + * @return Connection + */ + public function maxBodySize($bytes) + { + } + + /** + * @param int $millis + * @return Connection + */ + public function timeout($millis) + { + } + + /** + * @param string $referrer + * @return Connection + */ + public function referrer($referrer) + { + } + + /** + * @param bool $enable + * @return Connection + */ + public function followRedirects($enable) + { + } + + /** + * @param bool $enable + * @return Connection + */ + public function ignoreHttpErrors($enable) + { + } + + /** + * @param bool $enable + * @return Connection + */ + public function ignoreContentType($enable) + { + } /** * @return ConnectionResponse */ - public function execute() { } + public function execute() + { + } /** * * @return Document */ - public function get() { } + public function get() + { + } /** * * @return Document */ - public function post() { } + public function post() + { + } + + /** + * @return ConnectionRequest + */ + public function request() + { + } + + /** + * @return ConnectionResponse + */ + public function response() + { + } } \ No newline at end of file diff --git a/jphp-jsoup-ext/src/main/resources/JPHP-INF/sdk/php/jsoup/ConnectionRequest.php b/jphp-jsoup-ext/src/main/resources/JPHP-INF/sdk/php/jsoup/ConnectionRequest.php new file mode 100644 index 000000000..27300b767 --- /dev/null +++ b/jphp-jsoup-ext/src/main/resources/JPHP-INF/sdk/php/jsoup/ConnectionRequest.php @@ -0,0 +1,53 @@ +foobar'); +$element = $doc->select('a')->first(); + +var_dump($element->text()); +var_dump($element->tagName()); +var_dump($element->nodeName()); +var_dump($element->attr('href')); + +$element->attr('href', 'www_modified'); +var_dump($element->attr('href')); + +var_dump($element->html()); +var_dump($element->id()); + +?> +--EXPECT-- +string(6) "foobar" +string(1) "a" +string(1) "a" +string(3) "www" +string(12) "www_modified" +string(6) "foobar" +string(6) "100500" \ No newline at end of file diff --git a/jphp-jsoup-ext/src/main/tests/resources/jsoup/Jsoup_002.php b/jphp-jsoup-ext/src/main/tests/resources/jsoup/Jsoup_002.php new file mode 100644 index 000000000..dd67dedb5 --- /dev/null +++ b/jphp-jsoup-ext/src/main/tests/resources/jsoup/Jsoup_002.php @@ -0,0 +1,18 @@ +--TEST-- +Jsoup test #2 +--FILE-- +write('foobar'); +$source->seek(0); + +$doc = Jsoup::parse($source, 'UTF-8', 'examle.com'); + +var_dump($doc->select('a')->text()); +?> +--EXPECT-- +string(6) "foobar" \ No newline at end of file diff --git a/jphp-mail-ext/README.md b/jphp-mail-ext/README.md deleted file mode 100644 index 877bf4163..000000000 --- a/jphp-mail-ext/README.md +++ /dev/null @@ -1,40 +0,0 @@ -## Email Extension - -A simple extension for sending mail via smtp servers. - -#### Examples - -Sending email via Gmail account. - -```php -use php\mail\Email; -use php\mail\EmailBackend; - -// Create email server backend configuration. -$backend = new EmailBackend(); - -// set username and password of gmail account -$backend->setAuthentication('yourname@gmail.com', 'password'); - -// host name of gmail smtp server -$backend->hostName = 'smtp.googlemail.com'; - -$backend->smtpPort = 465; -$backend->sslOnConnect = true; - -$email = new Email(); -$email->setSubject('Hello!'); -$email->setFrom('noreply@jphp.ru', 'JPHP Compiler'); -$email->setTo(['dz@dim-s.net', 'd.zayceff@gmail.com']); - -// Set html text -$email->setHtmlMessage('Foobar'); - -// Set simple text -$email->setTextMessage('Foobar'); - -// Add attachment using file, also you can use php\io\Stream objects. -$email->attach('path/to/file', 'image/jpeg', 'My Picture'); - -$email->send($backend); -``` \ No newline at end of file diff --git a/jphp-mail-ext/src/main/java/org/develnext/jphp/ext/mail/classes/PHtmlEmail.java b/jphp-mail-ext/src/main/java/org/develnext/jphp/ext/mail/classes/PHtmlEmail.java index c711c4506..23e08c3d8 100644 --- a/jphp-mail-ext/src/main/java/org/develnext/jphp/ext/mail/classes/PHtmlEmail.java +++ b/jphp-mail-ext/src/main/java/org/develnext/jphp/ext/mail/classes/PHtmlEmail.java @@ -123,8 +123,12 @@ public PHtmlEmail attach(Environment env, Memory content, String type, String na throws EmailException, MessagingException, IOException { InputStream is = Stream.getInputStream(env, content); - htmlEmail.attach(new ByteArrayDataSource(is, type), name, description, EmailAttachment.ATTACHMENT); - return this; + try { + htmlEmail.attach(new ByteArrayDataSource(is, type), name, description, EmailAttachment.ATTACHMENT); + return this; + } finally { + Stream.closeStream(env, is); + } } @Signature