/** * Imports an array representation into an actual PHP object * * @param array $something * The object representation to import * * @return object * The PHP object */ private function importObject($something) { if (isset($something['__id__'])) { if (isset($this->state[$something['__id__']])) { return $this->state[$something['__id__']]; } } $entry = $this->manifest->getEntryByAlias($something['__class__']); $className = $entry->class; if (method_exists($className, '__set_state')) { $object = call_user_func(array($className, '__set_state'), $something); } else { $object = new $className(); } if (isset($something['__id__'])) { $this->state[$something['__id__']] = $object; } $ref = new \ReflectionClass(get_class($object)); foreach ($entry->properties as $name => $propertyDefinition) { if (!isset($something[$name])) { continue; } if ($propertyDefinition->isReadOnly) { continue; } $property = $ref->getProperty($name); $property->setAccessible(true); if ($propertyDefinition->isStatic) { $property->setValue(new \stdClass(), $something[$name]); } else { $property->setValue($object, $something[$name]); } } return $object; }
/** * Add the class's properties to the manifest */ private function finaliseProperties() { $ref = new \ReflectionClass($this->class); foreach ($ref->getProperties() as $propertyReflector) { $needExportComment = !$this->exportAll && !$this->manifest->exportAll(); $property = new Property($propertyReflector); if ($needExportComment && !$property->export) { continue; } $this->properties[$property->name] = $property; if ($property->isIdentifier) { $this->identifiers[] = $property->name; } } }
/** * Outputs an AngularJS module, which contains definitions of all the classes exported. * Mixing PHP and JavaScript is not a great idea, but this solution is rather elegant in * that it requires no JS libraries, as its output is 100% AngularJS. It also removes * the need for bootstrapping individual manifests, or delaying bootstrapping while a * JSON-fetched manifest is parsed. Everything is present upon normal AngularJS * bootstrapping, which is the best possible outcome. * * @return string * The actual AngularJS module */ public function getAngularJSModule() { if ($this->minify) { $jsSrc = 'echobot-angularphp.min.js'; } else { $jsSrc = 'echobot-angularphp.js'; } $code = file_get_contents(__DIR__ . '/../js/' . $jsSrc); /** * Replace the placeholders for the manifest & URI with their proper * values. */ $encodingOptions = 0; if (!$this->minify && defined('JSON_PRETTY_PRINT')) { $encodingOptions = JSON_PRETTY_PRINT; } $toReplace = array('$MANIFEST$' => json_encode($this->manifest->export(), $encodingOptions), '$URI$' => $this->uri, '$MODULE$' => json_encode($this->moduleName ? $this->moduleName : $this->uri), '$DEBUG$' => json_encode($this->debug)); foreach ($toReplace as $what => $with) { $code = str_replace($what, $with, $code); } return $code; }