Esempio n. 1
0
 /**
  * Reindex PDF media by content for in-PDF search
  */
 public static function reindex_pdfs($po_opts = null)
 {
     require_once __CA_LIB_DIR__ . "/core/Db.php";
     require_once __CA_MODELS_DIR__ . "/ca_object_representations.php";
     if (!caPDFMinerInstalled()) {
         CLIUtils::addError(_t("Can't reindex PDFs: PDFMiner is not installed."));
         return false;
     }
     $o_db = new Db();
     $t_rep = new ca_object_representations();
     $t_rep->setMode(ACCESS_WRITE);
     $va_versions = array("original");
     $va_kinds = ($vs_kinds = $po_opts->getOption("kinds")) ? explode(",", $vs_kinds) : array();
     if (!is_array($va_kinds) || !sizeof($va_kinds)) {
         $va_kinds = array('all');
     }
     $va_kinds = array_map('strtolower', $va_kinds);
     if (in_array('all', $va_kinds) || in_array('ca_object_representations', $va_kinds)) {
         if (!($vn_start = (int) $po_opts->getOption('start_id'))) {
             $vn_start = null;
         }
         if (!($vn_end = (int) $po_opts->getOption('end_id'))) {
             $vn_end = null;
         }
         if ($vn_id = (int) $po_opts->getOption('id')) {
             $vn_start = $vn_id;
             $vn_end = $vn_id;
         }
         $va_ids = array();
         if ($vs_ids = (string) $po_opts->getOption('ids')) {
             if (sizeof($va_tmp = explode(",", $vs_ids))) {
                 foreach ($va_tmp as $vn_id) {
                     if ((int) $vn_id > 0) {
                         $va_ids[] = (int) $vn_id;
                     }
                 }
             }
         }
         $vs_sql_where = null;
         $va_params = array();
         if (sizeof($va_ids)) {
             $vs_sql_where = "WHERE representation_id IN (?)";
             $va_params[] = $va_ids;
         } else {
             if ($vn_start > 0 && $vn_end > 0 && $vn_start <= $vn_end || $vn_start > 0 && $vn_end == null) {
                 $vs_sql_where = "WHERE representation_id >= ?";
                 $va_params[] = $vn_start;
                 if ($vn_end) {
                     $vs_sql_where .= " AND representation_id <= ?";
                     $va_params[] = $vn_end;
                 }
             }
         }
         if ($vs_sql_where) {
             $vs_sql_where .= " AND mimetype = 'application/pdf'";
         } else {
             $vs_sql_where = " WHERE mimetype = 'application/pdf'";
         }
         $qr_reps = $o_db->query("\n\t\t\t\t\tSELECT * \n\t\t\t\t\tFROM ca_object_representations \n\t\t\t\t\t{$vs_sql_where}\n\t\t\t\t\tORDER BY representation_id\n\t\t\t\t", $va_params);
         print CLIProgressBar::start($qr_reps->numRows(), _t('Reindexing PDF representations'));
         $vn_rep_table_num = $t_rep->tableNum();
         while ($qr_reps->nextRow()) {
             $va_media_info = $qr_reps->getMediaInfo('media');
             $vs_original_filename = $va_media_info['ORIGINAL_FILENAME'];
             print CLIProgressBar::next(1, _t("Reindexing PDF %1", $vs_original_filename ? $vs_original_filename . " (" . $qr_reps->get('representation_id') . ")" : $qr_reps->get('representation_id')));
             $t_rep->load($qr_reps->get('representation_id'));
             $vn_rep_id = $t_rep->getPrimaryKey();
             $m = new Media();
             if ($m->read($vs_path = $t_rep->getMediaPath('media', 'original')) && is_array($va_locs = $m->getExtractedTextLocations())) {
                 MediaContentLocationIndexer::clear($vn_rep_table_num, $vn_rep_id);
                 foreach ($va_locs as $vs_content => $va_loc_list) {
                     foreach ($va_loc_list as $va_loc) {
                         MediaContentLocationIndexer::index($vn_rep_table_num, $vn_rep_id, $vs_content, $va_loc['p'], $va_loc['x1'], $va_loc['y1'], $va_loc['x2'], $va_loc['y2']);
                     }
                 }
                 MediaContentLocationIndexer::write();
             } else {
                 //CLIUtils::addError(_t("[Warning] No content to reindex for PDF representation: %1", $vs_path));
             }
         }
         print CLIProgressBar::finish();
     }
     if (in_array('all', $va_kinds) || in_array('ca_attributes', $va_kinds)) {
         // get all Media elements
         $va_elements = ca_metadata_elements::getElementsAsList(false, null, null, true, false, true, array(16));
         // 16=media
         $qr_c = $o_db->query("\n\t\t\t\t\tSELECT count(*) c \n\t\t\t\t\tFROM ca_attribute_values\n\t\t\t\t\tWHERE\n\t\t\t\t\t\telement_id in (?)\n\t\t\t\t", caExtractValuesFromArrayList($va_elements, 'element_id', array('preserveKeys' => false)));
         if ($qr_c->nextRow()) {
             $vn_count = $qr_c->get('c');
         } else {
             $vn_count = 0;
         }
         $t_attr_val = new ca_attribute_values();
         $vn_attr_table_num = $t_attr_val->tableNum();
         print CLIProgressBar::start($vn_count, _t('Reindexing metadata attribute media'));
         foreach ($va_elements as $vs_element_code => $va_element_info) {
             $qr_vals = $o_db->query("SELECT value_id FROM ca_attribute_values WHERE element_id = ?", (int) $va_element_info['element_id']);
             $va_vals = $qr_vals->getAllFieldValues('value_id');
             foreach ($va_vals as $vn_value_id) {
                 $t_attr_val = new ca_attribute_values($vn_value_id);
                 if ($t_attr_val->getPrimaryKey()) {
                     $t_attr_val->setMode(ACCESS_WRITE);
                     $t_attr_val->useBlobAsMediaField(true);
                     $va_media_info = $t_attr_val->getMediaInfo('value_blob');
                     $vs_original_filename = $va_media_info['ORIGINAL_FILENAME'];
                     if (!is_array($va_media_info) || $va_media_info['MIMETYPE'] !== 'application/pdf') {
                         continue;
                     }
                     print CLIProgressBar::next(1, _t("Reindexing %1", $vs_original_filename ? $vs_original_filename . " ({$vn_value_id})" : $vn_value_id));
                     $m = new Media();
                     if ($m->read($vs_path = $t_attr_val->getMediaPath('value_blob', 'original')) && is_array($va_locs = $m->getExtractedTextLocations())) {
                         MediaContentLocationIndexer::clear($vn_attr_table_num, $vn_attr_table_num);
                         foreach ($va_locs as $vs_content => $va_loc_list) {
                             foreach ($va_loc_list as $va_loc) {
                                 MediaContentLocationIndexer::index($vn_attr_table_num, $vn_value_id, $vs_content, $va_loc['p'], $va_loc['x1'], $va_loc['y1'], $va_loc['x2'], $va_loc['y2']);
                             }
                         }
                         MediaContentLocationIndexer::write();
                     } else {
                         //CLIUtils::addError(_t("[Warning] No content to reindex for PDF in metadata attribute: %1", $vs_path));
                     }
                 }
             }
         }
         print CLIProgressBar::finish();
     }
     return true;
 }
