public function find($templateName, $currentSkin = null) { assert('\\de\\toxa\\txf\\txf::current()'); $folders = array(TXF_APPLICATION_PATH . '/skins/', dirname(dirname(__FILE__)) . '/skins/' . TXF_APPLICATION, dirname(dirname(__FILE__)) . '/skins/default'); $skins = array('default'); if ($currentSkin !== null) { $currentSkin = data::isKeyword($currentSkin); } if ($currentSkin) { if ($currentSkin != 'default') { array_unshift($skins, $currentSkin); } } foreach ($folders as $folder) { foreach ($skins as $skin) { $pathname = path::glue($folder, $skin, $templateName . '.phpt'); if (is_file($pathname)) { return $pathname; } } } throw new \UnexpectedValueException(sprintf('template not found: %s (%s)', $templateName, $currentSkin)); }
/** * Retrieves relation according to declaration selected by given name. * * Relations may be declared in static property $relations of a model. * * @example - have user relate to address via immediately related person (user.person_id => person.id - person.address_id => contact.id) user::$relations = array( 'contact_address' => array( // <- declaring name of relation 'referencing' => array( // <- declaring user referring to some 'model' => 'person', // <- ... person. ... 'with' => 'person_id', // <- declaring user.person_id to contain foreign key of ... 'on' => 'id', // <- ... person.id thus: user.person_id => person.id 'referencing' => array( // <- declaring person is then referring to another model ... 'model' => 'address', // <- ... address ... 'alias' => 'contact', // <- ... calling it "contact" here ... 'with' => 'address_id', // <- ... with person.address_id containing foreign key of ... 'on' => 'id', // <- ... contact.id thus: person.address_id => contact.id ) ) ), ); - same relation declared in reverse direction (contact.id <= person.address_id - person.id <= user.person_id) address::$relations = array( 'user' => array( // <- declaring name of relation 'alias' => 'contact', // <- declaring alias of initial node in relation being contact 'referencedBy' => array( // <- declaring address (called contact) referred to by some 'model' => 'person', // <- ... person. ... 'with' => 'address_id', // <- ... using its property address_id to contain foreign key of ... 'on' => 'id', // <- ... contact.id thus: contact.id <= person.address_id 'referencedBy' => array( // <- declaring person is then referred to by another model ... 'model' => 'user', // <- ... user ... 'with' => 'person_id', // <- ... using its property person_id to contain foreign key of ... 'on' => 'id', // <- ... person.id thus: person.id <= user.person_id ) ) ), ); - example of an m:n-relation (customer.id <= ordered.customer_id - ordered.product_id => goods.id) customer::$relations = array( 'ordered_goods' => array( 'referencedBy' => array( 'model' => 'ordered', 'with' => 'customer_id', 'on' => 'id', 'referencing' => array( 'model' => 'product', 'alias' => 'goods', 'with' => 'product_id', 'on' => 'id', ) ) ), ); - same m:n-relation with multi-dimensional reference (customer.id <= ordered.customer_id - [ordered.type,ordered.product_id] => [goods.type,goods.id]) customer::$relations = array( 'ordered_goods' => array( 'referencedBy' => array( 'model' => 'ordered', 'with' => 'customer_id', 'on' => 'id', 'referencing' => array( 'model' => 'product', 'alias' => 'goods', 'with' => array( 'type', 'product_id' ), 'on' => array( 'type', 'id' ), ) ) ), ); - again, same m:n-relation with multi-dimensional reference, this time relying on implicitly inserted virtual model (named explicitly) (customer.id <= ordered.customer_id - [ordered.type,ordered.product_id] => [goods.type,goods.id]) customer::$relations = array( 'ordered_goods' => array( 'referencedBy' => array( 'dataset' => 'ordered', 'with' => 'customer_id', 'on' => 'id', 'referencing' => array( 'model' => 'product', 'alias' => 'goods', 'with' => array( 'type', 'product_id' ), 'on' => array( 'type', 'id' ), ) ) ), ); - again, same m:n-relation with multi-dimensional reference, this time relying on implicitly inserted virtual model (not named explicitly) (customer.id <= customer_goods.customer_id - [customer_product.type,customer_product.product_id] => [goods.type,goods.id]) The inner set's name is derived by combining names of neighbouring sets. customer::$relations = array( 'ordered_goods' => array( 'referencedBy' => array( 'with' => 'customer_id', 'on' => 'id', 'referencing' => array( 'model' => 'product', 'alias' => 'goods', 'with' => array( 'type', 'product_id' ), 'on' => array( 'type', 'id' ), ) ) ), ); - finally, same m:n-relation with multi-dimensional reference, this time relying on implicitly inserted virtual model (not named explicitly) and deriving property names from referenced properties' names (customer.id <= customer_product.customer_id - [customer_product.product_type,customer_product.product_id] => [goods.type,goods.id]) The inner set's name is derived by combining names of neighbouring sets. customer::$relations = array( 'ordered_goods' => array( 'referencedBy' => array( 'on' => 'id', 'referencing' => array( 'model' => 'product', 'alias' => 'goods', 'on' => array( 'type', 'id' ), ) ) ), ); * * @param string $name name of model's relation to retrieve * @param model $bindOnInstance instance of current model to bind relation on * @return model_relation */ public static function relation($name, model $bindOnInstance = null) { $name = data::isKeyword($name); if (!$name) { throw new \InvalidArgumentException('invalid relation name'); } $fullName = static::getReflection()->getName() . '::' . $name; if (array_key_exists($fullName, self::$_relationCache)) { // read existing relation from runtime cache $relation = self::$_relationCache[$fullName]; } else { if (!array_key_exists($name, static::$relations)) { throw new \InvalidArgumentException(sprintf('no such relation: %s', $name)); } try { $relation = static::_compileRelation(null, static::$relations[$name]); if (!$relation->isComplete()) { throw new \InvalidArgumentException('incomplete relation definition: %s'); } $relation->setName($name); // write this relation (unbound) into runtime cache self::$_relationCache[$fullName] = $relation; } catch (\InvalidArgumentException $e) { throw new \InvalidArgumentException(sprintf('%s: %s', $e->getMessage(), $name), $e->getCode(), $e); } } // clone cached relation $relation = clone $relation; // bind on provided instance if that is a subclass of current one if ($bindOnInstance) { $expectedClass = new \ReflectionClass(get_called_class()); $givenClass = $bindOnInstance->getReflection(); if ($givenClass->getName() !== $expectedClass->getName() && !$givenClass->isSubclassOf($expectedClass)) { throw new \InvalidArgumentException('provided instance is not compatible'); } $relation->bindNodeOnItem(0, $bindOnInstance); } return $relation; }
/** * Adds some content to selected viewport. * * @param string $viewportName name of viewport to write into * @param string $viewportCode some code to append/prepend * @param boolean $append if true, code is appended, otherwise it's prepended * @return string|null * @throws \InvalidArgumentException */ public function writeInViewport($viewportName, $viewportCode = null, $append = true) { if (!($viewportName = data::isKeyword($viewportName))) { throw new \InvalidArgumentException('invalid viewport name'); } if (is_null($viewportCode)) { // retrieve current content of selected viewport if (array_key_exists($viewportName, $this->viewports)) { return $this->viewports[$viewportName]->get(); } return ''; } // extend selected viewport's content if (!array_key_exists($viewportName, $this->viewports)) { $this->viewports[$viewportName] = new capture(); } $this->viewports[$viewportName]->put($viewportCode, !$append); }