public static function import($path_csv, $path_resources = null, $mapping = array()) { $tag = "EntityImporter:import()"; Log::notice("{$tag}: <{$path_csv}, {$path_resources}, {$mapping}>"); // pseudo contants $IMPORT_MODE_INSERT = 0; $IMPORT_MODE_UPDATE = 1; // init results array $stat = array(); $stat["attempts"] = 0; $stat["inserts"] = 0; $stat["updates"] = 0; $stat["warnings"] = 0; $stat["errors"] = 0; // TODO: include sub-arrays for warning messages and error messages // eg: $stat["warning_messages"] = array(); where array indecies reference csv row numbers if (!is_readable($path_csv)) { Log::error("{$tag}: Unable to read from path {$path_csv}"); throw new Exception("{$tag}: Unable to read from path {$path_csv}"); } if ($path_resources != null && !is_readable($path_resources)) { Log::error("{$tag}: Unable to read from path {$path_resources}"); throw new Exception("{$tag}: Unable to read from path {$path_resources}"); } $csv_filename = basename($path_csv); $blueprint_key = substr($csv_filename, 0, strpos($csv_filename, ".")); $blueprint_signature = $blueprint_key . ".entity.xml"; Log::debug("{$tag}: Blueprint Signature: {$blueprint_signature}"); /* // Compare CSV Header with Blueprint // determine if mapping is required */ // read blueprint (on server) $bp = BlueprintReader::read($blueprint_signature); // init csv file for parsing $csv = new Csv($path_csv); // read csv header row $csv_header_row = $csv->nextRow(); // apply mappings for ($i = 0; $i < count($csv_header_row); $i++) { $import_field = $csv_header_row[$i]; $mapping_key = "mapping_" . $bp->getKey() . "_" . str_replace(".", "_", $import_field); // skip <id> columns if ($import_field == "id") { continue; } // skip columns where mapping is _DROP if (array_key_exists($mapping_key, $mapping) && $mapping[$mapping_key] == "_DROP") { continue; } if (array_key_exists($mapping_key, $mapping)) { // replace csv column header with mapped value $csv_header_row[$i] = $mapping["{$mapping_key}"]; } } foreach ($csv_header_row as $import_field) { // skip <id> columns if ($import_field == "id") { continue; } // skip columns where mapping is _DROP $mapping_key = "mapping_" . $bp->getKey() . "_" . str_replace(".", "_", $import_field); if (array_key_exists($mapping_key, $mapping) && $mapping[$mapping_key] == "_DROP") { continue; } if (!$bp->keyExists($import_field)) { throw new EntityImporterException($bp, $csv_header_row); } } // check for id column $with_ids = false; if (in_array("id", $csv_header_row)) { $with_ids = true; Log::debug("{$tag}: Importing with ids"); } // init Entity DAO $entityDAO = new EntityDAO($bp); // Import rows from Csv while (($row = $csv->nextRow()) !== FALSE) { $stat["attempts"]++; // init an entity to import unset($entity); // clear previous $entity = null; // flag an import mode (insert, update) $import_mode = EntityImporter::$IMPORT_MODE_INSERT; // check <id> to see if this csv row references an existing entity if ($with_ids) { $import_id = $row[0]; if (!empty($import_id) && $import_id != 0) { // check that an entity with this id exists try { if ($match = $entityDAO->load($import_id)) { $entity = $match; $import_mode = EntityImporter::$IMPORT_MODE_UPDATE; Log::debug("{$tag}: Updating an existing {$blueprint_signature} with id {$import_id}"); } else { $entity = $bp->build(); $entity->setId($import_id); Log::debug("{$tag}: Creating a new {$blueprint_signature} with id {$import_id}"); } } catch (Exception $e) { $stat["warnings"]++; Log::warning("{$tag}: Caught Exception: " . $e->getMessage()); $entity = $bp->build(); $entity->setId($import_id); Log::debug("{$tag}: Creating a new {$blueprint_signature} with id {$import_id}"); } } // END: if( (!empty($import_id)) && ($import_id!=0) ) } // END: if($with_ids) // if we are not working with an existing entity, build a new one if ($entity == null) { $entity = $bp->build(); Log::debug("{$tag}: Creating a new {$blueprint_signature} without an id"); } for ($i = 0; $i < count($csv_header_row); $i++) { // extract data from csv $import_field_key = $csv_header_row[$i]; $import_field_value = $row[$i]; // skid <id> column if ($import_field_key == "id") { continue; } // skip columns where mapping is _DROP $mapping_key = "mapping_" . $bp->getKey() . "_" . str_replace(".", "_", $import_field_key); if (array_key_exists($mapping_key, $mapping) && $mapping[$mapping_key] == "_DROP") { continue; } // extract field information from blueprint $field = $bp->get($import_field_key); switch ($field->getDataType()) { case "date": // reformat dates for mysql $time = strtotime($import_field_value); $import_field_value = date("Y-m-d", $time); $entity->set($import_field_key, $import_field_value); break; case "binary": $path_binary = $path_resources . $import_field_value; Log::debug("{$tag}: Searching for binary at path {$path_binary}"); if (is_readable($path_binary)) { Log::debug("{$tag}: Found readable binary at path {$path_binary}"); $binaryString = file_get_contents($path_binary); $entity->set($import_field_key, $binaryString); } else { Log::debug("{$tag}: No readable binary at path {$path_binary}"); } break; default: $entity->set($import_field_key, $import_field_value); break; } // END: switch($field->getType()) } // END: for($i=0; $i<count($csv_header_row); $i++) switch ($import_mode) { case EntityImporter::$IMPORT_MODE_UPDATE: try { $entityDAO->update($entity); $stat["updates"]++; } catch (Exception $e) { Log::warning("{$tag}: Caught Exception: " . $e->getMessage()); $stat["errors"]++; } break; case EntityImporter::$IMPORT_MODE_INSERT: try { $entityDAO->insert($entity); $stat["inserts"]++; } catch (Exception $e) { Log::warning("{$tag}: Caught Exception: " . $e->getMessage()); $stat["errors"]++; } break; } } // END: while( ($row = $csv->nextRow()) !== FALSE ) return $stat; }