William Candillon has proposed merging lp:~zorba-coders/zorba/phpapi into lp:zorba.
Requested reviews: Matthias Brantner (matthias-brantner) David Graf (davidagraf) Rodolfo Ochoa (rodolfo-ochoa) For more details, see: https://code.launchpad.net/~zorba-coders/zorba/phpapi/+merge/86856 This merge adds the PHP API that was introduced at the PHP Tour 2011. It contains a test for it (php2). It also fix issues with the PHP include paths to ease the deployment of the API into PHP apps. The two key tests are: - php1 - php2 -- https://code.launchpad.net/~zorba-coders/zorba/phpapi/+merge/86856 Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'doc/php/examples/CMakeLists.txt' --- doc/php/examples/CMakeLists.txt 2011-08-19 00:03:31 +0000 +++ doc/php/examples/CMakeLists.txt 2011-12-24 16:33:26 +0000 @@ -20,14 +20,21 @@ MESSAGE(STATUS "PHP Path:" ${phpPath}) SET(phpExtensionPath ${CMAKE_BINARY_DIR}/swig/php) MESSAGE(STATUS "PHP Extension Path: " ${phpExtensionPath}) + SET(phpIncludePath ${CMAKE_BINARY_DIR}/swig/php) + MESSAGE(STATUS "PHP Include Path: " ${phpExtensionPath}) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/php.ini.in ${CMAKE_CURRENT_BINARY_DIR}/php.ini) MESSAGE(STATUS "Configuration file: " ${CMAKE_CURRENT_BINARY_DIR}/php.ini) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/simple.php.in ${CMAKE_CURRENT_BINARY_DIR}/simple.php) MESSAGE(STATUS "Simple configuration file: " ${CMAKE_CURRENT_BINARY_DIR}/simple.php) - ADD_TEST("php" ${PHP5_EXECUTABLE} -c ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/simple.php) + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/test.php.in ${CMAKE_CURRENT_BINARY_DIR}/test.php) + MESSAGE(STATUS "PHP test file configured: " ${CMAKE_CURRENT_BINARY_DIR}/test.php) + ADD_TEST("php1" ${PHP5_EXECUTABLE} -c ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/simple.php) MESSAGE(STATUS "Installing: " ${CMAKE_CURRENT_BINARY_DIR}/simple.php) - - INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/simple.php + ADD_TEST("php2" ${PHP5_EXECUTABLE} -c ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/test.php) + MESSAGE(STATUS "Installing: " ${CMAKE_CURRENT_BINARY_DIR}/test.php) + + + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/simple.php ${CMAKE_CURRENT_BINARY_DIR}/test.php COMPONENT "php_examples" DESTINATION share/doc/zorba-${ZORBA_MAJOR_NUMBER}.${ZORBA_MINOR_NUMBER}.${ZORBA_PATCH_NUMBER}/php/examples) === modified file 'doc/php/examples/php.ini.in' --- doc/php/examples/php.ini.in 2009-10-30 16:34:37 +0000 +++ doc/php/examples/php.ini.in 2011-12-24 16:33:26 +0000 @@ -1,2 +1,3 @@ enable_dl=On extension_dir=@phpExtensionPath@ +include_path=".:@phpIncludePath@" \ No newline at end of file === modified file 'doc/php/examples/simple.php.in' --- doc/php/examples/simple.php.in 2011-08-04 02:14:56 +0000 +++ doc/php/examples/simple.php.in 2011-12-24 16:33:26 +0000 @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -require '@phpPath@/zorba_api_wrapper.php'; +require '@phpPath@/Zorba/zorba_api_wrapper.php'; function example_1(Zorba $aZorba) { === added file 'doc/php/examples/test.php.in' --- doc/php/examples/test.php.in 1970-01-01 00:00:00 +0000 +++ doc/php/examples/test.php.in 2011-12-24 16:33:26 +0000 @@ -0,0 +1,69 @@ +<?php +/* + * Copyright 2006-2008 The FLWOR Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +require '@phpPath@/Zorba/XQueryProcessor.php'; + +function omitXMLDecl($xml) +{ + $xml = str_replace('<?xml version="1.0" encoding="UTF-8"?>', '', $xml); + $xml = trim($xml); + return $xml; +} + +function assertEquality($test, $reference, $label) +{ + + if($test == $reference) { + throw new Exception( + "Test " + . $label + . " failed. Result:\n" + . $test + . "\nDoesn't match reference:\n" + . $reference + ); + } +} +/* Test 1 */ +$xquery = new XQueryProcessor(); +$xquery->importQuery('1+1'); +$result = $xquery->execute(); +assertEquality($result, '2', "1+1"); + +/* Test 2 */ +$query = <<<'XQ' +declare variable $foo as xs:string external; +declare variable $bar as xs:integer external; +declare variable $doc1 as document-node() external; +declare variable $doc2 as document-node() external; + +$foo, $bar, $doc1, $doc2 +XQ; + +$xquery->importQuery($query); + +$xquery->setVariable("foo", "bar"); +$xquery->setVariable("bar", 3); + +$doc = simplexml_load_string('<root />'); +$xquery->setVariable("doc1", $doc); + +$doc = $xquery->parseXML("<root />"); +$xquery->setVariable("doc2", $doc); + +$result = trim($xquery->execute()); +assertEquality($result, "bar 3<root /><root />", "Scalar Types"); +?> === modified file 'swig/php/CMakeLists.txt' --- swig/php/CMakeLists.txt 2011-12-21 14:40:33 +0000 +++ swig/php/CMakeLists.txt 2011-12-24 16:33:26 +0000 @@ -55,7 +55,8 @@ INSTALL ( FILES - ${CMAKE_CURRENT_BINARY_DIR}/zorba_api_wrapper.php + ${CMAKE_CURRENT_BINARY_DIR}/Zorba/XQueryProcessor.php + ${CMAKE_CURRENT_BINARY_DIR}/Zorba/zorba_api_wrapper.php ${CMAKE_CURRENT_BINARY_DIR}/${ZORBA_SWIG_LIB_PREFIX}zorba_api.so DESTINATION ${PHP5_INSTALL_PATH} ) @@ -77,6 +78,7 @@ ### Start PHP proxy generation # Configure the test file + SET (phpLibPrefix ${ZORBA_SWIG_LIB_PREFIX}) SET (phpAPIPath ${CMAKE_CURRENT_BINARY_DIR}) SET (phpLibPrefix ${ZORBA_SWIG_LIB_PREFIX}) CONFIGURE_FILE ( @@ -84,8 +86,13 @@ ${CMAKE_CURRENT_BINARY_DIR}/generate_proxy.php ) + CONFIGURE_FILE ( + ${CMAKE_CURRENT_SOURCE_DIR}/XQueryProcessor.php + ${CMAKE_CURRENT_BINARY_DIR}/Zorba/XQueryProcessor.php + ) + ADD_CUSTOM_COMMAND ( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zorba_api_wrapper.php + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Zorba/zorba_api_wrapper.php # the following addes a dependency to the *.cxx file that is generated by swig DEPENDS ${swig_generated_file_fullname} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/generate_proxy.php.in @@ -94,7 +101,8 @@ ) ADD_CUSTOM_TARGET ( Api_PHP_Wrapper ALL - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/zorba_api_wrapper.php + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Zorba/zorba_api_wrapper.php + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Zorba/XQueryProcessor.php ) ### End PHP proxy generation === added file 'swig/php/XQueryProcessor.php' --- swig/php/XQueryProcessor.php 1970-01-01 00:00:00 +0000 +++ swig/php/XQueryProcessor.php 2011-12-24 16:33:26 +0000 @@ -0,0 +1,278 @@ +<?php +require_once 'Zorba/zorba_api_wrapper.php'; + +/** + * The XQueryProcessor class allows to invoke + * <a href="http://www.zorba-xquery.com">Zorba XQuery Processor</a>. + * + * Instruction to install the extension can be found at <a href=""></a>. + * + * The following code snippet executes a small <em>Hello World</em> program: + * <code> + * <?php + * require_once 'ZorbaXQueryProcessor.php'; + * + * $xquery = new XQueryProcessor(); + * + * $query = <<<'XQ' + * declare variable $name external; + * + * <h1>Hello {$name}</h1> + * XQ; + * + * $xquery->importQuery($query); + * + * $xquery->setVariable('name', 'World'); + * + * echo $xquery->execute(); + * ?> + * </code> + */ +class XQueryProcessor { + + private $store = null; + private $zorba = null; + private $query = null; + private $variables = array(); + + /** + * Creates a Zorba instance. + */ + public function __construct(){ + $this->store = InMemoryStore::getInstance(); + $this->zorba = Zorba::getInstance($this->store); + } + + /** + * Shutdowns Zorba instance. + */ + public function __destruct() { + $this->zorba->shutdown(); + InMemoryStore::shutdown($this->store); + } + + /** + * Import a query to execute. + * For instance, the following code snippets imports and executes the query '1+1': + * <code> + * $xquery = new ZorbaXQueryProcessor(); + * + * $xquery->importQuery('1+1'); + * + * echo $xquery->execute() . '\n'; + * </code> + * In the following code snippet, the following code snippets imports and execute an <em>Hello World</em> query: + * <code> + * <?php + * $xquery = new XQueryProcessor(); + * + * $query = <<<'XQ' + * let $world := 'World' + * return <h1>Hello {$world}</h1> + * XQ; + * + * $xquery->importQuery($query); + * + * echo $xquery->execute() . '\n'; + * ?> + * </code> + * + * @param $query Query to execute. + * @return ZorbaXQueryProcessor instance. + */ + public function importQuery($query) { + $this->query = $query; + return $this; + } + + /** + * Import a query to execute from its filename. + * For instance, the following code snippet imports the query file named <em>hello_word.xq</em>: + * <code> + * $xquery = new ZorbaXQueryProcessor(); + * + * $xquery->importQueryiFromURI('hello_world.xq'); + * + * echo $xquery->execute() . '\n'; + * </code> + * + * @param $filename Filename of the query to execute. + * @return ZorbaXQueryProcessor instance. + */ + public function importQueryFromURI($filename) { + $this->importQuery(file_get_contents($filename)); + return $this; + } + + /** + * Set value for an external variable. + * + * The following code snippet sets the value of the variable + * <em>$i</em> with <em>1</em>. + * <code> + * $xquery = new ZorbaXQueryProcessor(); + * + * $query = <<<'XQ' + * declare variable $i as xs:integer external; + * + * $i + 1 + * 'XQ'; + * + * $xquery->importQuery($query); + * $xquery->setVariable($i, 1); + * + * echo $xquery->execute() . '\n'; + * </code> + * + * The following code snippet sets the value of the variable <em>$i</em> in + * the local namespace with the value <em>1</em>. + * <code> + * $xquery = new ZorbaXQueryProcessor(); + * + * $query = <<<'XQ' + * declare variable $local:i as xs:integer external; + * + * $i + 1 + * 'XQ'; + * + * $xquery->importQuery($query); + * $xquery->setVariable("http://www.w3.org/2005/xquery-local-functions", $i, 1); + * + * echo $xquery->execute() . '\n'; + * </code> + * + * PHP types are converted to the following XML types: + * - <b>string</b>: xs:string + * - <b>float</b>: xs:float + * - <b>long</b>: xs:long + * - <b>integer</b>: xs:integer + * - <b>boolean</b>: xs:boolean + * - <b>DOMDocument</b>: document-node() + * + * @param string $namespace optional Namespace URI of the external variable. + * @param string $name Local name of the external variable. + * @param mixed $value of the external variable. + * + * return ZorbaXQueryProcessor instance. + */ + public function setVariable($arg1, $arg2) { + $count = func_num_args(); + if($count == 2) { + $name = func_get_arg(0); + $value = func_get_arg(1); + $value = $this->getItem($value); + $this->variables['_'][$name] = $value; + } else { + $ns = func_get_arg(0); + $name = func_get_arg(1); + $value = func_get_arg(2); + $value = $this->getItem($value); + $this->variables[$ns][$name] = $value; + } + return $this; + } + + private function getItem($value) { + + $itemFactory = $this->zorba->getItemFactory(); + + if($value instanceof Item) { + //Do nothing + } else if($value instanceof DOMDocument or $value instanceof SimpleXMLElement) { + $value = $this->parseXML($value->saveXML()); + } else if(is_string($value)) { + $value = $itemFactory->createString($value); + } else if(is_int($value)) { + $value = $itemFactory->createInteger($value); + } else if(is_bool($value)) { + $value = $itemFactory->createBoolean($value); + } else if(is_float($value)) { + $value = $itemFactory->createFloat($value); + } else if(is_long($value)) { + $value = $itemFactory->createLong($value); + } else { + throw new Exception("Unsupported variable type: ".gettype($value)); + } + + assert($value instanceof Item); + + return $value; + } + + /** + * Parse an XML string to an XQuery Item. + * + * @param $xml string XML string to parse. + * + * @return Item instance. + */ + public function parseXML($xml) + { + $lDataManager = $this->zorba->getXmlDataManager(); + $lDocMgr = $lDataManager->getDocumentManager(); + $iter = $lDataManager->parseXML($xml); + + $iter->open(); + $doc = Item::createEmptyItem(); + + $iter->next($doc); + $iter->close(); + $iter->destroy(); + + return $doc; + } + + /** + * Parse an XML document from its URI to an XQuery Item. + * + * @param $uri string URI of the XML document to parse. + * + * @return Item instance. + */ + public function parseXMLfromURI($uri) + { + $this->parseXML($uri); + } + + private function prepareQuery() { + if($this->query == null) { + throw new Exception("No Query Imported"); + } + //Compile Query + $query = $this->zorba->compileQuery($this->query); + //Set Variables + $dctx = $query->getDynamicContext(); + foreach($this->variables as $ns => $variables){ + foreach($variables as $name => $value) { + if($ns == "_") $ns = ""; + $param = $this->zorba->compileQuery("."); + $param->getDynamicContext()->setContextItem($value); + $dctx->setVariable($ns, $name, $param->iterator()); + } + } + return $query; + } + + /** + * Execute the Query. + * + * @return Query result. + */ + public function execute() { + //Execute + $query = $this->prepareQuery(); + $result = $query->execute(); + $query->destroy(); + return $result; + } + + /** + * Execute the query and store its results to + * the given URI. + */ + public function executeToURI($uri) { + $result = $this->execute(); + return file_put_contents($uri, $result); + } +} +?> === modified file 'swig/php/generate_proxy.php.in' --- swig/php/generate_proxy.php.in 2011-12-21 14:40:33 +0000 +++ swig/php/generate_proxy.php.in 2011-12-24 16:33:26 +0000 @@ -1,5 +1,5 @@ <?php -$libPrefix = '@phpLibPrefix@'; +$prefix = '@phpLibPrefix@'; $file = file_get_contents('@phpAPIPath@/zorba_api.php'); $file = str_replace('class Iterator {', 'class IteratorImpl {', $file); $file = str_replace('extends Iterator {', 'extends IteratorImpl {', $file); @@ -18,9 +18,9 @@ if(!dl('php_zorba_api.dll')) return; } else { if(PHP_SHLIB_SUFFIX === 'PHP_SHLIB_SUFFIX' || PHP_SHLIB_SUFFIX === 'dylib') { - if(!dl('$libPrefix'.'zorba_api.so')) return; + if(!dl('$prefix'.'zorba_api.so')) return; } else { - if(!dl('$libPrefix'.'zorba_api.' . PHP_SHLIB_SUFFIX)) return; + if(!dl('$prefix'.'zorba_api.' . PHP_SHLIB_SUFFIX)) return; } } } @@ -164,7 +164,7 @@ } } -file_put_contents('zorba_api_wrapper.php', $wrapper); +file_put_contents('Zorba/zorba_api_wrapper.php', $wrapper); function getRefParameters(ReflectionMethod $method, array $params) { $result = "";
-- Mailing list: https://launchpad.net/~zorba-coders Post to : zorba-coders@lists.launchpad.net Unsubscribe : https://launchpad.net/~zorba-coders More help : https://help.launchpad.net/ListHelp