/** * Finds all or up to selected number of items of model matching provided * properties' values. * * If $limit is omitted or 1, the result is a matching instance or null. In * all other cases a probably empty list of matches is returned. * * @param connection $source data source to look for matching item in * @param array $properties set of model's properties mapping into values to match * @param int $limit maximum number of matches to retrieve * @return model|null matching model item, null on mismatch * @throws \InvalidArgumentException */ public static function findAll(connection $source = null, $properties, $limit = 1) { if (!is_array($properties) || !count($properties)) { throw new \InvalidArgumentException('invalid set of properties to find'); } if (!ctype_digit(strval($limit)) || !$limit) { throw new \InvalidArgumentException('invalid limit on number of desired matches'); } if ($source == null) { $source = datasource::selectConfigured('default'); } static::updateSchema($source); $query = $source->createQuery(static::$set_prefix . static::$set); foreach (static::$id as $idName) { $query->addProperty($idName); } $definition = static::define(); foreach ($properties as $name => $value) { if (array_key_exists($name, $definition) || in_array($name, static::$id)) { $query->addCondition("{$name}=?", true, $value); } else { throw new \InvalidArgumentException('undefined property'); } } $query = $query->limit($limit)->execute(); $matches = array(); while ($id = $query->row()) { $matches[] = static::select($source, $id); if (count($matches) >= $limit) { $query->close(); break; } } if ($limit === 1) { return count($matches) ? array_shift($matches) : null; } return $matches; }
/** * Retrieves connection to configured datasource containing users database. * * @throws \Exception * @return datasource\connection connection to datasource */ public function datasource() { if (!is_array($this->configuration)) { throw new \RuntimeException(_L('Missing user source configuration.')); } $conf = $this->configuration; $hash = sha1(serialize($conf)); if (!array_key_exists($hash, self::$datasources)) { // gain access on datasource configured to contain users if ($conf['datasource']) { $ds = datasource::selectConfigured($conf['datasource']); } else { $ds = datasource::selectConfigured('default'); } if (!$ds instanceof datasource\pdo) { throw new \UnexpectedValueException(_L('Unsupported kind of datasource for managing users.')); } // apply optionally configured mapping of a user's properties $definition = array('uuid' => 'CHAR(36) NOT NULL', 'loginname' => 'CHAR(64) NOT NULL', 'password' => 'CHAR(128) NOT NULL', 'name' => 'CHAR(128)', 'lock' => 'CHAR(128)', 'email' => 'CHAR(128)'); $mappedDefinition = name_mapping::map($definition, 'txf.sql_user'); // create data set in datasource on demand if (!$ds->createDataset($conf['set'], $mappedDefinition)) { throw $ds->exception(_L('failed to create dataset for managing users')); } // ensure to have a single user at least by default if (!intval($ds->createQuery($conf['set'])->execute(true)->cell())) { $record = name_mapping::map(array('uuid' => uuid::createRandom(), 'loginname' => 'admin', 'password' => blowfish::get('nimda'), 'name' => _L('Administrator'), 'lock' => '', 'email' => ''), 'txf.sql_user'); $currentUser = $this; $ds->transaction()->wrap(function (datasource\connection $conn) use($record, $conf, $currentUser) { $names = array_map(function ($n) use($conn) { return $conn->quoteName($n); }, array_keys($record)); $markers = array_map(function () { return '?'; }, $record); $newUserID = $conn->nextID($conf['set']); $values = array_values($record); array_unshift($values, $newUserID); $sql = sprintf('INSERT INTO %s (id,%s) VALUES (?,%s)', $conn->qualifyDatasetName($conf['set']), implode(',', $names), implode(',', $markers)); if (!$conn->test($sql, $values)) { throw $conn->exception(_L('failed to create default user')); } // load created user for adopting administrator role sql_role::select($conn, 'administrator')->makeAdoptedBy(user::load($newUserID)); return true; }); } self::$datasources[$hash] = $ds; } return self::$datasources[$hash]; }
protected function __construct(connection $datasource = null, $formName = null) { if ($datasource === null) { $datasource = datasource::selectConfigured('default'); } $this->datasource = $datasource; $this->formName = \de\toxa\txf\_1($formName, 'model_editor'); }