/** * Helper method used by setup(). Adds information about the handler (and * about the handler's wrapper, if existant and IFormresultAggregate'd) * to the formresult * * @param scriptlet.xml.workflow.Handler handler the handler to add * @param xml.Node node the node to add the handler representation to * @param scriptlet.xml.workflow.WorkflowScriptletRequest request */ protected function addHandlerToFormresult($handler, $node, $request) { $node->addChild(Node::fromArray($handler->values[HVAL_PERSISTENT], 'values')); if (isset($handler->values[HVAL_FORMPARAM])) { foreach ($handler->values[HVAL_FORMPARAM] as $key => $value) { // Skip parameters which were set via setFormValue() and which were // posted via request to avoid duplicate parameters. We do not need // to use $response->addFormValue() because this is done in // XMLScriptlet::processRequest() called in XMLScriptlet::doGet(). if ($request->hasParam($key)) { continue; } $request->setParam($key, $value); } } // Add wrapper parameter representation if the handler has a wrapper // and this wrapper implements the IFormresultAggregate interface if ($handler->hasWrapper() && $handler->wrapper instanceof IFormresultAggregate) { $wrapper = $node->addChild(new Node('wrapper')); foreach ($handler->wrapper->paraminfo as $name => $paraminfo) { $param = $wrapper->addChild(new Node('param', null, ['name' => $name, 'type' => $paraminfo['type'], 'occurrence' => $paraminfo['occurrence']])); if ($paraminfo['values']) { foreach ($paraminfo['values'] as $key => $value) { $param->addChild(new Node('value', $value, ['name' => $key])); } } if ($paraminfo['default']) { $param->addChild(new Node('default', $paraminfo['default'])); } } } }
protected function node($name, $in) { if (is_object($in)) { return Node::fromObject($in, $name); } else { if (is_array($in)) { return Node::fromArray($in, $name); } else { return new Node($name, $in); } } }
/** * Get content (the default). * * @param string encoding * @param var namespaces * @return var data */ public function getContent($encoding = null, $namespaces = null) { $ret = parent::getContent(); @(list($ns, $t) = explode(':', @$this->getAttribute($namespaces[XMLNS_XSI] . ':type'))); switch (strtolower($t)) { case 'base64': case 'base64binary': return new SOAPBase64Binary($ret, $encoded = true); break; case 'hexbinary': return new SOAPHexBinary($ret, $encoded = true); break; case 'boolean': return 0 == strncasecmp('true', $ret, 4) || 0 == strncasecmp('1', $ret, 1) ? true : false; case 'long': case 'int': $t = 'integer'; break; case 'decimal': case 'float': case 'double': $t = 'double'; break; case 'date': case 'datetime': // ISO 8601: http://www.w3.org/TR/xmlschema-2/#ISO8601 http://www.w3.org/TR/xmlschema-2/#dateTime return new \util\Date($ret); break; default: $t = 'string'; } // Decode if necessary $ret = iconv($encoding, \xp::ENCODING, $ret); // Set type settype($ret, $t); return $ret; }
/** * Recursivly serialize data to the given node. * * Scalar values are natively supported by the protocol, so we just encode * them as the spec tells us. As arrays and structs / hashes are the same * in PHP, and structs are the more powerful construct, we're always encoding * arrays as structs. * * XP objects are encoded as structs, having their FQDN stored in the member * __xp_class. * * @param xml.Node node * @param var data * @throws lang.IllegalArgumentException in case the data could not be serialized. */ protected function _marshall($data) { $value = new Node('value'); // Handle objects: // - util.Date objects are serialized as dateTime.iso8601 // - lang.types.Bytes object are serialized as base64 // - Provide a standard-way to serialize Object-derived classes if ($data instanceof Date) { $value->addChild(new Node('dateTime.iso8601', $data->toString('Ymd\\TH:i:s'))); return $value; } else { if ($data instanceof Bytes || $data instanceof \lang\types\Bytes) { $value->addChild(new Node('base64', base64_encode($data))); return $value; } else { if ($data instanceof \lang\Generic) { $n = $value->addChild(new Node('struct')); $n->addChild(Node::fromArray(['name' => '__xp_class', 'value' => ['string' => nameof($data)]], 'member')); foreach ($data->getClass()->getFields() as $field) { if ($field->getModifiers() & MODIFIER_STATIC) { continue; } $member = $n->addChild(new Node('member')); $member->addChild(new Node('name', $field->getName())); $member->addChild($this->_marshall($field->setAccessible(true)->get($data))); } return $value; } } } switch (\xp::typeOf($data)) { case 'integer': $value->addChild(new Node('int', $data)); break; case 'boolean': $value->addChild(new Node('boolean', (string) (int) $data)); break; case 'double': case 'float': $value->addChild(new Node('double', $data)); break; case 'array': if ($this->_isVector($data)) { $n = $value->addChild(new Node('array'))->addChild(new Node('data')); for ($i = 0, $s = sizeof($data); $i < $s; $i++) { $n->addChild($this->_marshall($data[$i])); } } else { $n = $value->addChild(new Node('struct')); foreach ($data as $name => $v) { $member = $n->addChild(new Node('member')); $member->addChild(new Node('name', $name)); $member->addChild($this->_marshall($v)); } } break; case 'string': $value->addChild(new Node('string', $data)); break; case 'NULL': $value->addChild(new Node('nil')); break; default: throw new \lang\IllegalArgumentException('Cannot serialize data of type "' . \xp::typeOf($data) . '"'); } return $value; }
/** * Compares XML after stripping all whitespace between tags of both * expected and actual strings. * * @see xp://unittest.TestCase#assertEquals * @param string $expect * @param xml.Node $node * @throws unittest.AssertionFailedError */ public function assertMarshalled($expect, $node) { $this->assertEquals(preg_replace('#>[\\s\\r\\n]+<#', '><', trim($expect)), preg_replace('#>[\\s\\r\\n]+<#', '><', trim($node->getSource(INDENT_DEFAULT)))); }
public function dateFormatCallbackWithoutTZ() { $date = new Date('2009-09-20 21:33:00'); $this->assertEquals($date->toString('Y-m-d H:i:s T'), $this->runTransformation(Node::fromObject($date, 'date')->getSource(), 'xp.date::format', ['string(/date/value)', "'Y-m-d H:i:s T'"])); }
/** * @param string $nodeName * @return Node */ public final function toNode($nodeName) { $node = new Node($nodeName); foreach ($this->toArray() as $group => $keyList) { $groupNode = $node->addChild(new Node($group)); foreach ($keyList as $key => $value) { $groupNode->addChild(new Node($key))->setContent($value); } } return $node; }
/** * Recursively deserialize data for the given node. * * @param xml.Node node * @return var * @throws lang.IllegalArgumentException if the data cannot be deserialized * @throws lang.ClassNotFoundException in case a XP object's class could not be loaded * @throws xml.XMLFormatException */ protected function _unmarshall(Node $node) { // Simple form: If no subnode indicating the type exists, the type // is string, e.g. <value>Test</value> if (!$node->hasChildren()) { return (string) $node->getContent(); } // Long form - with subnode, the type is derived from the node's name, // e.g. <value><string>Test</string></value>. $c = $node->nodeAt(0); switch ($c->getName()) { case 'struct': $ret = []; foreach ($c->getChildren() as $child) { $data = []; $data[$child->nodeAt(0)->getName()] = $child->nodeAt(0); $data[$child->nodeAt(1)->getName()] = $child->nodeAt(1); $ret[$data['name']->getContent()] = $this->_unmarshall($data['value']); unset($data); } if (!isset($ret['__xp_class'])) { return $ret; } $class = XPClass::forName($ret['__xp_class']); $instance = $class->newInstance(); foreach ($ret as $name => $value) { if (!$class->hasField($name)) { continue; } $field = $class->getField($name); if ($field->getModifiers() & MODIFIER_STATIC) { continue; } $class->getField($name)->setAccessible(true)->set($instance, $value); } return $instance; case 'array': $ret = []; foreach ($c->nodeAt(0)->getChildren() as $child) { $ret[] = $this->_unmarshall($child); } return $ret; case 'int': case 'i4': return (int) $c->getContent(); case 'double': return (double) $c->getContent(); case 'boolean': return (bool) $c->getContent(); case 'string': return (string) $c->getContent(); case 'dateTime.iso8601': return new Date($c->getContent()); case 'nil': return null; case 'base64': return new Bytes(base64_decode($c->getContent())); default: throw new \lang\IllegalArgumentException('Could not decode node as its type is not supported: ' . $c->getName()); } }
/** * @param bool $indent * @return string */ public function getSource($indent = true) { return $this->getProlog() . $this->rootNode->getSource($indent); }
/** * Called when a test run finishes. * * @param unittest.TestSuite suite * @param unittest.TestResult result */ public function testRunFinished(\unittest\TestSuite $suite, TestResult $result) { $coverage = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); $results = array(); foreach ($coverage as $fileName => $data) { foreach ($this->paths as $path) { if (substr($fileName, 0, strlen($path)) !== $path) { continue; } $results[dirname($fileName)][basename($fileName)] = $data; break; } } $pathsNode = new Node('paths'); foreach ($results as $pathName => $files) { $pathNode = new Node('path'); $pathNode->setAttribute('name', $pathName); foreach ($files as $fileName => $data) { $fileNode = new Node('file'); $fileNode->setAttribute('name', $fileName); $num = 1; $reader = new TextReader(new FileInputStream($pathName . '/' . $fileName)); while (($line = $reader->readLine()) !== null) { $lineNode = new Node('line', new CData($line)); if (isset($data[$num])) { if (1 === $data[$num]) { $lineNode->setAttribute('checked', 'checked'); } elseif (-1 === $data[$num]) { $lineNode->setAttribute('unchecked', 'unchecked'); } } $fileNode->addChild($lineNode); ++$num; } $pathNode->addChild($fileNode); } $pathsNode->addChild($pathNode); } $pathsNode->setAttribute('time', date('Y-m-d H:i:s')); $this->processor->setXMLBuf($pathsNode->getSource()); $this->processor->run(); FileUtil::setContents(new File($this->reportFile), $this->processor->output()); }
/** * Create node for XML feed * * @param xml.Node n */ public function visit(\xml\Node $n) { $n->setAttribute('url', $this->url); $this->lastModified && $n->setAttribute('last-modified', $this->lastModified->toString('r')); }
/** * @param string $name * @param string $value * @return AbstractSitePage this */ public final function setFormData($name, $value) { $this->formData->addChild(new Node($name))->setContent($value); return $this; }
public function writeInterfaces($description, $output) { static $purposes = array(HOME_INTERFACE => 'home', REMOTE_INTERFACE => 'remote'); foreach ($description->getInterfaces() as $type => $interface) { $node = Node::fromObject($interface, 'interface'); $node->setAttribute('purpose', $purposes[$type]); $node->addChild(new Node('jndiName', $this->jndi)); $this->processor->setXMLBuf($node->getSource(INDENT_NONE)); $this->processor->run(); $output->append(strtr($interface->getClassName(), '.', '/') . \xp::CLASS_FILE_EXT, $this->processor->output()); } }
/** * Adds an error. The XML representation will look like this: * <xmp> * <error * checker="foo.bar.wrapper.MyLoginDataChecker" * type="user_nonexistant" * field="username" * /> * </xmp> * * @param string checker The class checking the input * @param string type The error type * @param string field default '*' The form field corresponding * @param var info default NULL * @return bool FALSE */ public function addFormError($checker, $type, $field = '*', $info = null) { if (is_array($info)) { $c = \xml\Node::fromArray($info, 'error'); } else { if (is_object($info)) { $c = \xml\Node::fromObject($info, 'error'); } else { $c = new \xml\Node('error', $info); } } $c->setAttributes(['type' => $type, 'field' => $field, 'checker' => $checker]); $this->document->formerrors->addChild($c); return false; }