public function __construct($maximumValidation, $tableName) { if (!$this->isDatabaseSupported(\Yii::$app->db->dsn)) { throw new Exception(DATABASE_IS_NOT_SUPPORTED); } if (isset(MySqlTableSchemaParser::$describeTable[$tableName])) { $tableSchemaRowList = MySqlTableSchemaParser::$describeTable[$tableName]; } else { $command = \Yii::$app->db->createCommand('DESCRIBE ' . $tableName); $tableSchemaRowList = $command->queryAll(); MySqlTableSchemaParser::$describeTable[$tableName] = $tableSchemaRowList; $command = \Yii::$app->db->createCommand('SHOW CREATE TABLE ' . $tableName); $tableSchemaStr = $command->queryAll(); MySqlTableSchemaParser::$showCreateTable[$tableName] = $tableSchemaStr[0]['Create Table']; } $tableSchemaParser = new $this->tableSchemaParserClass($this, $tableName, $tableSchemaRowList, $maximumValidation); parent::__construct(); }
public function __construct($tableName, $dsn, $pdo) { if (!$this->isDatabaseSupported($dsn)) { throw new Exception(DATABASE_IS_NOT_SUPPORTED); } if (isset(MySqlTableSchemaParser::$describeTable[$tableName])) { $tableSchemaRowList = MySqlTableSchemaParser::$describeTable[$tableName]; } else { $pdoAttributeATTR_CASE = $pdo->getAttribute(\PDO::ATTR_CASE); $pdo->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_NATURAL); $pdoStatement = $pdo->query('DESCRIBE ' . $tableName); $tableSchemaRowList = $pdoStatement->fetchAll(\PDO::FETCH_ASSOC); MySqlTableSchemaParser::$describeTable[$tableName] = $tableSchemaRowList; $pdoStatement = $pdo->query('SHOW CREATE TABLE ' . $tableName); $tableSchemaStr = $pdoStatement->fetchAll(\PDO::FETCH_ASSOC); MySqlTableSchemaParser::$showCreateTable[$tableName] = $tableSchemaStr[0]['Create Table']; $pdo->setAttribute(\PDO::ATTR_CASE, $pdoAttributeATTR_CASE); } $tableSchemaParser = new $this->tableSchemaParserClass($this, $tableName, $tableSchemaRowList, true); parent::__construct(); }
/** * Generates the expression for selecting rows with specified composite key values. * * @param TableSchema $table the table schema * @param array $values list of primary key values to be selected within * @param string $prefix column prefix (ended with dot) * * @return string the expression for selection * @throws \Exception */ protected function createCompositeInCondition($table, $values, $prefix) { $keyNames = array(); foreach (array_keys($values[0]) as $name) { /** @type ColumnSchema $column */ if (null === ($column = $table->getColumn($name))) { throw new \Exception("Table '{$table->name}' does not have a column named '{$name}'."); } $keyNames[] = $prefix . $column->rawName; } $vs = array(); foreach ($values as $value) { $vs[] = '(' . implode(', ', $value) . ')'; } return '(' . implode(', ', $keyNames) . ') IN (' . implode(', ', $vs) . ')'; }
public function delete() { /** * ACL Enforcement */ $currentUserId = $this->acl->getUserId(); $cmsOwnerId = $this->acl->getRecordCmsOwnerId($this, $this->table); $isCurrentUserOwner = $cmsOwnerId === $currentUserId; $canBigDelete = false; $canDelete = false; if (TableSchema::hasTableColumn($this->table, STATUS_COLUMN_NAME)) { if ($this->acl->hasTablePrivilege($this->table, 'bigdelete')) { $canBigDelete = true; } else { if ($this->acl->hasTablePrivilege($this->table, 'delete')) { $canDelete = true; } } } if (!$canDelete && !$canBigDelete) { $aclErrorPrefix = $this->acl->getErrorMessagePrefix(); throw new UnauthorizedTableBigDeleteException($aclErrorPrefix . ' forbidden to hard delete on table `' . $this->table . '` because it has status column.'); } /** * Enforce Privilege: "Little" Delete (I am the record CMS owner) */ if ($isCurrentUserOwner && !$canDelete) { $recordPk = self::stringifyPrimaryKeyForRecordDebugRepresentation($this->primaryKeyData); $aclErrorPrefix = $this->acl->getErrorMessagePrefix(); throw new UnauthorizedTableDeleteException($aclErrorPrefix . 'Table harddelete access forbidden on `' . $this->table . '` table record with ' . $recordPk . ' owned by the authenticated CMS user (#' . $cmsOwnerId . ').'); } elseif (!$isCurrentUserOwner && !$canBigDelete) { /** * Enforce Privilege: "Big" Delete (I am not the record CMS owner) */ $recordPk = self::stringifyPrimaryKeyForRecordDebugRepresentation($this->primaryKeyData); $recordOwner = false === $cmsOwnerId ? 'no magic owner column' : 'the CMS owner #' . $cmsOwnerId; $aclErrorPrefix = $this->acl->getErrorMessagePrefix(); throw new UnauthorizedTableBigDeleteException($aclErrorPrefix . 'Table bigharddelete access forbidden on `' . $this->table . '` table record with $recordPk and ' . $recordOwner . '.'); } return parent::delete(); }