public function performPreInstallTasks() { $o_config = Configuration::load(); CompositeCache::flush(); // avoid stale cache // create tmp dir if (!file_exists($o_config->get('taskqueue_tmp_directory'))) { if (!self::createDirectoryPath($o_config->get('taskqueue_tmp_directory'))) { $this->addError("Couldn't create tmp directory at " . $o_config->get('taskqueue_tmp_directory')); return false; } } else { // if already exists then remove all contents to avoid stale cache caRemoveDirectory($o_config->get('taskqueue_tmp_directory'), false); } // Create media directories $o_media_volumes = new MediaVolumes(); $va_media_volumes = $o_media_volumes->getAllVolumeInformation(); $vs_base_dir = $o_config->get('ca_base_dir'); $va_dir_creation_errors = array(); foreach ($va_media_volumes as $vs_label => $va_volume_info) { if (preg_match('!^' . $vs_base_dir . '!', $va_volume_info['absolutePath'])) { if (!self::createDirectoryPath($va_volume_info['absolutePath'])) { $this->addError("Couldn't create directory for media volume {$vs_label}"); return false; } } } return true; }
/** * Returns appropriate representation of that media version in an html tag, including attributes for display * * @param string $field field name * @param string $version version of the media file, as defined in media_processing.conf * @param string $name name attribute of the img tag * @param string $vspace vspace attribute of the img tag - note: deprecated in HTML 4.01, not supported in XHTML 1.0 Strict * @param string $hspace hspace attribute of the img tag - note: deprecated in HTML 4.01, not supported in XHTML 1.0 Strict * @param string $alt alt attribute of the img tag * @param int $border border attribute of the img tag - note: deprecated in HTML 4.01, not supported in XHTML 1.0 Strict * @param string $usemap usemap attribute of the img tag * @param int $align align attribute of the img tag - note: deprecated in HTML 4.01, not supported in XHTML 1.0 Strict * @return string html tag */ public function getMediaTag($ps_field, $ps_version, $pa_options = null) { if (!is_array($va_media_info = $this->getMediaInfo($ps_field))) { return null; } if (!is_array($va_media_info[$ps_version])) { return null; } # # Use icon # if (isset($va_media_info[$ps_version]['USE_ICON']) && ($vs_icon_code = $va_media_info[$ps_version]['USE_ICON'])) { return caGetDefaultMediaIconTag($vs_icon_code, $va_media_info[$ps_version]['WIDTH'], $va_media_info[$ps_version]['HEIGHT']); } # # Is this version queued for processing? # if (isset($va_media_info[$ps_version]["QUEUED"]) && $va_media_info[$ps_version]["QUEUED"]) { return $va_media_info[$ps_version]["QUEUED_MESSAGE"]; } $url = $this->getMediaUrl($ps_field, $ps_version, isset($pa_options["page"]) ? $pa_options["page"] : null); $m = new Media(); $o_vol = new MediaVolumes(); $va_volume = $o_vol->getVolumeInformation($va_media_info[$ps_version]['VOLUME']); return $m->htmlTag($va_media_info[$ps_version]["MIMETYPE"], $url, $va_media_info[$ps_version]["PROPERTIES"], $pa_options, $va_volume); }
public function getMediaTag($ps_data, $ps_version, $pa_options = null) { if (!($va_media_info = $this->getMediaArray($ps_data))) { return false; } if (!is_array($pa_options)) { $pa_options = array(); } if (!isset($pa_options["page"]) || $pa_options["page"] < 1) { $pa_options["page"] = 1; } # # Use icon # if (isset($va_media_info[$ps_version]['USE_ICON']) && ($vs_icon_code = $va_media_info[$ps_version]['USE_ICON'])) { return caGetDefaultMediaIconTag($vs_icon_code, $va_media_info[$ps_version]['WIDTH'], $va_media_info[$ps_version]['HEIGHT']); } # # Is this version queued for processing? # if (isset($va_media_info[$ps_version]["QUEUED"]) && $va_media_info[$ps_version]["QUEUED"]) { return $va_media_info[$ps_version]["QUEUED_MESSAGE"]; } $vs_url = $this->getMediaUrl($va_media_info, $ps_version, $pa_options["page"], $pa_options); $o_media = new Media(); $o_vol = new MediaVolumes(); $va_volume = $o_vol->getVolumeInformation($va_media_info[$ps_version]['VOLUME']); $va_properties = $va_media_info[$ps_version]["PROPERTIES"]; if (isset($pa_options['width'])) { $va_properties['width'] = $pa_options['width']; } if (isset($pa_options['height'])) { $va_properties['height'] = $pa_options['height']; } $o_config = Configuration::load(); if ($o_config->get('use_pdfjs_viewer')) { foreach ($va_media_info as $vs_version => $va_info) { if (isset($va_info['MIMETYPE']) && $va_info['MIMETYPE'] == 'application/pdf') { JavascriptLoadManager::register("pdfjs"); } } } return $o_media->htmlTag($va_media_info[$ps_version]["MIMETYPE"], $vs_url, $va_properties, $pa_options, $va_volume); }
/** * Method invoked when the task queue needs to actually execute the task. For mediaproc this means * actually doing the processing of media! * * Return false on failure/error and sets the error property with an error description. Returns an array * with processing details on success. * * @param array $pa_parameters An unserialized parameters array for the current task (eg. unserialized data from ca_task_queue.parameters) * @return array Returns false on error, or an array with processing details on success */ public function process($pa_parameters) { $vs_table = $pa_parameters["TABLE"]; // name of table of record we're processing $vs_field = $pa_parameters["FIELD"]; // name of field in record we're processing $vs_pk = $pa_parameters["PK"]; // Field name of primary key of record we're processing $vn_id = $pa_parameters["PK_VAL"]; // Value of primary key $vs_input_mimetype = $pa_parameters["INPUT_MIMETYPE"]; // Mimetype of input file $vs_input_file = $pa_parameters["FILENAME"]; // Full path to input file // Array of media versions to process; keys are version names, // values are arrays with info about processing for that version // Currently the info array contains a single key, 'VOLUME', which indicates // the volume the version should be written to $va_versions = $pa_parameters["VERSIONS"]; $va_options = $pa_parameters["OPTIONS"]; // Array of processing options; names of options to employ are keys, settings are values // If true, then input media is *not* deleted $vb_dont_delete_original_media = (bool) $pa_parameters["DONT_DELETE_OLD_MEDIA"]; $va_report = array('errors' => array(), 'notes' => array()); $o_dm = Datamodel::load(); $o_media_volumes = new MediaVolumes(); $o_media = new Media(); $o_media_proc_settings = new MediaProcessingSettings($vs_table, $vs_field); $vs_media_type = $o_media_proc_settings->canAccept($vs_input_mimetype); $va_version_info = $o_media_proc_settings->getMediaTypeVersions($vs_media_type); if (!file_exists($vs_input_file)) { $o_eventlog = new EventLog(); $o_eventlog->log(array("CODE" => "DEBG", "SOURCE" => "TaskQueue->mediaproc->process()", "MESSAGE" => "Record {$vs_table}.field = file '{$vs_input_file}' did not exist; queued file was discarded")); $va_report['errors'][] = _t("Record %1.field = file '%2' did not exist; queued file was discarded", $vs_table, $vs_input_file); return $va_report; } if ($t_instance = $o_dm->getInstanceByTableName($vs_table, true)) { if ($t_instance->hasField($vs_field)) { if (!$t_instance->load($vn_id)) { # record no longer exists if (!$vb_dont_delete_original_media) { @unlink($vs_input_file); } $o_eventlog = new EventLog(); $o_eventlog->log(array("CODE" => "DEBG", "SOURCE" => "TaskQueue->mediaproc->process()", "MESSAGE" => "Record {$vs_table}.field = {$vn_id} did not exist; queued file was discarded")); $o_media->cleanup(); $va_report['errors'][] = _t("Record %1.field = %2 did not exist; queued file was discarded", $vs_table, $vn_id); return $va_report; } } else { # bad field name $this->error->setError(551, _t("Invalid media field '%1' in table '%2'", $vs_field, $vs_table), "mediaproc->process()"); return false; } } else { # bad table name $this->error->setError(550, _t("Invalid media field table '%1'", $vs_table), "mediaproc->process()"); return false; } $va_old_media_to_delete = array(); foreach ($va_versions as $v => $va_version_settings) { $vs_use_icon = null; if (!file_exists($vs_input_file)) { $this->error->setError(505, _t("Input media file '%1' does not exist", $vs_input_file), "mediaproc->process()"); $o_media->cleanup(); return false; } if (!is_readable($vs_input_file)) { $this->error->setError(506, _t("Denied permission to read input media file '%1'", $vs_input_file), "mediaproc->process()"); $o_media->cleanup(); return false; } if (!$o_media->read($vs_input_file)) { $this->error->setError(1600, _t("Could not process input media file '%1': %2", $vs_input_file, join('; ', $o_media->getErrors())), "mediaproc->process()"); $o_media->cleanup(); return false; } $vs_rule = isset($va_version_info[$v]['RULE']) ? $va_version_info[$v]['RULE'] : ''; $va_rules = $o_media_proc_settings->getMediaTransformationRule($vs_rule); $va_volume_info = $o_media_volumes->getVolumeInformation($va_version_settings['VOLUME']); if (sizeof($va_rules) == 0) { $vs_output_mimetype = $vs_input_mimetype; # # don't process this media, just copy the file # $vs_ext = $o_media->mimetype2extension($vs_output_mimetype); if (!$vs_ext) { $this->error->setError(1600, _t("File could not be copied for %1; can't convert mimetype %2 to extension", $vs_field, $vs_output_mimetype), "mediaproc->process()"); $o_media->cleanup(); return false; } if (($vs_dirhash = $this->_getDirectoryHash($va_volume_info["absolutePath"], $vn_id)) === false) { $this->error->setError(1600, _t("Couldn't create subdirectory for file for %1", $vs_field), "mediaproc->process()"); $o_media->cleanup(); return false; } $vs_magic = rand(0, 99999); $vs_filepath = $va_volume_info["absolutePath"] . "/" . $vs_dirhash . "/" . $vs_magic . "_" . $vs_table . "_" . $vs_field . "_" . $vn_id . "_" . $v . "." . $vs_ext; if (!copy($vs_input_file, $vs_filepath)) { $this->error->setError(504, _t("File could not be copied for %1", $vs_field), "mediaproc->process()"); $o_media->cleanup(); return false; } if (is_array($va_volume_info["mirrors"]) && sizeof($va_volume_info["mirrors"]) > 0) { $entity_key = join("/", array($vs_table, $vs_field, $vn_id, $v)); $row_key = join("/", array($vs_table, $vn_id)); foreach ($va_volume_info["mirrors"] as $vs_mirror_code => $va_mirror_info) { $vs_mirror_method = $va_mirror_info["method"]; $vs_queue = $vs_mirror_method . "mirror"; $tq = new TaskQueue(); if (!$tq->cancelPendingTasksForEntity($entity_key)) { $this->error->setError(560, _t("Could not cancel pending tasks"), "mediaproc->process()"); $o_media->cleanup(); return false; } if ($tq->addTask($vs_queue, array("MIRROR" => $vs_mirror_code, "VOLUME" => $va_version_settings['VOLUME'], "FIELD" => $vs_field, "TABLE" => $vs_table, "VERSION" => $v, "FILES" => array(array("FILE_PATH" => $vs_filepath, "ABS_PATH" => $va_volume_info["absolutePath"], "HASH" => $vs_dirhash, "FILENAME" => $vs_magic . "_" . $vs_table . "_" . $vs_field . "_" . $vn_id . "_" . $v . "." . $vs_ext)), "MIRROR_INFO" => $va_mirror_info, "PK" => $vs_pk, "PK_VAL" => $vn_id), array("priority" => 100, "entity_key" => $entity_key, "row_key" => $row_key))) { continue; } else { $this->error->setError(100, _t("Couldn't queue mirror using '%1' for version '%2' (handler '%3')", $vs_mirror_method, $v, $vs_queue), "mediaproc->process()"); } } } $media_desc[$v] = array("VOLUME" => $va_version_settings['VOLUME'], "MIMETYPE" => $vs_output_mimetype, "WIDTH" => $o_media->get("width"), "HEIGHT" => $o_media->get("height"), "PROPERTIES" => $o_media->getProperties(), "FILENAME" => $vs_table . "_" . $vs_field . "_" . $vn_id . "_" . $v . "." . $vs_ext, "HASH" => $vs_dirhash, "MAGIC" => $vs_magic, "EXTENSION" => $vs_ext, "MD5" => md5_file($vs_filepath)); } else { $o_media->set('version', $v); while (list($operation, $pa_parameters) = each($va_rules)) { if ($operation === 'SET') { foreach ($pa_parameters as $pp => $pv) { if ($pp == 'format') { $vs_output_mimetype = $pv; } else { $o_media->set($pp, $pv); } } } else { if (!$o_media->transform($operation, $pa_parameters)) { $this->error = $o_media->errors[0]; $o_media->cleanup(); return false; } } } if (!$vs_output_mimetype) { $vs_output_mimetype = $vs_input_mimetype; } if (!($vs_ext = $o_media->mimetype2extension($vs_output_mimetype))) { $this->error->setError(1600, _t("File could not be processed for %1; can't convert mimetype %2 to extension", $vs_field, $vs_output_mimetype), "mediaproc->process()"); $o_media->cleanup(); return false; } if (($vs_dirhash = $this->_getDirectoryHash($va_volume_info["absolutePath"], $vn_id)) === false) { $this->error->setError(1600, _t("Couldn't create subdirectory for file for %1", $vs_field), "mediaproc->process()"); $o_media->cleanup(); return false; } $vs_magic = rand(0, 99999); $vs_filepath = $va_volume_info["absolutePath"] . "/" . $vs_dirhash . "/" . $vs_magic . "_" . $vs_table . "_" . $vs_field . "_" . $vn_id . "_" . $v; if (!($vs_output_file = $o_media->write($vs_filepath, $vs_output_mimetype, $va_options))) { $this->error = $o_media->errors[0]; $o_media->cleanup(); return false; } else { if ($vs_output_file === __CA_MEDIA_VIDEO_DEFAULT_ICON__ || $vs_output_file === __CA_MEDIA_AUDIO_DEFAULT_ICON__ || $vs_output_file === __CA_MEDIA_DOCUMENT_DEFAULT_ICON__) { $vs_use_icon = $vs_output_file; } else { $va_output_files[] = $vs_output_file; } } if (is_array($va_volume_info["mirrors"]) && sizeof($va_volume_info["mirrors"]) > 0) { $entity_key = join("/", array($vs_table, $vs_field, $vn_id, $v)); $row_key = join("/", array($vs_table, $vn_id)); foreach ($va_volume_info["mirrors"] as $vs_mirror_code => $va_mirror_info) { $vs_mirror_method = $va_mirror_info["method"]; $vs_queue = $vs_mirror_method . "mirror"; $tq = new TaskQueue(); if (!$tq->cancelPendingTasksForEntity($entity_key)) { $this->error->setError(560, _t("Could not cancel pending tasks"), "mediaproc->process()"); $o_media->cleanup(); return false; } if ($tq->addTask($vs_queue, array("MIRROR" => $vs_mirror_code, "VOLUME" => $va_version_settings['VOLUME'], "FIELD" => $vs_field, "TABLE" => $vs_table, "VERSION" => $v, "FILES" => array(array("FILE_PATH" => $vs_filepath, "ABS_PATH" => $va_volume_info["absolutePath"], "HASH" => $vs_dirhash, "FILENAME" => $vs_magic . "_" . $vs_table . "_" . $vs_field . "_" . $vn_id . "_" . $v . "." . $vs_ext)), "MIRROR_INFO" => $va_mirror_info, "PK" => $vs_pk, "PK_VAL" => $vn_id), array("priority" => 100, "entity_key" => $entity_key, "row_key" => $row_key))) { continue; } else { $this->error->setError(100, _t("Couldn't queue mirror using '%1' for version '%2' (handler '%3')", $vs_mirror_method, $v, $vs_queue), "mediaproc->process()"); } } } if ($vs_use_icon) { $media_desc[$v] = array("MIMETYPE" => $vs_output_mimetype, "USE_ICON" => $vs_use_icon, "WIDTH" => $o_media->get("width"), "HEIGHT" => $o_media->get("height")); } else { $media_desc[$v] = array("VOLUME" => $va_version_settings['VOLUME'], "MIMETYPE" => $vs_output_mimetype, "WIDTH" => $o_media->get("width"), "HEIGHT" => $o_media->get("height"), "PROPERTIES" => $o_media->getProperties(), "FILENAME" => $vs_table . "_" . $vs_field . "_" . $vn_id . "_" . $v . "." . $vs_ext, "HASH" => $vs_dirhash, "MAGIC" => $vs_magic, "EXTENSION" => $vs_ext, "MD5" => md5_file($vs_filepath . "." . $vs_ext)); } } if (!$vb_dont_delete_original_media) { $vs_old_media_path = $t_instance->getMediaPath($vs_field, $v); if ($vs_old_media_path && $vs_filepath . "." . $vs_ext != $vs_old_media_path && $vs_input_file != vs_old_media_path) { //@unlink($t_instance->getMediaPath($vs_field, $v)); $va_old_media_to_delete[] = $vs_old_media_path; } } } # # Update record # if ($t_instance->load($vn_id)) { if (method_exists($t_instance, "useBlobAsMediaField")) { // support for attributes - force field to be FT_MEDIA $t_instance->useBlobAsMediaField(true); } $md = $t_instance->get($vs_field); $va_merged_media_desc = is_array($md) ? $md : array(); foreach ($media_desc as $vs_k => $va_v) { $va_merged_media_desc[$vs_k] = $va_v; } $t_instance->setMode(ACCESS_WRITE); $t_instance->setMediaInfo($vs_field, $va_merged_media_desc); $t_instance->update(); if ($t_instance->numErrors()) { # get rid of files we just created foreach ($va_output_files as $vs_to_delete) { @unlink($vs_to_delete); } $this->error->setError(560, _t("Could not update %1.%2: %3", $vs_table, $vs_field, join(", ", $t_instance->getErrors())), "mediaproc->process()"); $o_media->cleanup(); return false; } $va_report['notes'][] = _t("Processed file %1", $vs_input_file); // Generate preview frames for media that support that (Eg. video) // and add them as "multifiles" assuming the current model supports that (ca_object_representations does) $o_config = Configuration::load(); if (((bool) $o_config->get('video_preview_generate_frames') || (bool) $o_config->get('document_preview_generate_pages')) && method_exists($t_instance, 'addFile')) { $o_media->read($vs_input_file); $va_preview_frame_list = $o_media->writePreviews(array('width' => $o_media->get("width"), 'height' => $o_media->get("height"), 'numberOfFrames' => $o_config->get('video_preview_max_number_of_frames'), 'numberOfPages' => $o_config->get('document_preview_max_number_of_pages'), 'frameInterval' => $o_config->get('video_preview_interval_between_frames'), 'pageInterval' => $o_config->get('document_preview_interval_between_pages'), 'startAtTime' => $o_config->get('video_preview_start_at'), 'endAtTime' => $o_config->get('video_preview_end_at'), 'startAtPage' => $o_config->get('document_preview_start_page'), 'outputDirectory' => __CA_APP_DIR__ . '/tmp')); $t_instance->removeAllFiles(); // get rid of any previously existing frames (they might be hanging around if we're editing an existing record) if (is_array($va_preview_frame_list)) { foreach ($va_preview_frame_list as $vn_time => $vs_frame) { $t_instance->addFile($vs_frame, $vn_time, true); // the resource path for each frame is it's time, in seconds (may be fractional) for video, or page number for documents @unlink($vs_frame); // clean up tmp preview frame file } } } if (!$vb_dont_delete_original_media) { @unlink($vs_input_file); } foreach ($va_old_media_to_delete as $vs_to_delete) { @unlink($vs_to_delete); } $o_media->cleanup(); return $va_report; } else { # record no longer exists if (!$vb_dont_delete_original_media) { @unlink($vs_input_file); } $o_eventlog = new EventLog(); $o_eventlog->log(array("CODE" => "DEBG", "SOURCE" => "TaskQueue->mediaproc->process()", "MESSAGE" => "Record {$vs_table}.field = {$vn_id} did not exist; queued file was discarded")); $o_media->cleanup(); $va_report['errors'][] = _t("Record {$vs_table}.field = {$vn_id} did not exist; queued file was discarded"); return $va_report; } }
public function performPreInstallTasks() { $o_config = Configuration::load(); CompositeCache::flush(); // avoid stale cache // create tmp dir if (!file_exists($o_config->get('taskqueue_tmp_directory'))) { if (!self::createDirectoryPath($o_config->get('taskqueue_tmp_directory'))) { $this->addError("Couldn't create tmp directory at " . $o_config->get('taskqueue_tmp_directory')); return false; } } else { // if already exists then remove all contents to avoid stale cache caRemoveDirectory($o_config->get('taskqueue_tmp_directory'), false); } // Create media directories $o_media_volumes = new MediaVolumes(); $va_media_volumes = $o_media_volumes->getAllVolumeInformation(); $vs_base_dir = $o_config->get('ca_base_dir'); $va_dir_creation_errors = array(); foreach ($va_media_volumes as $vs_label => $va_volume_info) { if (preg_match('!^' . $vs_base_dir . '!', $va_volume_info['absolutePath'])) { if (!self::createDirectoryPath($va_volume_info['absolutePath'])) { $this->addError("Couldn't create directory for media volume {$vs_label}"); return false; } } } // nuke search index if we using ElasticSearch (the SqlSearch index is nuked when we drop the database) if ($o_config->get('search_engine_plugin') == 'ElasticSearch') { require_once __CA_LIB_DIR__ . '/core/Plugins/SearchEngine/ElasticSearch.php'; $o_es = new WLPlugSearchEngineElasticSearch(); $o_es->truncateIndex(null, true); } return true; }
/** * Get list of mimetypes for which replication options are configured * * @return array */ public static function getMediaReplicationMimeTypes() { $o_media_volumes = new MediaVolumes(); $o_media_processing = new MediaProcessingSettings('ca_object_representations', 'media'); $va_volumes = $o_media_volumes->getAllVolumeInformation(); $va_mimetypes = array(); foreach ($va_volumes as $vs_volume => $va_volume_info) { if (isset($va_volume_info['replication']) && is_array($va_volume_info['replication'])) { foreach ($va_volume_info['replication'] as $vs_target => $va_target_info) { if (isset($va_target_info['mimetypes']) && is_array($va_target_info['mimetypes'])) { $va_mimetype_list = $va_target_info['mimetypes']; } else { // get mimetypes for volume from media_processing $va_mimetype_list = $o_media_processing->getMimetypesForVolume($vs_volume); } foreach ($va_mimetype_list as $vs_mimetype) { $va_mimetypes[$vs_mimetype] = true; } } } } return array_keys($va_mimetypes); }
public function getMediaTag($ps_data, $ps_version, $pa_options = null) { if (!($va_media_info = $this->getMediaArray($ps_data))) { return false; } if (!is_array($pa_options)) { $pa_options = array(); } if (!isset($pa_options["page"]) || $pa_options["page"] < 1) { $pa_options["page"] = 1; } # # Use icon # if (isset($va_media_info[$ps_version]['USE_ICON']) && ($vs_icon_code = $va_media_info[$ps_version]['USE_ICON'])) { return caGetDefaultMediaIconTag($vs_icon_code, $va_media_info[$ps_version]['WIDTH'], $va_media_info[$ps_version]['HEIGHT']); } # # Is this version queued for processing? # if (isset($va_media_info[$ps_version]["QUEUED"]) && $va_media_info[$ps_version]["QUEUED"]) { return $va_media_info[$ps_version]["QUEUED_MESSAGE"]; } $vs_url = $this->getMediaUrl($va_media_info, $ps_version, $pa_options["page"], $pa_options); $o_media = new Media(); $o_vol = new MediaVolumes(); $va_volume = $o_vol->getVolumeInformation($va_media_info[$ps_version]['VOLUME']); $va_properties = $va_media_info[$ps_version]["PROPERTIES"]; if (isset($pa_options['width'])) { $va_properties['width'] = $pa_options['width']; } if (isset($pa_options['height'])) { $va_properties['height'] = $pa_options['height']; } return $o_media->htmlTag($va_media_info[$ps_version]["MIMETYPE"], $vs_url, $va_properties, $pa_options, $va_volume); }