logger->log($message, $level); } /** * Constructor. */ public function __construct($config = null) { $this->stats = sfIsisImporterStats::getInstance(); $this->isis = new IsisConnector($config); // Get a logger instance. $this->logger = sfIsisImporterLog::getInstance(); } /** * Get the model foreign table id. * * @param object $model Model * @return string Model table id */ static function getModelId($model) { return sfInflector::underscore(get_class($model)) .'_id'; } /** * Get the relation foreign table id. * * @param string $model Relation name * @return string Relation table id */ static function getRelationId($relation) { return sfInflector::underscore($relation) .'_id'; } /** * Get the model and relation tablename. * * @param object $model Model * @param string $model Relation name * @return string Relation table name */ static function getModelRelation($model, $relation) { return sfInflector::camelize(self::getModelName($model)) . sfInflector::camelize($relation); } /** * Get the model name. * * @param object $model Model * @return string Model name */ static function getModelName($model) { return get_class($model); } /** * Default implementation for parseName. * * @param mixed $value Name * @return mixed Name */ public function parseName($value) { return $value; } /** * Add a single entry from the database. * * @param string $base_model Model to use * @param int $entry Entry number */ public function addEntry($base_model, $entry) { // Get data and setup the model. $this->isis->read($entry); $model = $this->newModel($base_model); if ($model) { $this->log("Importing $base_model $entry..."); // Dispatch to custom import procedures. foreach (new IsisMethodIterator($this->isis, $this) as $method => $field) { if (!$this->hasDeniedCombinations($base_model, $field)) { $this->log("Calling $method for field ". $field['name'] .'.', 'debug'); $this->{$method}($model, $field); } } $model->save(); $model->free(true); } else { $this->log("Skipping existing entry $entry for $base_model."); } } /** * Create a new model just if doesn't exist for a given entry. For that * to work the entry must provide and id. * * @param string $base_model Model to use * @return mixed New model or false */ public function newModel($base_model) { $model = new $base_model(); $id = $this->getBaseModelId($model); if ($id) { $existing = call_user_func(array($base_model, 'getById'), $id); if (!$existing) { $this->setBaseModelId($model); return $model; } elseif ($this->skipExisting()) { return false; } else { return $existing; } } $model->save(); return $model; } /** * Check if ISIS database configuration is set to not skip existing * entries during an import. * * @return boolean */ public function skipExisting() { if (isset($this->isis->format['import']['skip_existing'])) { return $this->isis->format['import']['skip_existing']; } return true; } /** * Set the primary key for the model by getting it or just saving it. * * @param object $model Base model */ public function setBaseModelId(&$model) { $model->id = $this->getBaseModelId($model); $model->save(); } /** * Get the primary key for the base model. * * @param object $model Base model * @return int Base model id */ public function getBaseModelId(&$model) { $method = 'get'. $this->getModelName($model) .'PrimaryKey'; if (method_exists($this, $method)) { return $this->{$method}($model); } } /** * Check denied combinations inside a field. * * @param string $model Model name * @param array $field Field data from ISIS database schema * @return boolean True if has a denied combination, false otherwise * @todo Wildcard support * @todo Test */ public function hasDeniedCombinations($model, $field) { foreach ($this->isis->getDeniedCombinations($field) as $combination) { $has = true; foreach ($combination as $item) { foreach (new IsisRowIterator($this->isis, $field) as $row) { if (!$this->hasDeniedItem($field, $item, $row)) { $has = false; break 2; } } } if ($has) { $denied[$row] = $combination; } } if (isset($denied)) { foreach ($denied as $row => $combination) { $combination = implode(',', $combination); $this->log("Found denied combination for row $row: $combination"); } return true; } return false; } /** * Check if a field has a denied item. * * @param array $field Field data from ISIS database schema * @param string $item Item code * @param int $row Row number * @return boolean True if has a denied combination, false otherwise * @todo Wildcard * @todo Test */ public function hasDeniedItem($field, $item, $row) { // Default condition: presence requirement for an item. $condition = true; // Check if item has the negation (absence) requirement for an item. if (substr($item, 0, 1) == '!') { $item = substr($item, 1); $condition = false; } // Check if the item exists. $has = $this->isis->hasItem($field, $item, $row); if ($condition == true) { // If the condition is true, a denied combination won't be fulfilled if // the item is not present. if (!$has) { return false; } } else { // If the condition is false, a denied combination won't be fulfilled if // the item is present. if ($has) { return false; } } return true; } }