/** * {@inheritdoc} */ public function run(App $app, Document $config) { Enum::addSearchPrefix($app->n('Enums') . '\\'); $app->m->Helpers = new Helpers($app); $app->m->Helpers->addHelper('Jivoo\\Snippets\\SnippetHelper'); $app->m->Helpers->runInit(); $app->m->Helpers->addHelper('Jivoo\\AccessControl\\AuthHelper'); $app->m->addMethod('helper', array($app->m->Helpers, 'getHelper')); $app->m->Models = new Models($app); $app->m->Models->runInit(); $listeners = $this->p('app/Listeners'); if (is_dir($listeners)) { $files = scandir($listeners); if ($files !== false) { foreach ($files as $file) { $split = explode('.', $file); if (isset($split[1]) and $split[1] == 'php') { $listener = $this->app->n('Listeners\\' . $split[0]); Assume::isSubclassOf($listener, 'Jivoo\\Core\\AppListener'); $this->app->attachEventListener(new $listener($this->app)); } } } } }
/** * Get a snippet instance. * @param string $name Snippet class name. * @param bool $singleton Whether to use an existing instance instead of * creating a new one. * @return Snippet Snippet instance or null if not found. */ public function getSnippet($name, $singleton = true) { if (!$singleton or !isset($this->instances[$name])) { $class = $name; if (!class_exists($class)) { $class = $this->app->n('Snippets\\' . $class); } if (!class_exists($class)) { return null; } Assume::isSubclassOf($class, 'Jivoo\\Snippets\\SnippetBase'); $object = new $class($this->app); if (!$singleton) { return $object; } $this->instances[$name] = $object; } return $this->instances[$name]; }
/** * Get values of an enum class. * @param string $class Class name. * @throws InvalidEnumException If the class invalid or does not contain * constants. * @return string[] Enum values. */ public static function getValues($class = null) { if (!isset($class)) { $class = get_called_class(); } if (!isset(self::$values[$class])) { if (!self::classExists($class)) { throw new InvalidEnumException(tr('Enum class not found: %1', $class)); } $class = self::$classes[$class]; Assume::isSubclassOf($class, 'Jivoo\\Models\\Enum'); $ref = new \ReflectionClass($class); self::$values[$class] = array_flip($ref->getConstants()); if (count(self::$values[$class]) < 1) { throw new InvalidEnumException(tr('Enum type "%1" must contain at least one constant', $class)); } } return self::$values[$class]; }
/** * Get a helper instance * @param string $name Helper name * @return Helper A helper object */ public function getHelper($name) { if (!isset($this->helpers[$name])) { $class = $this->app->n('Helpers\\' . $name . 'Helper'); if (!class_exists($class)) { if (isset($this->helperClasses[$name])) { $class = $this->helperClasses[$name]; } else { if (strpos($name, '\\') !== false) { $class = $name . 'Helper'; $name = Utilities::getClassName($name); } else { $class = 'Jivoo\\Helpers\\' . $name . 'Helper'; } } } $this->triggerEvent('beforeLoadHelper', new LoadHelperEvent($this, $name)); Assume::isSubclassOf($class, 'Jivoo\\Helpers\\Helper'); $this->helpers[$name] = new $class($this->app); $this->triggerEvent('afterLoadHelper', new LoadHelperEvent($this, $name, $this->helpers[$name])); } return $this->helpers[$name]; }
/** * Create notification. * @param string $type Notification type, e.g. 'error' or 'success'. * @param string[] $parameters An array containing the notification message. */ public function __call($type, $parameters) { assume(isset($parameters[0])); Assume::isString($parameters[0]); $this->__set($type, $parameters[0]); }
public static function sort($data, $field, $descending = false) { Assume::isArray($data); usort($data, function (BasicRecord $a, BasicRecord $b) use($field, $descending) { if ($a->{$field} == $b->{$field}) { return 0; } if ($descending) { if (is_numeric($a->{$field})) { return $b->{$field} - $a->{$field}; } return strcmp($b->{$field}, $a->{$field}); } else { if (is_numeric($a->{$field})) { return $a->{$field} - $b->{$field}; } return strcmp($a->{$field}, $b->{$field}); } }); return $data; }
/** * Construct active model. * @param App $app Associated application. * @param DatabaseLoader $databases Databases module. * @throws InvalidActiveModelException If model is incorrectly defined. * @throws InvalidTableException If table not found. * @throws InvalidAssociationException If association models are invalid. * @throws InvalidMixinException If a mixin is invalid. */ public final function __construct(App $app, Loader $databases) { parent::__construct($app); $databaseName = $this->database; $database = $databases->{$databaseName}; $this->name = Utilities::getClassName(get_class($this)); if (!isset($database)) { throw new InvalidActiveModelException(tr('Database "%1" not found', $this->database)); } $this->database = $database; if (!isset($this->table)) { $this->table = $this->name; } $table = $this->table; if (!isset($this->database->{$table})) { throw new InvalidTableException(tr('Table "%1" not found in database', $table)); } $this->source = $this->database->{$table}; $this->schema = $this->source->getSchema(); if (!isset($this->schema)) { throw new InvalidTableException('Schema for table "' . $table . '" not found'); } $pk = $this->schema->getPrimaryKey(); if (count($pk) == 1) { $pk = $pk[0]; $this->primaryKey = $pk; $type = $this->schema->{$pk}; if ($type->isInteger() and $type->autoIncrement) { $this->aiPrimaryKey = $pk; } } else { throw new InvalidActiveModelException(tr('ActiveModel does not support multi-field primary keys')); } $this->nonVirtualFields = $this->schema->getFields(); $this->fields = $this->nonVirtualFields; foreach ($this->virtual as $field) { $this->fields[] = $field; $this->virtualFields[] = $field; } $this->validator = new ValidatorBuilder($this, $this->validate); $this->schema->createValidationRules($this->validator); foreach ($this->nonVirtualFields as $field) { $type = $this->schema->{$field}; if (isset($type->default)) { $this->defaults[$field] = $type->default; } } if (isset($this->record)) { Utilities::assumeSubclassOf($this->record, 'Jivoo\\ActiveModels\\ActiveRecord'); } $this->attachEventListener($this); foreach ($this->mixins as $mixin => $options) { if (!is_string($mixin)) { $mixin = $options; $options = array(); } if (class_exists('Jivoo\\ActiveModels\\' . $mixin . 'Mixin')) { $mixin = 'Jivoo\\ActiveModels\\' . $mixin . 'Mixin'; } else { if (class_exists($mixin . 'Mixin')) { $mixin .= 'Mixin'; } else { if (!class_exists($mixin)) { throw new InvalidMixinException('Mixin class not found: ' . $mixin); } } } Assume::isSubclassOf($mixin, 'Jivoo\\ActiveModels\\ActiveModelMixin'); $mixin = new $mixin($this->app, $this, $options); $this->attachEventListener($mixin); $this->mixinObjects[] = $mixin; foreach ($mixin->getMethods() as $method) { $this->methods[$method] = array($mixin, $method); } } $this->database->{$table} = $this; $this->init(); }
/** * Make a database connection. * @param string $name Name of database connection. * @param DatabaseSchema $schema Database schema (collecton of table schemas). * @throws ConfigurationException If the $options-array does not * contain the necessary information for a connection to be made. * @throws InvalidSchemaException If one of the schema names listed * in the $schemas-parameter is unknown. * @throws ConnectionException If the connection fails. * @return LoadableDatabase A database object. */ public function connect($name, DatabaseSchema $schema = null) { if (!isset($this->config[$name])) { throw new ConfigurationException(tr('Database "%1" not configured', $name)); } $config = $this->config->getSubset($name); $driver = $config->get('driver', null); if (!isset($driver)) { throw new ConfigurationException(tr('Database driver not set')); } try { $driverInfo = $this->checkDriver($driver); } catch (InvalidDriverException $e) { throw new ConnectionException(tr('Invalid database driver: %1', $e->getMessage()), 0, $e); } foreach ($driverInfo['requiredOptions'] as $option) { if (!isset($config[$option])) { throw new ConfigurationException(tr('Database option missing: "%1"', $option)); } } try { $class = 'Jivoo\\Databases\\Drivers\\' . $driver . '\\' . $driver . 'Database'; Assume::isSubclassOf($class, 'Jivoo\\Databases\\LoadableDatabase'); if (!isset($schema)) { $schema = new DynamicDatabaseSchema(); } $object = new $class($schema, $config); $object->setLogger($this->logger); $this->connections[$name] = new DatabaseConnection($object); return $object; } catch (ConnectionException $exception) { throw new ConnectionException(tr('Database connection failed (%1): %2', $driver, $exception->getMessage()), 0, $exception); } }
/** * {@inheritdoc} */ public function __set($property, $value) { switch ($property) { case 'userModel': case 'loginRoute': case 'unauthorizedRoute': case 'ajaxRoute': case 'createSessions': case 'createCookies': case 'sessionPrefix': case 'sessionLifeTime': case 'sessionRenewAfter': case 'cookiePrefix': case 'cookieLifeTime': case 'cookieRenewAfter': case 'permissionPrefix': $this->{$property} = $value; return; case 'passwordHasher': if ($value instanceof PasswordHasher) { $this->passwordHasher = $value; } else { Assume::isSubclassOf($value, 'Jivoo\\AccessControl\\Passwordhasher'); $this->passwordHasher = new $value(); } return; case 'authentication': if (is_array($value)) { foreach ($value as $name => $options) { if (!is_string($name)) { $name = $options; $options = array(); } $this->loadAuthentication($name, $options); } } else { $this->loadAuthentication($value); } return; case 'authorization': if (is_array($value)) { foreach ($value as $name => $options) { if (!is_string($name)) { $name = $options; $options = array(); } $this->loadAuthorization($name, $options); } } else { $this->loadAuthorization($value); } return; case 'acl': if (is_array($value)) { foreach ($value as $name => $options) { if (!is_string($name)) { $name = $options; $options = array(); } $this->loadAcl($name, $options); } } else { $this->loadAcl($value); } return; } parent::__set($property, $value); }
/** * {@inheritdoc} */ public function saveDeferred(CacheItem $item) { if (!isset($this->data)) { $this->read(); } Assume::isInstanceOf($item, 'Jivoo\\Core\\Cache\\MutableItem'); $expiration = $item->getExpiration(); if (isset($expiration)) { $expiration = $expiration->getTimestamp(); } $this->data[$item->getKey()] = array($item->get(), $expiration); return true; }
/** * Add a filter to a field. * @param string $field Field name. * @param string $stage Content stage: 'preprocess', 'postprocess', 'prerender'. * @param callable $callable Filter function, accepts a string and returns a * string. */ public function addFilter($field, $stage, $callable) { Assume::hasKey($this->filters, $field); if (!isset($this->filters[$field][$stage])) { $this->filters[$field][$stage] = array(); } $this->filters[$field][$stage][] = $callable; }
/** * Load a unit (does not enable it). * * When loading a unit, the method will first look in the namespaces * "Jivoo\Core\Units" and "(app namespace)\Units". E.g. when attempting to * load "Foo\Bar", the following class lookups are made: * "Jivoo\Core\Units\Foo\BarUnit", "(app namespace)\Units\Foo\BarUnit", * "Foor\BarUnit", and "Foo\Bar". * @param string|Unit $name Unit name or object. * @return Unit The loaded unit. */ public function load($name) { if ($name instanceof Unit) { $unit = $name; $name = $this->getName($unit); if (isset($this->units[$name])) { return $this->units[$name]; } } else { if (isset($this->units[$name])) { return $this->units[$name]; } if (class_exists('Jivoo\\Core\\Units\\' . $name . 'Unit')) { $class = 'Jivoo\\Core\\Units\\' . $name . 'Unit'; } else { if (class_exists($this->app->n('Units\\' . $name . 'Unit'))) { $class = $this->app->n('Units\\' . $name . 'Unit'); } else { if (class_exists($name . 'Unit')) { $class = $name . 'Unit'; } else { $class = $name; } } } Assume::isSubclassOf($class, 'Jivoo\\Core\\UnitBase'); $unit = new $class($this->app); } $this->units[$name] = $unit; foreach ($unit->before() as $dependency) { $this->before($name, $dependency); } foreach ($unit->after() as $dependency) { $this->before($dependency, $name); } return $unit; }