Esempio n. 2
0
 /**
  * Returns content for overlay containing details for object representation
  *
  * Expects the following request parameters: 
  *		object_id = the id of the ca_objects record to display
  *		representation_id = the id of the ca_object_representations record to display; the representation must belong to the specified object
  *
  *	Optional request parameters:
  *		version = The version of the representation to display. If omitted the display version configured in media_display.conf is used
  *		order_item_id = ca_commerce_order_items.item_id value to limit representation display to
  *
  */
 public function GetRepresentationInfo()
 {
     $pn_object_id = $this->request->getParameter('object_id', pInteger);
     $pn_representation_id = $this->request->getParameter('representation_id', pInteger);
     if (!($ps_display_type = trim($this->request->getParameter('display_type', pString)))) {
         $ps_display_type = 'media_overlay';
     }
     if (!($ps_containerID = trim($this->request->getParameter('containerID', pString)))) {
         $ps_containerID = 'caMediaPanelContentArea';
     }
     if (!$pn_object_id) {
         $pn_object_id = 0;
     }
     $t_rep = new ca_object_representations($pn_representation_id);
     if (!$t_rep->getPrimaryKey()) {
         $this->postError(1100, _t('Invalid object/representation'), 'DetailController->GetRepresentationInfo');
         return;
     }
     $va_opts = array('display' => $ps_display_type, 'object_id' => $pn_object_id, 'containerID' => $ps_containerID, 'access' => caGetUserAccessValues($this->request));
     if (strlen($vs_use_book_viewer = $this->request->getParameter('use_book_viewer', pInteger))) {
         $va_opts['use_book_viewer'] = (bool) $vs_use_book_viewer;
     }
     $vs_output = $t_rep->getRepresentationViewerHTMLBundle($this->request, $va_opts);
     if ($this->request->getParameter('include_tool_bar', pInteger)) {
         $vs_output = "<div class='repViewerContCont'><div id='cont{$vn_rep_id}' class='repViewerCont'>" . $vs_output . caRepToolbar($this->request, $t_rep, $pn_object_id) . "</div></div>";
     }
     $this->response->addContent($vs_output);
 }
if ($vn_audio_rep_id) {
    $t_rep->load($vn_audio_rep_id);
    $va_annotations = $t_rep->getAnnotations(array("checkAccess" => $this->getVar("access_values")));
    #print_r($va_annotations);
    print $t_rep->getMediaTag("media", $va_audio_media_display_info["display_version"], $va_audio_media_display_info, array("id" => "caPlayer"));
}
?>
					<div id="detailTools">						
						<div class="detailTool detailToolRight"><span class="glyphicon glyphicon-share-alt"></span>{{{shareLink}}}</div><!-- end detailTool -->
<?php 
print "<div class='detailTool'>";
if (caObjectsDisplayDownloadLink($this->request) && $vn_audio_rep_id) {
    # -- get version to download configured in media_display.conf
    $va_download_display_info = caGetMediaDisplayInfo('download', $t_rep->getMediaInfo('media', 'INPUT', 'MIMETYPE'));
    $vs_download_version = $va_download_display_info['display_version'];
    print caNavLink($this->request, " <span class='glyphicon glyphicon-download-alt'></span>", '', 'Detail', 'DownloadRepresentation', '', array('representation_id' => $t_rep->getPrimaryKey(), "object_id" => $t_object->get("object_id"), "download" => 1, "version" => $vs_download_version), array("title" => _t("Download"))) . "&nbsp;&nbsp;&nbsp;&nbsp;";
}
print $vs_transcript_link;
print "</div>";
?>
					</div>
					<HR class="dark"/>
				</div><!-- end col -->
			</div><!-- end row -->
			<div class="row">
				<div class='col-sm-12 col-md-6 col-lg-6'>
					{{{<unit relativeTo="ca_entities" restrictToRelationshipTypes="interviewer" delimiter=";"><H3>Interviewer:</H3><l>^ca_entities.preferred_labels.displayname</l></unit>}}}
					{{{<unit relativeTo="ca_entities" restrictToRelationshipTypes="interviewee" delimiter=";"><H3>Interviewee:</H3><l>^ca_entities.preferred_labels.displayname</l></unit>}}}
					{{{<unit relativeTo="ca_entities" restrictToRelationshipTypes="speaker" delimiter=";"><H3>Speaker:</H3><l>^ca_entities.preferred_labels.displayname</l></unit>}}}
					{{{<unit relativeTo="ca_entities" restrictToRelationshipTypes="sponsoring_body" delimiter=";"><H3>Sponsoring Body:</H3><l>^ca_entities.preferred_labels.displayname</l></unit>}}}
					{{{<ifdef code="ca_objects.pbcoreDate.pbcoreDates_value"><H3>Date:</H3>^ca_objects.pbcoreDate.pbcoreDates_value<br/></ifdef>}}}
 $va_related_objects_links = $t_occurrence->get("ca_objects_x_occurrences.relation_id", array("returnAsArray" => true));
 if (sizeof($va_related_objects_links)) {
     $t_objects_x_occurrences = new ca_objects_x_occurrences();
     $t_object = new ca_objects();
     foreach ($va_related_objects_links as $vn_relation_id) {
         $t_objects_x_occurrences->load($vn_relation_id);
         $va_reps = $t_objects_x_occurrences->get("ca_objects_x_occurrences.representation_list", array("returnAsArray" => true, 'idsOnly' => true));
         if (is_array($va_reps)) {
             foreach ($va_reps as $vn_i => $va_attr) {
                 $t_rep = new ca_object_representations($va_attr['representation_list']);
                 print "<div class='unit'>";
                 if ($ps_mode == "print") {
                     print "<input type='checkbox' checked name='print_fields[]' value='rep" . $t_rep->get("representation_id") . "'> ";
                 }
                 # --- open in media viewer
                 print "<a href='#' onclick='caMediaPanel.showPanel(\"" . caNavUrl($this->request, 'Detail', 'Object', 'GetRepresentationInfo', array('object_id' => $t_objects_x_occurrences->get("ca_objects.object_id"), 'representation_id' => $t_rep->getPrimaryKey())) . "\"); return false;' >" . $t_rep->getMediaTag('media', 'medium') . "</a>";
                 #print $t_rep->getMediaTag('media', 'medium');
                 print "</div><!-- end unit -->";
             }
         }
         print "<div class='unit' style='font-size:11px; font-style:italic;'>" . caNavLink($this->request, $t_objects_x_occurrences->get("ca_objects.preferred_labels.name"), '', 'Detail', 'Object', 'Show', array('object_id' => $t_objects_x_occurrences->get("ca_objects.object_id")));
         if ($va_dates = $t_objects_x_occurrences->get("ca_objects.date", array("returnAsArray" => true))) {
             foreach ($va_dates as $va_date_info) {
                 if ($va_date_info["dc_dates_types"] == $vn_original_date) {
                     print ", " . $va_date_info["dates_value"];
                 }
             }
         }
         if ($t_objects_x_occurrences->get("ca_objects.repository")) {
             print ", " . $t_objects_x_occurrences->get("ca_objects.repository", array('delimiter' => ', ', 'convertCodesToDisplayText' => true));
         }
 /**
  * Override set() to do idno_stub lookups on lots
  *
  * @param mixed $pm_fields
  * @param mixed $pm_value
  * @param array $pa_options Most options are handled by subclasses. Options defined here include:
  *		assumeIdnoStubForLotID = set to force lookup of lot_id values as ca_object_lots.idno_stub values first not matter what, before consideration as a numeric lot_id. The default is false, in which case integer values are considered lot_ids and non-numeric values possible idno_stubs.
  *		
  * @return int 
  */
 public function set($pm_fields, $pm_value = "", $pa_options = null)
 {
     if (!is_array($pm_fields)) {
         $pm_fields = array($pm_fields => $pm_value);
     }
     $pb_assume_idno_for_representation_id = caGetOption('assumeIdnoForRepresentationID', $pa_options, false);
     foreach ($pm_fields as $vs_fld => $vs_val) {
         if ($vs_fld == 'representation_id' && ($pb_assume_idno_for_representation_id || preg_match("![^\\d]+!", $vs_val))) {
             $t_rep = new ca_object_representations();
             if ($t_rep->load(array('idno' => $vs_val, 'deleted' => 0))) {
                 $vn_representation_id = (int) $t_rep->getPrimaryKey();
                 $pm_fields[$vs_fld] = $vn_representation_id;
                 if ($vn_rc = parent::set($pm_fields, null, $pa_options)) {
                     $this->set('type_code', $vs_type = $this->getAnnotationType());
                 }
                 return $vn_rc;
             }
         }
     }
     return parent::set($pm_fields, null, $pa_options);
 }
 /**
  * Apply changes made in representation editor to representation media
  *
  */
 public function ProcessMedia()
 {
     list($vn_object_id, $t_object) = $this->_initView();
     $pn_representation_id = $this->request->getParameter('representation_id', pInteger);
     $ps_op = $this->request->getParameter('op', pString);
     $pn_angle = $this->request->getParameter('angle', pInteger);
     $pb_revert = (bool) $this->request->getParameter('revert', pInteger);
     $t_rep = new ca_object_representations($pn_representation_id);
     if (!$t_rep->getPrimaryKey()) {
         $va_response = array('action' => 'process', 'status' => 20, 'message' => _t('Invalid representation_id'));
     } else {
         if ($t_rep->applyMediaTransformation('media', $ps_op, array('angle' => $pn_angle), array('revert' => $pb_revert))) {
             $va_response = array('action' => 'process', 'status' => 0, 'message' => 'OK', 'op' => $ps_op, 'angle' => $pn_angle);
         } else {
             $va_response = array('action' => 'process', 'status' => 10, 'message' => _t('Transformation failed'));
         }
     }
     $this->view->setVar('response', $va_response);
     $this->render('object_representation_process_media_json.php');
 }
 /** 
  * Add media represention to currently loaded item
  *
  * @param $ps_media_path - the path to the media you want to add
  * @param $pn_type_id - the item_id of the representation type, in the ca_list with list_code 'object_represention_types'
  * @param $pn_locale_id - the locale_id of the locale of the representation
  * @param $pn_status - the status code for the representation (as defined in item_value fields of items in the 'workflow_statuses' ca_list)
  * @param $pn_access - the access code for the representation (as defined in item_value fields of items in the 'access_statuses' ca_list)
  * @param $pb_is_primary - if set to true, representation is designated "primary." Primary representation are used in cases where only one representation is required (such as search results). If a primary representation is already attached to this item, then it will be changed to non-primary as only one representation can be primary at any given time. If no primary representations exist, then the new representation will always be marked primary no matter what the setting of this parameter (there must always be a primary representation, if representations are defined).
  * @param $pa_values - array of attributes to attach to new representation
  * @param $pa_options - an array of options passed through to BaseModel::set() when creating the new representation. Currently supported options:
  *		original_filename - the name of the file being uploaded; will be recorded in the database and used as the filename when the file is subsequently downloaded
  *		rank - a numeric rank used to order the representations when listed
  *		returnRepresentation = if set the newly created ca_object_representations instance is returned rather than the link_id of the newly created relationship record
  *
  * @return mixed Returns primary key (link_id) of the relatipnship row linking the newly created representation to the item; if the 'returnRepresentation' is set then an instance for the newly created ca_object_representations is returned instead; boolean false is returned on error
  */
 public function addRepresentation($ps_media_path, $pn_type_id, $pn_locale_id, $pn_status, $pn_access, $pb_is_primary, $pa_values = null, $pa_options = null)
 {
     if (!($vn_id = $this->getPrimaryKey())) {
         return null;
     }
     if (!$pn_locale_id) {
         $pn_locale_id = ca_locales::getDefaultCataloguingLocaleID();
     }
     $t_rep = new ca_object_representations();
     if ($this->inTransaction()) {
         $o_trans = $this->getTransaction();
         $t_rep->setTransaction($o_trans);
     }
     $t_rep->setMode(ACCESS_WRITE);
     $t_rep->set('type_id', $pn_type_id);
     $t_rep->set('locale_id', $pn_locale_id);
     $t_rep->set('status', $pn_status);
     $t_rep->set('access', $pn_access);
     $t_rep->set('media', $ps_media_path, $pa_options);
     if (is_array($pa_values)) {
         if (isset($pa_values['idno'])) {
             $t_rep->set('idno', $pa_values['idno']);
         }
         foreach ($pa_values as $vs_element => $va_value) {
             if (is_array($va_value)) {
                 // array of values (complex multi-valued attribute)
                 $t_rep->addAttribute(array_merge($va_value, array('locale_id' => $pn_locale_id)), $vs_element);
             } else {
                 // scalar value (simple single value attribute)
                 if ($va_value) {
                     $t_rep->addAttribute(array('locale_id' => $pn_locale_id, $vs_element => $va_value), $vs_element);
                 }
             }
         }
     }
     $t_rep->insert();
     if ($t_rep->numErrors()) {
         $this->errors = array_merge($this->errors, $t_rep->errors());
         return false;
     }
     if ($t_rep->getPreferredLabelCount() == 0) {
         $vs_label = isset($pa_values['name']) && $pa_values['name'] ? $pa_values['name'] : '[' . _t('BLANK') . ']';
         $t_rep->addLabel(array('name' => $vs_label), $pn_locale_id, null, true);
         if ($t_rep->numErrors()) {
             $this->errors = array_merge($this->errors, $t_rep->errors());
             return false;
         }
     }
     if (!($t_oxor = $this->_getRepresentationRelationshipTableInstance())) {
         return null;
     }
     $vs_pk = $this->primaryKey();
     if ($this->inTransaction()) {
         $o_trans = $this->getTransaction();
         $t_oxor->setTransaction($o_trans);
     }
     $t_oxor->setMode(ACCESS_WRITE);
     $t_oxor->set($vs_pk, $vn_id);
     $t_oxor->set('representation_id', $t_rep->getPrimaryKey());
     $t_oxor->set('is_primary', $pb_is_primary ? 1 : 0);
     $t_oxor->set('rank', isset($pa_options['rank']) ? (int) $pa_options['rank'] : null);
     if ($t_oxor->hasField('type_id')) {
         $t_oxor->set('type_id', isset($pa_options['type_id']) ? (int) $pa_options['type_id'] : null);
     }
     $t_oxor->insert();
     if ($t_oxor->numErrors()) {
         $this->errors = array_merge($this->errors, $t_oxor->errors());
         $t_rep->delete();
         if ($t_rep->numErrors()) {
             $this->errors = array_merge($this->errors, $t_rep->errors());
         }
         return false;
     }
     //
     // Perform mapping of embedded metadata for newly uploaded representation with respect
     // to ca_objects and ca_object_representation records
     //
     $va_metadata = $t_rep->get('media_metadata', array('binary' => true));
     if (caExtractEmbeddedMetadata($this, $va_metadata, $pn_locale_id)) {
         $this->update();
     }
     if (isset($pa_options['returnRepresentation']) && (bool) $pa_options['returnRepresentation']) {
         return $t_rep;
     }
     return $t_oxor->getPrimaryKey();
 }
Esempio n. 8
0
 /**
  * Returns representation_id for the object representation with the specified name (and type) or idno (regardless of specified type.) If the object does
  * not already exist then it will be created with the specified name, type and locale, as well as with any specified values in the $pa_values array.
  * $pa_values keys should be either valid object fields or attributes.
  *
  * @param string $ps_representation_name Object label name
  * @param int $pn_type_id The type_id of the object type to use if the representation needs to be created
  * @param int $pn_locale_id The locale_id to use if the representation needs to be created (will be used for both the object locale as well as the label locale)
  * @param array $pa_values An optional array of additional values to populate newly created representation records with. These values are *only* used for newly created representation; they will not be applied if the representation named already exists. The array keys should be names of ca_object_representations fields or valid representation attributes. Values should be either a scalar (for single-value attributes) or an array of values for (multi-valued attributes)
  * @param array $pa_options An optional array of options, which include:
  *                outputErrors - if true, errors will be printed to console [default=false]
  *                matchOn = optional list indicating sequence of checks for an existing record; values of array can be "label" and "idno". Ex. array("idno", "label") will first try to match on idno and then label if the first match fails.
  *                dontCreate - if true then new representations will not be created [default=false]
  *                transaction - if Transaction object is passed, use it for all Db-related tasks [default=null]
  *                returnInstance = return ca_object_representations instance rather than representation_id. Default is false.
  *                generateIdnoWithTemplate = A template to use when setting the idno. The template is a value with automatically-set SERIAL values replaced with % characters. Eg. 2012.% will set the created row's idno value to 2012.121 (assuming that 121 is the next number in the serial sequence.) The template is NOT used if idno is passed explicitly as a value in $pa_values.
  *                importEvent = if ca_data_import_events instance is passed then the insert/update of the representation will be logged as part of the import
  *                importEventSource = if importEvent is passed, then the value set for importEventSource is used in the import event log as the data source. If omitted a default value of "?" is used
  *                nonPreferredLabels = an optional array of nonpreferred labels to add to any newly created representations. Each label in the array is an array with required representation label values.
  *                log = if KLogger instance is passed then actions will be logged
  *				  matchMediaFilesWithoutExtension = if media path is invalid, attempt to find media in referenced directory and sub-directories that has a matching name, regardless of file extension. [default=false] 
  * @return bool|ca_object_representations|mixed|null
  */
 static function getObjectRepresentationID($ps_representation_name, $pn_type_id, $pn_locale_id, $pa_values = null, $pa_options = null)
 {
     if (!is_array($pa_options)) {
         $pa_options = array();
     }
     if (!isset($pa_options['outputErrors'])) {
         $pa_options['outputErrors'] = false;
     }
     $vb_match_media_without_extension = caGetOption('matchMediaFilesWithoutExtension', $pa_options, false);
     $pa_match_on = caGetOption('matchOn', $pa_options, array('label', 'idno'), array('castTo' => "array"));
     /** @var ca_data_import_events $o_event */
     $o_event = isset($pa_options['importEvent']) && $pa_options['importEvent'] instanceof ca_data_import_events ? $pa_options['importEvent'] : null;
     $t_rep = new ca_object_representations();
     if (isset($pa_options['transaction']) && $pa_options['transaction'] instanceof Transaction) {
         $t_rep->setTransaction($pa_options['transaction']);
         if ($o_event) {
             $o_event->setTransaction($pa_options['transaction']);
         }
     }
     $vs_event_source = isset($pa_options['importEventSource']) && $pa_options['importEventSource'] ? $pa_options['importEventSource'] : "?";
     /** @var KLogger $o_log */
     $o_log = isset($pa_options['log']) && $pa_options['log'] instanceof KLogger ? $pa_options['log'] : null;
     $vs_idno = isset($pa_values['idno']) ? (string) $pa_values['idno'] : null;
     if (preg_match('!\\%!', $vs_idno)) {
         $pa_options['generateIdnoWithTemplate'] = $vs_idno;
         $vs_idno = null;
     }
     if (!$vs_idno) {
         if (isset($pa_options['generateIdnoWithTemplate']) && $pa_options['generateIdnoWithTemplate']) {
             $vs_idno = $t_rep->setIdnoWithTemplate($pa_options['generateIdnoWithTemplate'], array('dontSetValue' => true));
         }
     }
     $va_regex_list = caBatchGetMediaFilenameToIdnoRegexList(array('log' => $o_log));
     // Get list of replacements that user can use to transform file names to match object idnos
     $va_replacements_list = caBatchGetMediaFilenameReplacementRegexList(array('log' => $o_log));
     $vn_id = null;
     foreach ($pa_match_on as $vs_match_on) {
         switch (strtolower($vs_match_on)) {
             case 'label':
             case 'labels':
                 if (trim($ps_representation_name)) {
                     if ($vn_id = ca_object_representations::find(array('preferred_labels' => array('name' => $ps_representation_name), 'type_id' => $pn_type_id), array('returnAs' => 'firstId', 'transaction' => $pa_options['transaction']))) {
                         break 2;
                     }
                 }
                 break;
             case 'idno':
                 if (!$vs_idno) {
                     break;
                 }
                 if ($vs_idno == '%') {
                     break;
                 }
                 // don't try to match on an unreplaced idno placeholder
                 $va_idnos_to_match = array($vs_idno);
                 if (is_array($va_replacements_list)) {
                     foreach ($va_replacements_list as $vs_replacement_code => $va_replacement) {
                         if (isset($va_replacement['search']) && is_array($va_replacement['search'])) {
                             $va_replace = caGetOption('replace', $va_replacement);
                             $va_search = array();
                             foreach ($va_replacement['search'] as $vs_search) {
                                 $va_search[] = '!' . $vs_search . '!';
                             }
                             if ($vs_idno_proc = @preg_replace($va_search, $va_replace, $vs_idno)) {
                                 $va_idnos_to_match[] = $vs_idno_proc;
                             }
                         }
                     }
                 }
                 if (is_array($va_regex_list) && sizeof($va_regex_list)) {
                     foreach ($va_regex_list as $vs_regex_name => $va_regex_info) {
                         foreach ($va_regex_info['regexes'] as $vs_regex) {
                             foreach ($va_idnos_to_match as $vs_idno_match) {
                                 if (!$vs_idno_match) {
                                     continue;
                                 }
                                 if (preg_match('!' . $vs_regex . '!', $vs_idno_match, $va_matches)) {
                                     if ($vn_id = ca_object_representations::find(array('idno' => $va_matches[1]), array('returnAs' => 'firstId', 'transaction' => $pa_options['transaction']))) {
                                         break 5;
                                     }
                                 }
                             }
                         }
                     }
                 } else {
                     foreach ($va_idnos_to_match as $vs_idno_match) {
                         if (!$vs_idno_match) {
                             continue;
                         }
                         if ($vn_id = ca_object_representations::find(array('idno' => $vs_idno_match), array('returnAs' => 'firstId', 'transaction' => $pa_options['transaction']))) {
                             break 3;
                         }
                     }
                 }
                 break;
         }
     }
     if (!$vn_id) {
         if (isset($pa_options['dontCreate']) && $pa_options['dontCreate']) {
             return false;
         }
         if ($o_event) {
             $o_event->beginItem($vs_event_source, 'ca_object_representations', 'I');
         }
         $t_rep->setMode(ACCESS_WRITE);
         $t_rep->set('locale_id', $pn_locale_id);
         $t_rep->set('type_id', $pn_type_id);
         $t_rep->set('source_id', isset($pa_values['source_id']) ? $pa_values['source_id'] : null);
         $t_rep->set('access', isset($pa_values['access']) ? $pa_values['access'] : 0);
         $t_rep->set('status', isset($pa_values['status']) ? $pa_values['status'] : 0);
         if (isset($pa_values['media']) && $pa_values['media']) {
             if ($vb_match_media_without_extension && !isURL($pa_values['media']) && !file_exists($pa_values['media'])) {
                 $vs_dirname = pathinfo($pa_values['media'], PATHINFO_DIRNAME);
                 $vs_filename = preg_replace('!\\.[A-Za-z0-9]{1,4}$!', '', pathinfo($pa_values['media'], PATHINFO_BASENAME));
                 $vs_original_path = $pa_values['media'];
                 $pa_values['media'] = null;
                 $va_files_in_dir = caGetDirectoryContentsAsList($vs_dirname, true, false, false, false);
                 foreach ($va_files_in_dir as $vs_filepath) {
                     if ($o_log) {
                         $o_log->logDebug(_t("Trying media %1 in place of %2/%3", $vs_filepath, $vs_original_path, $vs_filename));
                     }
                     if (pathinfo($vs_filepath, PATHINFO_FILENAME) == $vs_filename) {
                         if ($o_log) {
                             $o_log->logNotice(_t("Found media %1 for %2/%3", $vs_filepath, $vs_original_path, $vs_filename));
                         }
                         $pa_values['media'] = $vs_filepath;
                         break;
                     }
                 }
             }
             $t_rep->set('media', $pa_values['media']);
         }
         $t_rep->set('idno', $vs_idno);
         $t_rep->insert();
         if ($t_rep->numErrors()) {
             if (isset($pa_options['outputErrors']) && $pa_options['outputErrors']) {
                 print "[Error] " . _t("Could not insert object %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())) . "\n";
             }
             if ($o_log) {
                 $o_log->logError(_t("Could not insert object %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())));
             }
             return null;
         }
         $vb_label_errors = false;
         $t_rep->addLabel(array('name' => $ps_representation_name), $pn_locale_id, null, true);
         if ($t_rep->numErrors()) {
             if (isset($pa_options['outputErrors']) && $pa_options['outputErrors']) {
                 print "[Error] " . _t("Could not set preferred label for object %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())) . "\n";
             }
             if ($o_log) {
                 $o_log->logError(_t("Could not set preferred label for object %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())));
             }
             $vb_label_errors = true;
         }
         /** @var IIDNumbering $o_idno */
         if ($o_idno = $t_rep->getIDNoPlugInInstance()) {
             $va_values = $o_idno->htmlFormValuesAsArray('idno', $vs_idno);
             if (!is_array($va_values)) {
                 $va_values = array($va_values);
             }
             if (!($vs_sep = $o_idno->getSeparator())) {
                 $vs_sep = '';
             }
             if (($vs_proc_idno = join($vs_sep, $va_values)) && $vs_proc_idno != $vs_idno) {
                 $t_rep->set('idno', $vs_proc_idno);
                 $t_rep->update();
                 if ($t_rep->numErrors()) {
                     if (isset($pa_options['outputErrors']) && $pa_options['outputErrors']) {
                         print "[Error] " . _t("Could not update idno for %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())) . "\n";
                     }
                     if ($o_log) {
                         $o_log->logError(_t("Could not object idno for %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())));
                     }
                     return null;
                 }
             }
         }
         unset($pa_values['access']);
         unset($pa_values['status']);
         unset($pa_values['idno']);
         unset($pa_values['source_id']);
         $vb_attr_errors = false;
         if (is_array($pa_values)) {
             foreach ($pa_values as $vs_element => $va_values) {
                 if (!caIsIndexedArray($va_values)) {
                     $va_values = array($va_values);
                 }
                 foreach ($va_values as $va_value) {
                     if (is_array($va_value)) {
                         // array of values (complex multi-valued attribute)
                         $t_rep->addAttribute(array_merge($va_value, array('locale_id' => $pn_locale_id)), $vs_element);
                     } else {
                         // scalar value (simple single value attribute)
                         if ($va_value) {
                             $t_rep->addAttribute(array('locale_id' => $pn_locale_id, $vs_element => $va_value), $vs_element);
                         }
                     }
                 }
             }
             $t_rep->update();
             if ($t_rep->numErrors()) {
                 if (isset($pa_options['outputErrors']) && $pa_options['outputErrors']) {
                     print "[Error] " . _t("Could not set values for representation %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())) . "\n";
                 }
                 if ($o_log) {
                     $o_log->logError(_t("Could not set values for representation %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())));
                 }
                 $vb_attr_errors = true;
             }
         }
         if (is_array($va_nonpreferred_labels = caGetOption("nonPreferredLabels", $pa_options, null))) {
             if (caIsAssociativeArray($va_nonpreferred_labels)) {
                 // single non-preferred label
                 $va_labels = array($va_nonpreferred_labels);
             } else {
                 // list of non-preferred labels
                 $va_labels = $va_nonpreferred_labels;
             }
             foreach ($va_labels as $va_label) {
                 $t_rep->addLabel($va_label, $pn_locale_id, null, false);
                 if ($t_rep->numErrors()) {
                     if (isset($pa_options['outputErrors']) && $pa_options['outputErrors']) {
                         print "[Error] " . _t("Could not set non-preferred label for representation %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())) . "\n";
                     }
                     if ($o_log) {
                         $o_log->logError(_t("Could not set non-preferred label for representation %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())));
                     }
                 }
             }
         }
         $vn_representation_id = $t_rep->getPrimaryKey();
         if ($o_event) {
             if ($vb_attr_errors || $vb_label_errors) {
                 $o_event->endItem($vn_representation_id, __CA_DATA_IMPORT_ITEM_PARTIAL_SUCCESS__, _t("Errors setting field values: %1", join('; ', $t_rep->getErrors())));
             } else {
                 $o_event->endItem($vn_representation_id, __CA_DATA_IMPORT_ITEM_SUCCESS__, '');
             }
         }
         if ($o_log) {
             $o_log->logInfo(_t("Created new representation %1", $ps_representation_name));
         }
         if (isset($pa_options['returnInstance']) && $pa_options['returnInstance']) {
             return $t_rep;
         }
     } else {
         if ($o_event) {
             $o_event->beginItem($vs_event_source, 'ca_object_representations', 'U');
         }
         $vn_representation_id = $vn_id;
         if ($o_event) {
             $o_event->endItem($vn_representation_id, __CA_DATA_IMPORT_ITEM_SUCCESS__, '');
         }
         if ($o_log) {
             $o_log->logDebug(_t("Found existing representation %1 in DataMigrationUtils::getObjectRepresentationID()", $ps_representation_name));
         }
         if (isset($pa_options['returnInstance']) && $pa_options['returnInstance']) {
             $t_rep = new ca_object_representations($vn_representation_id);
             if (isset($pa_options['transaction']) && $pa_options['transaction'] instanceof Transaction) {
                 $t_rep->setTransaction($pa_options['transaction']);
             }
             return $t_rep;
         }
     }
     return $vn_representation_id;
 }
 /**
  *
  */
 public function parseValue($ps_value, $pa_element_info, $pa_options = null)
 {
     $vb_require_value = is_null($pa_element_info['settings']['requireValue']) ? true : (bool) $pa_element_info['settings']['requireValue'];
     if (preg_match('![^\\d]+!', $ps_value)) {
         // try to convert idno to representation_id
         if ($vn_id = ca_object_representations::find(array('idno' => $ps_value), array('returnAs' => 'firstId'))) {
             $ps_value = $vn_id;
         }
     }
     if (!$vb_require_value && !(int) $ps_value) {
         return array('value_longtext1' => null, 'value_integer1' => null);
     }
     if (strlen($ps_value) && !is_numeric($ps_value)) {
         $this->postError(1970, _t('Item_id %2 is not valid for element %1', $pa_element_info["element_code"], $ps_value), 'ObjectRepresentationsAttributeValue->parseValue()');
         return false;
     }
     $t_item = new ca_object_representations((int) $ps_value);
     if (!$t_item->getPrimaryKey()) {
         if ($ps_value) {
             $this->postError(1970, _t('%1 is not a valid representation_id for %2 [%3]', $ps_value, $pa_element_info['displayLabel'], $pa_element_info['element_code']), 'ObjectRepresentationsAttributeValue->parseValue()');
         } else {
             return null;
         }
         return false;
     }
     return array('value_longtext1' => $ps_value, 'value_integer1' => (int) $ps_value);
 }
 /** 
  * Add media represention to currently loaded item
  *
  * @param $ps_media_path - the path to the media you want to add
  * @param $pn_type_id - the item_id of the representation type, in the ca_list with list_code 'object_represention_types'
  * @param $pn_locale_id - the locale_id of the locale of the representation
  * @param $pn_status - the status code for the representation (as defined in item_value fields of items in the 'workflow_statuses' ca_list)
  * @param $pn_access - the access code for the representation (as defined in item_value fields of items in the 'access_statuses' ca_list)
  * @param $pb_is_primary - if set to true, representation is designated "primary." Primary representation are used in cases where only one representation is required (such as search results). If a primary representation is already attached to this item, then it will be changed to non-primary as only one representation can be primary at any given time. If no primary representations exist, then the new representation will always be marked primary no matter what the setting of this parameter (there must always be a primary representation, if representations are defined).
  * @param $pa_values - array of attributes to attach to new representation
  * @param $pa_options - an array of options passed through to BaseModel::set() when creating the new representation. Currently supported options:
  *		original_filename - the name of the file being uploaded; will be recorded in the database and used as the filename when the file is subsequently downloaded
  *		rank - a numeric rank used to order the representations when listed
  *		returnRepresentation = if set the newly created ca_object_representations instance is returned rather than the link_id of the newly created relationship record
  *		matchOn = 
  *		centerX = Horizontal position of image center used when cropping as a percentage expressed as a decimal between 0 and 1. If omitted existing value is maintained. Note that both centerX and centerY must be specified for the center to be changed.
  *		centerY = Vertical position of image center used when cropping as a percentage expressed as a decimal between 0 and 1. If omitted existing value is maintained. Note that both centerX and centerY must be specified for the center to be changed.
  *
  * @return mixed Returns primary key (link_id) of the relatipnship row linking the newly created representation to the item; if the 'returnRepresentation' is set then an instance for the newly created ca_object_representations is returned instead; boolean false is returned on error
  */
 public function addRepresentation($ps_media_path, $pn_type_id, $pn_locale_id, $pn_status, $pn_access, $pb_is_primary, $pa_values = null, $pa_options = null)
 {
     if (!($vn_id = $this->getPrimaryKey())) {
         return null;
     }
     if (!$pn_locale_id) {
         $pn_locale_id = ca_locales::getDefaultCataloguingLocaleID();
     }
     $t_rep = new ca_object_representations();
     if ($this->inTransaction()) {
         $t_rep->setTransaction($this->getTransaction());
     }
     $vn_rep_id = null;
     if (is_array($va_match_on = caGetOption('matchOn', $pa_options, null))) {
         $va_ids = null;
         foreach ($va_match_on as $vs_match_on) {
             switch ($vs_match_on) {
                 case 'idno':
                     if (!trim($pa_values['idno'])) {
                         break;
                     }
                     $va_ids = ca_object_representations::find(array('idno' => trim($pa_values['idno'])), array('returnAs' => 'ids'));
                     break;
                 case 'label':
                     if (!trim($pa_values['preferred_labels']['name'])) {
                         break;
                     }
                     $va_ids = ca_object_representations::find(array('preferred_labels' => array('name' => trim($pa_values['preferred_labels']['name']))), array('returnAs' => 'ids'));
                     break;
             }
             if (is_array($va_ids) && sizeof($va_ids)) {
                 $vn_rep_id = array_shift($va_ids);
                 break;
             }
         }
     }
     if (!$vn_rep_id) {
         $t_rep->setMode(ACCESS_WRITE);
         $t_rep->set('type_id', $pn_type_id);
         $t_rep->set('locale_id', $pn_locale_id);
         $t_rep->set('status', $pn_status);
         $t_rep->set('access', $pn_access);
         $t_rep->set('media', $ps_media_path, $pa_options);
         $o_idno = $t_rep->getIDNoPlugInInstance();
         $t_rep->setIdnoWithTemplate($o_idno->makeTemplateFromValue(''));
         if (is_array($pa_values)) {
             if (isset($pa_values['idno'])) {
                 $t_rep->set('idno', $pa_values['idno']);
                 unset($pa_values['idno']);
             }
             foreach ($pa_values as $vs_element => $va_value) {
                 if (is_array($va_value)) {
                     // array of values (complex multi-valued attribute)
                     $t_rep->addAttribute(array_merge($va_value, array('locale_id' => $pn_locale_id)), $vs_element);
                 } else {
                     // scalar value (simple single value attribute)
                     if ($va_value) {
                         $t_rep->addAttribute(array('locale_id' => $pn_locale_id, $vs_element => $va_value), $vs_element);
                     }
                 }
             }
         }
         $t_rep->insert();
         if ($t_rep->numErrors()) {
             $this->errors = array_merge($this->errors, $t_rep->errors());
             return false;
         }
         if ($t_rep->getPreferredLabelCount() == 0) {
             $vs_label = isset($pa_values['name']) && $pa_values['name'] ? $pa_values['name'] : '[' . _t('BLANK') . ']';
             $t_rep->addLabel(array('name' => $vs_label), $pn_locale_id, null, true);
             if ($t_rep->numErrors()) {
                 $this->errors = array_merge($this->errors, $t_rep->errors());
                 return false;
             }
         }
     } else {
         $t_rep->load($vn_rep_id);
         $t_rep->setMode(ACCESS_WRITE);
         $t_rep->set('status', $pn_status);
         $t_rep->set('access', $pn_access);
         if ($ps_media_path) {
             $t_rep->set('media', $ps_media_path, $pa_options);
         }
         if (is_array($pa_values)) {
             if (isset($pa_values['idno'])) {
                 $t_rep->set('idno', $pa_values['idno']);
                 unset($pa_values['idno']);
             }
             foreach ($pa_values as $vs_element => $va_value) {
                 if (is_array($va_value)) {
                     // array of values (complex multi-valued attribute)
                     $t_rep->replaceAttribute(array_merge($va_value, array('locale_id' => $pn_locale_id)), $vs_element);
                 } else {
                     // scalar value (simple single value attribute)
                     if ($va_value) {
                         $t_rep->replaceAttribute(array('locale_id' => $pn_locale_id, $vs_element => $va_value), $vs_element);
                     }
                 }
             }
         }
         $t_rep->update();
         if ($t_rep->numErrors()) {
             $this->errors = array_merge($this->errors, $t_rep->errors());
             return false;
         }
     }
     // Set image center if specified
     $vn_center_x = caGetOption('centerX', $pa_options, null);
     $vn_center_y = caGetOption('centerY', $pa_options, null);
     if (strlen($vn_center_x) && strlen($vn_center_y) && $vn_center_x >= 0 && $vn_center_y >= 0 && $vn_center_x <= 1 && $vn_center_y <= 1) {
         $t_rep->setMediaCenter('media', (double) $vn_center_x, (double) $vn_center_y);
         $t_rep->update();
         if ($t_rep->numErrors()) {
             $this->errors = array_merge($this->errors, $t_rep->errors());
             return false;
         }
     }
     if (!($t_oxor = $this->_getRepresentationRelationshipTableInstance())) {
         return null;
     }
     $vs_pk = $this->primaryKey();
     if ($this->inTransaction()) {
         $t_oxor->setTransaction($this->getTransaction());
     }
     $t_oxor->setMode(ACCESS_WRITE);
     $t_oxor->set($vs_pk, $vn_id);
     $t_oxor->set('representation_id', $t_rep->getPrimaryKey());
     $t_oxor->set('is_primary', $pb_is_primary ? 1 : 0);
     $t_oxor->set('rank', isset($pa_options['rank']) ? (int) $pa_options['rank'] : $t_rep->getPrimaryKey());
     if ($t_oxor->hasField('type_id')) {
         $t_oxor->set('type_id', isset($pa_options['type_id']) ? (int) $pa_options['type_id'] : null);
     }
     $t_oxor->insert();
     if ($t_oxor->numErrors()) {
         $this->errors = array_merge($this->errors, $t_oxor->errors());
         //$t_rep->delete();
         //if ($t_rep->numErrors()) {
         //	$this->errors = array_merge($this->errors, $t_rep->errors());
         //}
         return false;
     }
     //
     // Perform mapping of embedded metadata for newly uploaded representation with respect
     // to ca_objects and ca_object_representation records
     //
     $va_metadata = $t_rep->get('media_metadata', array('binary' => true));
     if (caExtractEmbeddedMetadata($this, $va_metadata, $pn_locale_id)) {
         $this->update();
     }
     if (isset($pa_options['returnRepresentation']) && (bool) $pa_options['returnRepresentation']) {
         return $t_rep;
     }
     return $t_oxor->getPrimaryKey();
 }
 /**
  * Perform client services-related periodic tasks
  */
 public function hookPeriodicTask(&$pa_params)
 {
     $t_log = new Eventlog();
     $o_db = new Db();
     if (!(bool) $this->opo_config->get('enable_client_services')) {
         return true;
     }
     // Find any orders with status PROCESSED_AWAITING_MEDIA_ACCESS and fetch media
     $qr_orders = $o_db->query("\n\t\t\t\tSELECT order_id\n\t\t\t\tFROM ca_commerce_orders\n\t\t\t\tWHERE\n\t\t\t\t\torder_status = 'PROCESSED_AWAITING_MEDIA_ACCESS'\n\t\t\t");
     //
     // Set up HTTP client for REST calls
     //
     if ($this->opo_client_services_config->get('remote_media_base_url')) {
         $vs_base_url = $this->opo_client_services_config->get('remote_media_base_url');
         $o_client = new RestClient($vs_base_url . "/service.php/iteminfo/ItemInfo/rest");
         try {
             $o_res = $o_client->auth($this->opo_client_services_config->get('remote_media_username'), $this->opo_client_services_config->get('remote_media_password'))->get();
             if (!$o_res->isSuccess()) {
                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not authenticate to remote system %1', $vs_base_url), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
             }
             while ($qr_orders->nextRow()) {
                 $t_order = new ca_commerce_orders($qr_orders->get('order_id'));
                 $vb_download_errors = false;
                 if ($t_order->getPrimaryKey() && sizeof($va_missing_media = $t_order->itemsMissingDownloadableMedia())) {
                     $va_missing_media_representation_ids = $t_order->itemsMissingDownloadableMedia('original', array('returnRepresentationIDs' => true));
                     foreach ($va_missing_media as $vn_object_id => $va_representation_md5s) {
                         foreach ($va_representation_md5s as $vn_i => $vs_representation_md5) {
                             $o_xml = $o_client->getObjectRepresentationURLByMD5($vs_representation_md5, 'original')->get();
                             $vs_url = (string) $o_xml->getObjectRepresentationURLByMD5->original;
                             if (!$vs_url) {
                                 continue;
                             }
                             // media no longer exists
                             // fetch the file
                             $t_rep = new ca_object_representations($va_missing_media_representation_ids[$vn_object_id][$vn_i]);
                             if ($t_rep->getPrimaryKey() && ($vs_target_path = $t_rep->getMediaPath('media', 'original'))) {
                                 if ($r_source = fopen($vs_url, "rb")) {
                                     if ($r_target = fopen($vs_target_path, "wb")) {
                                         while (feof($r_source) === false) {
                                             fwrite($r_target, fread($r_source, 1024 * 8), 1024 * 8);
                                         }
                                         fclose($r_target);
                                     } else {
                                         $vb_download_errors = true;
                                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not open target path %1', $vs_target_path), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                                     }
                                     fclose($r_source);
                                 } else {
                                     $vb_download_errors = true;
                                     $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not open download URL "%1"', $vs_url), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                                 }
                                 // verify the file was downloaded correctly
                                 if (($vs_target_md5 = md5_file($vs_target_path)) !== $vs_representation_md5) {
                                     unlink($vs_target_path);
                                     $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Media file %1 failed to be downloaded from url "%2"; checksums differ: %3/%4', $vs_target_path, $vs_url, $vs_representation_md5, $vs_target_md5), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                                     $vb_download_errors = true;
                                 }
                             } else {
                                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Invalid representation_id "%1" or target path "%2"', $vn_representation_id, $vs_representation_md5, $vs_target_path), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                                 $vb_download_errors = true;
                             }
                         }
                     }
                 }
                 if (!$vb_download_errors) {
                     $t_order->setMode(ACCESS_WRITE);
                     $t_order->set('order_status', 'PROCESSED');
                     $t_order->update();
                     if ($t_order->numErrors()) {
                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Change of order status to PROCESSED from PROCESSED_AWAITING_MEDIA_ACCESS failed for order_id %1: %2', $t_order->getPrimaryKey(), join('; ', $t_order->getErrors())), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                     }
                 }
             }
         } catch (Exception $e) {
             // noop
         }
     }
     // Find any orders with status PROCESSED_AWAITING_DIGITIZATION where all media are now present
     $qr_orders = $o_db->query("\n\t\t\t\tSELECT order_id\n\t\t\t\tFROM ca_commerce_orders\n\t\t\t\tWHERE\n\t\t\t\t\torder_status = 'PROCESSED_AWAITING_DIGITIZATION'\n\t\t\t");
     while ($qr_orders->nextRow()) {
         $t_order = new ca_commerce_orders($qr_orders->get('order_id'));
         if ($t_order->getPrimaryKey() && !sizeof($t_order->itemsWithNoDownloadableMedia())) {
             $t_order->setMode(ACCESS_WRITE);
             $t_order->set('order_status', 'PROCESSED');
             $t_order->update();
             if ($t_order->numErrors()) {
                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Change of order status to PROCESSED from PROCESSED_AWAITING_DIGITIZATION failed for order_id %1: %2', $t_order->getPrimaryKey(), join('; ', $t_order->getErrors())), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
             }
         }
     }
     // Find orders paid/shipped more than X days ago and mark them as "COMPLETED"
     $vn_days = (int) $this->opo_client_services_config->get('completed_order_age_threshold');
     if ($vn_days > 1) {
         $vn_threshold = (int) (time() - $vn_days * 24 * 60 * 60);
         $qr_orders = $o_db->query("\n\t\t\t\t\tSELECT order_id\n\t\t\t\t\tFROM ca_commerce_orders\n\t\t\t\t\tWHERE\n\t\t\t\t\t\t(order_status = 'PROCESSED') \n\t\t\t\t\t\tAND \n\t\t\t\t\t\t((payment_received_on > 0) AND (payment_received_on < ?))\n\t\t\t\t\t\tAND \n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(shipping_date IS NULL AND shipped_on_date IS NULL)\n\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t(shipped_on_date > 0) AND (shipped_on_date < ?)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t", $vn_threshold, $vn_threshold);
         while ($qr_orders->nextRow()) {
             $t_order = new ca_commerce_orders($qr_orders->get('order_id'));
             if ($t_order->getPrimaryKey()) {
                 $t_order->setMode(ACCESS_WRITE);
                 $t_order->set('order_status', 'COMPLETED');
                 $t_order->update();
                 if ($t_order->numErrors()) {
                     $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Change of order status to COMPLETED from PROCESSED failed for order_id %1: %2', $t_order->getPrimaryKey(), join('; ', $t_order->getErrors())), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                 }
             }
         }
     }
     return true;
 }
 /**
  * Download all media attached to specified object (not necessarily open for editing)
  * Includes all representation media attached to the specified object + any media attached to other
  * objects in the same object hierarchy as the specified object. 
  */
 public function DownloadMedia($pa_options = null)
 {
     list($vn_subject_id, $t_subject) = $this->_initView();
     $pn_representation_id = $this->request->getParameter('representation_id', pInteger);
     $pn_value_id = $this->request->getParameter('value_id', pInteger);
     if ($pn_value_id) {
         return $this->DownloadAttributeFile();
     }
     $ps_version = $this->request->getParameter('version', pString);
     if (!$vn_subject_id) {
         return;
     }
     $o_view = new View($this->request, $this->request->getViewsDirectoryPath() . '/bundles/');
     if (!$ps_version) {
         $ps_version = 'original';
     }
     $o_view->setVar('version', $ps_version);
     $va_ancestor_ids = $t_subject->isHierarchical() ? $t_subject->getHierarchyAncestors(null, array('idsOnly' => true, 'includeSelf' => true)) : array($vn_subject_id);
     if ($vn_parent_id = array_pop($va_ancestor_ids)) {
         $t_subject->load($vn_parent_id);
         array_unshift($va_ancestor_ids, $vn_parent_id);
     }
     $va_child_ids = $t_subject->isHierarchical() ? $t_subject->getHierarchyChildren(null, array('idsOnly' => true)) : array($vn_subject_id);
     foreach ($va_ancestor_ids as $vn_id) {
         array_unshift($va_child_ids, $vn_id);
     }
     $vn_c = 1;
     $va_file_names = array();
     $va_file_paths = array();
     foreach ($va_child_ids as $vn_child_id) {
         if (!$t_subject->load($vn_child_id)) {
             continue;
         }
         if ($t_subject->tableName() == 'ca_object_representations') {
             $va_reps = array($vn_child_id => array('representation_id' => $vn_child_id, 'info' => array($ps_version => $t_subject->getMediaInfo('media', $ps_version))));
         } else {
             $va_reps = $t_subject->getRepresentations(array($ps_version));
         }
         $vs_idno = $t_subject->get('idno');
         foreach ($va_reps as $vn_representation_id => $va_rep) {
             if ($pn_representation_id && $pn_representation_id != $vn_representation_id) {
                 continue;
             }
             $va_rep_info = $va_rep['info'][$ps_version];
             $vs_idno_proc = preg_replace('![^A-Za-z0-9_\\-]+!', '_', $vs_idno);
             switch ($this->request->user->getPreference('downloaded_file_naming')) {
                 case 'idno':
                     $vs_file_name = $vs_idno_proc . '_' . $vn_c . '.' . $va_rep_info['EXTENSION'];
                     break;
                 case 'idno_and_version':
                     $vs_file_name = $vs_idno_proc . '_' . $ps_version . '_' . $vn_c . '.' . $va_rep_info['EXTENSION'];
                     break;
                 case 'idno_and_rep_id_and_version':
                     $vs_file_name = $vs_idno_proc . '_representation_' . $vn_representation_id . '_' . $ps_version . '.' . $va_rep_info['EXTENSION'];
                     break;
                 case 'original_name':
                 default:
                     if ($va_rep['info']['original_filename']) {
                         $va_tmp = explode('.', $va_rep['info']['original_filename']);
                         if (sizeof($va_tmp) > 1) {
                             if (strlen($vs_ext = array_pop($va_tmp)) < 3) {
                                 $va_tmp[] = $vs_ext;
                             }
                         }
                         $vs_file_name = join('_', $va_tmp);
                     } else {
                         $vs_file_name = $vs_idno_proc . '_representation_' . $vn_representation_id . '_' . $ps_version;
                     }
                     if (isset($va_file_names[$vs_file_name . '.' . $va_rep_info['EXTENSION']])) {
                         $vs_file_name .= "_{$vn_c}";
                     }
                     $vs_file_name .= '.' . $va_rep_info['EXTENSION'];
                     break;
             }
             $va_file_names[$vs_file_name] = true;
             $o_view->setVar('version_download_name', $vs_file_name);
             //
             // Perform metadata embedding
             $t_rep = new ca_object_representations($va_rep['representation_id']);
             if (!($vs_path = caEmbedMediaMetadataIntoFile($t_rep->getMediaPath('media', $ps_version), $t_subject->tableName(), $t_subject->getPrimaryKey(), $t_subject->getTypeCode(), $t_rep->getPrimaryKey(), $t_rep->getTypeCode()))) {
                 $vs_path = $t_rep->getMediaPath('media', $ps_version);
             }
             $va_file_paths[$vs_path] = $vs_file_name;
             $vn_c++;
         }
     }
     if (!($vn_limit = ini_get('max_execution_time'))) {
         $vn_limit = 30;
     }
     set_time_limit($vn_limit * 2);
     $o_zip = new ZipStream();
     foreach ($va_file_paths as $vs_path => $vs_name) {
         $o_zip->addFile($vs_path, $vs_name);
     }
     $o_view->setVar('zip_stream', $o_zip);
     $o_view->setVar('archive_name', preg_replace('![^A-Za-z0-9\\.\\-]+!', '_', $t_subject->get('idno')) . '.zip');
     $this->response->addContent($o_view->render('download_file_binary.php'));
     set_time_limit($vn_limit);
 }