1183 lines
63 KiB
PHP
Executable File
1183 lines
63 KiB
PHP
Executable File
<?php
|
|
|
|
include_once __DIR__ . "/../../include/boot.php";
|
|
include_once __DIR__ . "/../../include/image_processing.php";
|
|
command_line_only();
|
|
|
|
$send_notification = false;
|
|
$suppress_output = (isset($staticsync_suppress_output) && $staticsync_suppress_output) ? true : false;
|
|
|
|
// CLI options check
|
|
$cli_short_options = 'hc';
|
|
$cli_long_options = array(
|
|
'help',
|
|
'send-notifications',
|
|
'suppress-output',
|
|
'clearlock'
|
|
);
|
|
|
|
foreach (getopt($cli_short_options, $cli_long_options) as $option_name => $option_value) {
|
|
if (in_array($option_name, array('h', 'help'))) {
|
|
echo "To clear the lock after a failed run, ";
|
|
echo "pass in '--clearlock'" . PHP_EOL;
|
|
echo 'If you have the configs [$file_checksums=true; $file_upload_block_duplicates=true;] set and would like to have duplicate resource information sent as a notification please run php staticsync.php --send-notifications' . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
if (
|
|
in_array($option_name, array('clearlock', 'c'))
|
|
&& is_process_lock("staticsync")
|
|
) {
|
|
clear_process_lock("staticsync");
|
|
}
|
|
|
|
if ('send-notifications' == $option_name) {
|
|
$send_notification = true;
|
|
}
|
|
if ('suppress-output' == $option_name) {
|
|
$suppress_output = true;
|
|
}
|
|
}
|
|
|
|
if (isset($staticsync_userref)) {
|
|
# If a user is specified, log them in.
|
|
$userref = $staticsync_userref;
|
|
$userdata = get_user($userref);
|
|
if ($userdata === false) {
|
|
echo 'Unable to get user.' . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
$userdata = array($userdata);
|
|
setup_user($userdata[0]);
|
|
}
|
|
|
|
ob_end_clean();
|
|
if ($suppress_output) {
|
|
ob_start();
|
|
}
|
|
|
|
set_time_limit(60 * 60 * 40);
|
|
echo "StaticSync started at " . date('Y-m-d H:i:s', time()) . PHP_EOL;
|
|
|
|
# Check for a process lock
|
|
if (is_process_lock("staticsync")) {
|
|
echo 'Process lock is in place. Deferring.' . PHP_EOL;
|
|
echo 'To clear the lock after a failed run use --clearlock flag.' . PHP_EOL;
|
|
exit();
|
|
}
|
|
set_process_lock("staticsync");
|
|
|
|
// Strip trailing slash if it has been left in
|
|
$syncdir = rtrim($syncdir, "/");
|
|
|
|
echo "Preloading data... ";
|
|
|
|
// Set options that don't make sense here
|
|
$merge_filename_with_title = false;
|
|
|
|
$count = 0;
|
|
$done = $fcs_to_reorder = [];
|
|
$errors = array();
|
|
$syncedresources = ps_query("SELECT ref, file_path, file_modified, archive FROM resource WHERE LENGTH(file_path)>0");
|
|
foreach ($syncedresources as $syncedresource) {
|
|
$done[$syncedresource["file_path"]]["ref"] = $syncedresource["ref"];
|
|
$done[$syncedresource["file_path"]]["modified"] = $syncedresource["file_modified"];
|
|
$done[$syncedresource["file_path"]]["archive"] = $syncedresource["archive"];
|
|
}
|
|
|
|
// Set up an array to monitor processing of new alternative files
|
|
$alternativefiles = array();
|
|
$restypes = get_resource_types();
|
|
|
|
if (isset($numeric_alt_suffixes) && $numeric_alt_suffixes > 0) {
|
|
// Add numeric suffixes to $staticsync_alt_suffix_array to support additional suffixes
|
|
$newsuffixarray = array();
|
|
foreach ($staticsync_alt_suffix_array as $suffix => $description) {
|
|
$newsuffixarray[$suffix] = $description;
|
|
for ($i = 1; $i < $numeric_alt_suffixes; $i++) {
|
|
$newsuffixarray[$suffix . $i] = $description . " (" . $i . ")";
|
|
}
|
|
}
|
|
$staticsync_alt_suffix_array = $newsuffixarray;
|
|
}
|
|
|
|
// Add all the synced alternative files to the list of completed
|
|
if (isset($staticsync_alternative_file_text) && (!$staticsync_ingest || $staticsync_ingest_force)) {
|
|
// Add any staticsynced alternative files to the array so we don't process them unnecessarily
|
|
$syncedalternatives = ps_query("SELECT ref, file_name, resource, creation_date FROM resource_alt_files WHERE file_name like concat('%',?,'%')", ['s', $syncdir]);
|
|
foreach ($syncedalternatives as $syncedalternative) {
|
|
$shortpath = str_replace($syncdir . '/', '', $syncedalternative["file_name"]);
|
|
$done[$shortpath]["ref"] = $syncedalternative["resource"];
|
|
$done[$shortpath]["modified"] = $syncedalternative["creation_date"];
|
|
$done[$shortpath]["alternative"] = $syncedalternative["ref"];
|
|
}
|
|
}
|
|
|
|
$lastsync = ps_value("SELECT value FROM sysvars WHERE name='lastsync'", array(), "");
|
|
$lastsync = (strlen($lastsync) > 0) ? strtotime($lastsync) : '';
|
|
|
|
echo "done." . PHP_EOL;
|
|
echo "Looking for changes..." . PHP_EOL;
|
|
|
|
# Pre-load the category tree, if configured.
|
|
if (isset($staticsync_mapped_category_tree)) {
|
|
$treefield = get_resource_type_field($staticsync_mapped_category_tree);
|
|
migrate_resource_type_field_check($treefield);
|
|
$tree = get_nodes($staticsync_mapped_category_tree, '', true);
|
|
}
|
|
|
|
function touch_category_tree_level($path_parts)
|
|
{
|
|
# For each level of the mapped category tree field, ensure that the matching path_parts path exists
|
|
global $staticsync_mapped_category_tree, $tree;
|
|
|
|
$parent_search = '';
|
|
$nodename = '';
|
|
$order_by = 10;
|
|
$treenodes = array();
|
|
for ($n = 0; $n < count($path_parts); $n++) {
|
|
$nodename = $path_parts[$n];
|
|
|
|
echo " - Looking for folder '" . $nodename . "' @ level " . $n . " in linked metadata field... ";
|
|
# Look for this node in the tree.
|
|
$found = false;
|
|
foreach ($tree as $treenode) {
|
|
if ($treenode["parent"] == $parent_search) {
|
|
if ($treenode["name"] == $nodename) {
|
|
# A match!
|
|
echo " - FOUND" . PHP_EOL;
|
|
$found = true;
|
|
$treenodes[] = $treenode["ref"];
|
|
$parent_search = $treenode["ref"]; # Search for this as the parent node on the pass for the next level.
|
|
} else {
|
|
if ($order_by <= $treenode["order_by"]) {
|
|
$order_by = $order_by + 10;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!$found) {
|
|
echo " - NOT FOUND. Updating tree field" . PHP_EOL;
|
|
# Add this node
|
|
$newnode = set_node(null, $staticsync_mapped_category_tree, $nodename, $parent_search, $order_by);
|
|
$tree[] = array("ref" => $newnode,"parent" => $parent_search,"name" => $nodename,"order_by" => $order_by);
|
|
$parent_search = $newnode; # Search for this as the parent node on the pass for the next level.
|
|
$treenodes[] = $newnode;
|
|
clear_query_cache("schema");
|
|
}
|
|
}
|
|
// Return the matching path nodes
|
|
return $treenodes;
|
|
}
|
|
|
|
function ProcessFolder($folder)
|
|
{
|
|
global $lang, $syncdir, $nogo, $staticsync_max_files, $count, $done, $lastsync, $unoconv_extensions,
|
|
$staticsync_autotheme, $FEATURED_COLLECTION_BG_IMG_SELECTION_OPTIONS, $staticsync_mapped_category_tree,
|
|
$staticsync_title_includes_path, $staticsync_ingest, $staticsync_mapfolders, $staticsync_alternatives_suffix,
|
|
$staticsync_defaultstate, $additional_archive_states, $staticsync_extension_mapping_append_values,
|
|
$staticsync_deleted_state, $staticsync_alternative_file_text, $staticsync_filepath_to_field,
|
|
$resource_deletion_state, $alternativefiles, $staticsync_revive_state, $enable_thumbnail_creation_on_upload,
|
|
$staticsync_extension_mapping_append_values_fields, $staticsync_extension_mapping_append_separator,
|
|
$view_title_field, $filename_field, $FIXED_LIST_FIELD_TYPES,
|
|
$staticsync_whitelist_folders,$staticsync_ingest_force,$errors, $category_tree_add_parents,
|
|
$staticsync_alt_suffixes, $staticsync_alt_suffix_array, $staticsync_file_minimum_age, $userref,
|
|
$resource_type_extension_mapping_default, $resource_type_extension_mapping, $restypes;
|
|
|
|
$collection = 0;
|
|
$treeprocessed = false;
|
|
|
|
if (!file_exists($folder)) {
|
|
echo "Sync folder does not exist: " . $folder . PHP_EOL;
|
|
return false;
|
|
}
|
|
echo "Processing Folder: " . $folder . PHP_EOL;
|
|
|
|
# List all files in this folder.
|
|
|
|
$directories_arr = array();
|
|
$files_arr = array();
|
|
$import_paths = array();
|
|
|
|
$dh = opendir($folder);
|
|
while (($file = readdir($dh)) !== false) {
|
|
if ($file == '.' || $file == '..') {
|
|
continue;
|
|
}
|
|
|
|
$fullpath = "{$folder}/{$file}";
|
|
$filetype = filetype($fullpath);
|
|
|
|
# Sort directory content so files are processed first.
|
|
if ($filetype == 'dir' || $filetype == 'link') {
|
|
$directories_arr[] = $fullpath;
|
|
}
|
|
if ($filetype == 'file') {
|
|
$files_arr[] = $fullpath;
|
|
}
|
|
}
|
|
|
|
$import_paths = array_merge($files_arr, $directories_arr);
|
|
$fullpath = '';
|
|
|
|
foreach ($import_paths as $fullpath) {
|
|
if (!is_readable($fullpath)) {
|
|
echo "Warning: File '{$fullpath}' is unreadable!" . PHP_EOL;
|
|
continue;
|
|
}
|
|
$skipfc_create = false; // Flag to prevent creation of new FC
|
|
$filetype = filetype($fullpath);
|
|
$shortpath = str_replace($syncdir . '/', '', $fullpath);
|
|
$file = basename($fullpath);
|
|
|
|
if ($staticsync_mapped_category_tree && !$treeprocessed) {
|
|
$path_parts = explode("/", $shortpath);
|
|
array_pop($path_parts);
|
|
$treenodes = touch_category_tree_level($path_parts);
|
|
$treeprocessed = true;
|
|
}
|
|
|
|
# -----FOLDERS-------------
|
|
if (
|
|
($filetype == 'dir' || $filetype == 'link')
|
|
&& count($staticsync_whitelist_folders) > 0
|
|
&& !isPathWhitelisted($shortpath, $staticsync_whitelist_folders)
|
|
) {
|
|
// Folders which are not whitelisted will not be processed any further
|
|
continue;
|
|
}
|
|
|
|
if (
|
|
($filetype == 'dir' || $filetype == 'link')
|
|
&& strpos($nogo, "[{$file}]") === false
|
|
&& strpos($file, $staticsync_alternatives_suffix) === false
|
|
) {
|
|
// Recurse
|
|
ProcessFolder("{$fullpath}");
|
|
}
|
|
|
|
# -------FILES---------------
|
|
if (($filetype == "file") && (substr($file, 0, 1) != ".") && (strtolower($file) != "thumbs.db")) {
|
|
if (isset($staticsync_file_minimum_age) && (time() - filectime($folder . "/" . $file) < $staticsync_file_minimum_age)) {
|
|
// Don't process this file yet as it is too new
|
|
echo " - " . $file . " is too new (" . (time() - filectime($folder . "/" . $file)) . " seconds), skipping\n";
|
|
continue;
|
|
}
|
|
|
|
# Work out extension
|
|
$extension = mb_strcut(parse_filename_extension($file), 0, 10);
|
|
$filename = pathinfo($file, PATHINFO_FILENAME);
|
|
|
|
if (isset($staticsync_alternative_file_text) && strpos($file, $staticsync_alternative_file_text) !== false && !$staticsync_ingest_force) {
|
|
// Set a flag so we can process this later in case we don't process this along with a primary resource file (it may be a new alternative file for an existing resource)
|
|
$alternativefiles[] = $syncdir . '/' . $shortpath;
|
|
continue;
|
|
} elseif (isset($staticsync_alt_suffixes) && $staticsync_alt_suffixes && is_array($staticsync_alt_suffix_array)) {
|
|
// Check if this is a file with a suffix defined in the $staticsync_alt_suffixes array and then process at the end
|
|
foreach ($staticsync_alt_suffix_array as $altsfx => $altname) {
|
|
$altsfxlen = mb_strlen($altsfx);
|
|
$checksfx = substr($filename, -$altsfxlen) == $altsfx;
|
|
if ($checksfx == $altsfx) {
|
|
echo " - Adding to \$alternativefiles array " . $file . "\n";
|
|
$alternativefiles[] = $syncdir . '/' . $shortpath;
|
|
continue 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
$modified_extension = hook('staticsync_modify_extension', 'staticsync', array($fullpath, $shortpath, $extension));
|
|
if ($modified_extension !== false) {
|
|
$extension = $modified_extension;
|
|
}
|
|
|
|
global $banned_extensions, $file_checksums, $file_upload_block_duplicates, $file_checksums_50k;
|
|
# Check to see if extension is banned, do not add if it is banned
|
|
if (array_search(strtolower($extension), array_map('strtolower', $banned_extensions)) !== false) {
|
|
continue;
|
|
}
|
|
|
|
if ($count > $staticsync_max_files) {
|
|
return true;
|
|
}
|
|
|
|
# Already exists or deleted/archived in which case we won't proceed?
|
|
if (!isset($done[$shortpath])) {
|
|
// Extra check to make sure we don't end up with duplicates
|
|
$existing = ps_value("SELECT ref value FROM resource WHERE file_path = ?", array("s",$shortpath), 0);
|
|
if ($existing > 0 || hook('staticsync_plugin_add_to_done')) {
|
|
$done[$shortpath]["processed"] = true;
|
|
$done[$shortpath]["modified"] = date('Y-m-d H:i:s', time());
|
|
continue;
|
|
}
|
|
# Check for duplicate files
|
|
if ($file_upload_block_duplicates) {
|
|
# Generate the ID
|
|
if ($file_checksums_50k) {
|
|
# Fetch the string used to generate the unique ID
|
|
$use = filesize_unlimited($fullpath) . "_" . file_get_contents($fullpath, false, null, 0, 50000);
|
|
$checksum = md5($use);
|
|
} else {
|
|
$checksum = md5_file($fullpath);
|
|
}
|
|
$duplicates = ps_array("select ref value from resource where file_checksum= ?", ['s', $checksum]);
|
|
if (count($duplicates) > 0) {
|
|
$message = str_replace("%resourceref%", implode(",", $duplicates), str_replace("%filename%", $fullpath, $lang['error-duplicatesfound']));
|
|
debug("STATICSYNC ERROR- " . $message);
|
|
$errors[] = $message;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
$count++;
|
|
|
|
echo "Processing file: $fullpath" . PHP_EOL;
|
|
|
|
if ($collection == 0 && $staticsync_autotheme && !$skipfc_create) {
|
|
# Find or create a featured collection for this folder as required.
|
|
$e = explode("/", $shortpath);
|
|
$fallback_fc_categ_name = ucwords($e[0]);
|
|
$name = (count($e) == 1) ? '' : $e[count($e) - 2];
|
|
echo " - Collection '{$name}'" . PHP_EOL;
|
|
// The real featured collection will always be the last directory in the path
|
|
$proposed_fc_categories = array_values(array_diff($e, array_slice($e, -2)));
|
|
if (count($proposed_fc_categories) == 0) {
|
|
if (count($e) > 1) {
|
|
// This is a top level folder - this is needed to ensure no duplication of existing top level FCs
|
|
echo " - File is in a top level folder" . PHP_EOL;
|
|
$proposed_fc_categories = array($e[0]);
|
|
} else {
|
|
// This file is in the root folder, no FC needs to be created
|
|
echo " - File is not in a folder, skipping FC creation" . PHP_EOL;
|
|
$skipfc_create = true;
|
|
}
|
|
}
|
|
if (!$skipfc_create) {
|
|
echo " - Proposed Featured Collection Categories: " . join(" / ", $proposed_fc_categories) . PHP_EOL;
|
|
// Build the tree first, if needed
|
|
$proposed_branch_path = array();
|
|
for ($b = 0; $b < count($proposed_fc_categories); $b++) {
|
|
$parent = ($b == 0 ? 0 : $proposed_branch_path[($b - 1)]);
|
|
$fc_categ_name = ucwords($proposed_fc_categories[$b]);
|
|
|
|
$params = [];
|
|
if ($parent == 0) {
|
|
$parent_sql = 'IS NULL';
|
|
} else {
|
|
$parent_sql = '= ?';
|
|
$params[] = 'i';
|
|
$params[] = $parent;
|
|
}
|
|
|
|
$fc_categ_ref_sql = 'SELECT DISTINCT ref AS `value` FROM collection c LEFT JOIN collection_resource cr on c.ref = cr.collection
|
|
WHERE parent ' . $parent_sql . ' AND type = ? AND name = ? GROUP BY c.ref HAVING count(DISTINCT cr.resource) = 0';
|
|
$fc_categ_ref = ps_value($fc_categ_ref_sql, array_merge($params, ['i', COLLECTION_TYPE_FEATURED, 's', $fc_categ_name]), 0);
|
|
if ($fc_categ_ref == 0) {
|
|
echo " - Creating new Featured Collection category named '{$fc_categ_name}'" . PHP_EOL;
|
|
$fc_categ_ref = create_collection($userref, $fc_categ_name);
|
|
echo " - Created '{$fc_categ_name}' with ref #{$fc_categ_ref}" . PHP_EOL;
|
|
|
|
$updated_fc_category = save_collection(
|
|
$fc_categ_ref,
|
|
array(
|
|
"featured_collections_changes" => array(
|
|
"update_parent" => $parent,
|
|
"force_featured_collection_type" => true,
|
|
"thumbnail_selection_method" => $FEATURED_COLLECTION_BG_IMG_SELECTION_OPTIONS["most_popular_image"],
|
|
)
|
|
)
|
|
);
|
|
|
|
if ($updated_fc_category === false) {
|
|
echo " - Unable to update '{$fc_categ_name}' with ref #{$fc_categ_ref} to a Featured Collection Category" . PHP_EOL;
|
|
}
|
|
}
|
|
|
|
$proposed_branch_path[] = $fc_categ_ref;
|
|
}
|
|
|
|
$collection_parent = array_pop($proposed_branch_path);
|
|
if (is_null($collection_parent)) {
|
|
// We don't have enough folders to create categories so the first one will do (legacy logic)
|
|
$collection_parent = create_collection($userref, $fallback_fc_categ_name);
|
|
save_collection(
|
|
$collection_parent,
|
|
array(
|
|
"featured_collections_changes" => array(
|
|
"update_parent" => 0,
|
|
"force_featured_collection_type" => true,
|
|
"thumbnail_selection_method" => $FEATURED_COLLECTION_BG_IMG_SELECTION_OPTIONS["most_popular_image"],
|
|
)
|
|
)
|
|
);
|
|
}
|
|
echo " - Collection parent should be ref #{$collection_parent}" . PHP_EOL;
|
|
|
|
$params = [];
|
|
if ($collection_parent == 0) {
|
|
$parent_sql = 'IS NULL';
|
|
} else {
|
|
$parent_sql = '= ?';
|
|
$params[] = 'i';
|
|
$params[] = $collection_parent;
|
|
}
|
|
|
|
$collection_sql = 'SELECT DISTINCT ref as `value` FROM collection c LEFT JOIN collection_resource cr on c.ref = cr.collection
|
|
WHERE parent ' . $parent_sql . ' AND type = ? AND name = ? GROUP BY c.ref HAVING count(DISTINCT cr.resource) > 0';
|
|
$collection = ps_value($collection_sql, array_merge($params, ['i', COLLECTION_TYPE_FEATURED, 's', ucwords($name)]), 0);
|
|
|
|
if ($collection == 0) {
|
|
$collection = create_collection($userref, ucwords($name));
|
|
echo " - Created '{$name}' with ref #{$collection}" . PHP_EOL;
|
|
|
|
$updated_fc_category = save_collection(
|
|
$collection,
|
|
array(
|
|
"featured_collections_changes" => array(
|
|
"update_parent" => $collection_parent,
|
|
"force_featured_collection_type" => true,
|
|
"thumbnail_selection_method" => $FEATURED_COLLECTION_BG_IMG_SELECTION_OPTIONS["most_popular_image"],
|
|
)
|
|
)
|
|
);
|
|
|
|
if ($updated_fc_category === false) {
|
|
echo " - Unable to update '{$name}' with ref #{$collection} to be a Featured Collection under parent ref #{$collection_parent}" . PHP_EOL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Work out a resource type based on the extension.
|
|
$type = (isset($GLOBALS['staticsync_extension_mapping_default']) ? $GLOBALS['staticsync_extension_mapping_default'] : $resource_type_extension_mapping_default);
|
|
$rt_ext_mappings = (isset($GLOBALS['staticsync_extension_mapping']) ? $GLOBALS['staticsync_extension_mapping'] : $resource_type_extension_mapping);
|
|
reset($rt_ext_mappings);
|
|
foreach ($rt_ext_mappings as $rt => $extensions) {
|
|
if (in_array(strtolower($extension), $extensions)) {
|
|
$type = $rt;
|
|
}
|
|
}
|
|
|
|
if (isset($staticsync_mapfolders)) {
|
|
$field_nodes = array();
|
|
foreach ($staticsync_mapfolders as $mapfolder) {
|
|
$match = $mapfolder["match"];
|
|
$field = $mapfolder["field"];
|
|
$level = $mapfolder["level"];
|
|
$path_parts = explode("/", $shortpath);
|
|
if (
|
|
$field == 'resource_type'
|
|
&& (strpos("/" . $shortpath, $match) !== false)
|
|
&& $level < count($path_parts)
|
|
) {
|
|
$value = $path_parts[$level - 1];
|
|
$typeidx = array_search($value, array_column($restypes, "name"));
|
|
if ($typeidx !== false) {
|
|
$type = $restypes[$typeidx]["ref"];
|
|
echo " - \$staticsync_mapfolders - set resource type to " . $value . " ($type)" . PHP_EOL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$modified_type = hook('modify_type', 'staticsync', array( $type ));
|
|
if (is_numeric($modified_type)) {
|
|
$type = $modified_type;
|
|
}
|
|
|
|
# Formulate a title
|
|
if ($staticsync_title_includes_path && $view_title_field !== $filename_field) {
|
|
$title_find = array('/', '_', ".$extension" );
|
|
$title_repl = array(' - ', ' ', '');
|
|
$title = ucfirst(str_ireplace($title_find, $title_repl, $shortpath));
|
|
} else {
|
|
$title = str_ireplace(".$extension", '', $file);
|
|
}
|
|
|
|
$modified_title = hook('modify_title', 'staticsync', array( $title ));
|
|
if ($modified_title !== false) {
|
|
$title = $modified_title;
|
|
}
|
|
|
|
# Import this file
|
|
$r = import_resource($shortpath, $type, $title, $staticsync_ingest, $extension);
|
|
echo " - Created resource #" . $r . PHP_EOL;
|
|
|
|
if ($r !== false) {
|
|
# Add to mapped category tree (if configured)
|
|
if (isset($staticsync_mapped_category_tree) && isset($treenodes) && count($treenodes) > 0) {
|
|
// Add path nodes to resource
|
|
add_resource_nodes($r, $treenodes);
|
|
}
|
|
|
|
# default access level. This may be overridden by metadata mapping.
|
|
$accessval = 0;
|
|
|
|
# StaticSync path / metadata mapping
|
|
# Extract metadata from the file path as per $staticsync_mapfolders in config.php
|
|
if (isset($staticsync_mapfolders)) {
|
|
$field_nodes = array();
|
|
foreach ($staticsync_mapfolders as $mapfolder) {
|
|
$match = $mapfolder["match"];
|
|
$field = $mapfolder["field"];
|
|
$level = $mapfolder["level"];
|
|
if (strpos("/" . $shortpath, $match) !== false) {
|
|
# Match. Extract metadata.
|
|
$path_parts = explode("/", $shortpath);
|
|
if ($level < count($path_parts)) {
|
|
// special cases first.
|
|
if ($field == 'access') {
|
|
# access level is a special case
|
|
# first determine if the value matches a defined access level
|
|
$value = $path_parts[$level - 1];
|
|
for ($n = 0; $n < 3; $n++) {
|
|
# if we get an exact match or a match except for case
|
|
if ($value == $lang["access" . $n] || strtoupper($value) == strtoupper($lang['access' . $n])) {
|
|
$accessval = $n;
|
|
echo " - Will set access level to " . $lang['access' . $n] . " ($n)" . PHP_EOL;
|
|
}
|
|
}
|
|
} elseif ($field == 'archive') {
|
|
# archive level is a special case
|
|
# first determine if the value matches a defined archive level
|
|
$value = $mapfolder["archive"];
|
|
$archive_array = array_merge(array(-2,-1,0,1,2,3), $additional_archive_states);
|
|
if (in_array($value, $archive_array)) {
|
|
$archiveval = $value;
|
|
echo " - Will set archive level to " . $lang['status' . $value] . " ($archiveval)" . PHP_EOL;
|
|
}
|
|
} elseif (is_int_loose($field)) {
|
|
# Save the value
|
|
$value = $path_parts[$level - 1];
|
|
$modifiedval = hook('staticsync_mapvalue', '', array($r, $value));
|
|
if ($modifiedval) {
|
|
$value = $modifiedval;
|
|
}
|
|
$field_info = get_resource_type_field($field);
|
|
if (in_array($field_info['type'], $FIXED_LIST_FIELD_TYPES)) {
|
|
$fieldnodes = get_nodes($field, null, $field_info['type'] == FIELD_TYPE_CATEGORY_TREE);
|
|
|
|
if (in_array($value, array_column($fieldnodes, "name")) || ($field_info['type'] == FIELD_TYPE_DYNAMIC_KEYWORDS_LIST && !checkperm('bdk' . $field))) {
|
|
// Add this to array of nodes to add
|
|
|
|
if ($field_info['type'] == FIELD_TYPE_CATEGORY_TREE) {
|
|
# Use value found in category tree
|
|
$category_tree_values = array_filter($fieldnodes, function (array $fieldnodes) use ($value) {
|
|
return $value == $fieldnodes['name'];
|
|
});
|
|
$newnode = array_values($category_tree_values)[0]['ref']; # If multiple values found (category tree "leaves") we must pick one, taking first in array i.e. lowest node ref.
|
|
echo " - Using category tree node $newnode - $value" . "\n";
|
|
} else {
|
|
# Add new field for dynamic keywords list
|
|
$newnode = set_node(null, $field, trim($value), null, null);
|
|
echo " - Adding node" . trim($value) . "\n";
|
|
}
|
|
|
|
$newnodes = array($newnode);
|
|
|
|
if ($field_info['type'] == FIELD_TYPE_CATEGORY_TREE && $category_tree_add_parents) {
|
|
// We also need to add all parent nodes for category trees
|
|
$parent_nodes = get_parent_nodes($newnode);
|
|
$newnodes = array_merge($newnodes, array_keys($parent_nodes));
|
|
}
|
|
|
|
if ($staticsync_extension_mapping_append_values && !in_array($field_info['type'], array(FIELD_TYPE_DROP_DOWN_LIST,FIELD_TYPE_RADIO_BUTTONS)) && (!isset($staticsync_extension_mapping_append_values_fields) || in_array($field_info['ref'], $staticsync_extension_mapping_append_values_fields))) {
|
|
// The $staticsync_extension_mapping_append_values variable actually refers to folder->metadata mapping, not the file extension
|
|
$curnodes = get_resource_nodes($r, $field);
|
|
$field_nodes[$field] = array_merge($curnodes, $newnodes, $field_nodes[$field] ?? []);
|
|
} else {
|
|
// We have got a new value for this field and we are not appending values,
|
|
// replace any existing value the array
|
|
$field_nodes[$field] = $newnodes;
|
|
}
|
|
}
|
|
} else {
|
|
if (
|
|
$staticsync_extension_mapping_append_values
|
|
&& (!isset($staticsync_extension_mapping_append_values_fields)
|
|
|| in_array($field_info['ref'], $staticsync_extension_mapping_append_values_fields))
|
|
&& in_array(
|
|
$field_info['type'],
|
|
[
|
|
FIELD_TYPE_TEXT_BOX_SINGLE_LINE,
|
|
FIELD_TYPE_TEXT_BOX_MULTI_LINE,
|
|
FIELD_TYPE_TEXT_BOX_LARGE_MULTI_LINE,
|
|
FIELD_TYPE_TEXT_BOX_FORMATTED_AND_TINYMCE,
|
|
FIELD_TYPE_DATE,FIELD_TYPE_WARNING_MESSAGE,
|
|
]
|
|
)
|
|
) {
|
|
// Append the values if possible
|
|
$existing_value = get_data_by_field($r, $field);
|
|
if ((string) $existing_value != "") {
|
|
$values_to_add[$field] = $existing_value .
|
|
($staticsync_extension_mapping_append_separator ?? " ") .
|
|
$value;
|
|
} else {
|
|
$values_to_add[$field] = $value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (count($field_nodes) > 0) {
|
|
$nodes_to_add = array();
|
|
foreach ($field_nodes as $nodeids) {
|
|
$nodes_to_add = array_merge($nodes_to_add, $nodeids);
|
|
}
|
|
}
|
|
}
|
|
|
|
# Update resource table
|
|
$setvals = array();
|
|
$setvals["access"] = $accessval;
|
|
|
|
if (isset($archiveval)) {
|
|
$setvals["archive"] = $archiveval;
|
|
} else {
|
|
$setvals["archive"] = $staticsync_defaultstate;
|
|
}
|
|
|
|
if (!$enable_thumbnail_creation_on_upload) {
|
|
$setvals["has_image"] = 0;
|
|
$setvals["preview_attempts"] = 0;
|
|
}
|
|
|
|
$updatesql = array();
|
|
$params = [];
|
|
|
|
foreach ($setvals as $name => $val) {
|
|
$updatesql[] = $name . "= ? ";
|
|
$params[] = 'i';
|
|
$params[] = $val;
|
|
}
|
|
|
|
$params[] = 'i';
|
|
$params[] = $r;
|
|
|
|
ps_query("UPDATE resource SET " . implode(",", $updatesql) . " WHERE ref = ?", $params);
|
|
unset($GLOBALS["get_resource_data_cache"][$r]);
|
|
|
|
if (count($nodes_to_add ?? [])) {
|
|
echo " - adding nodes " . implode(", ", $nodes_to_add) . "to resource: $r" . PHP_EOL;
|
|
add_resource_nodes($r, $nodes_to_add);
|
|
$joins = get_resource_table_joins();
|
|
foreach ($nodes_to_add as $node) {
|
|
$node_data = [];
|
|
if (get_node($node, $node_data) && in_array($node_data["resource_type_field"], $joins)) {
|
|
update_resource_field_column($r, $node_data["resource_type_field"], $node_data["name"]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (count($values_to_add ?? [])) {
|
|
foreach ($values_to_add as $field => $value) {
|
|
echo " - adding value $value in field ref: $field to resource: $r" . PHP_EOL;
|
|
$errors = [];
|
|
$result = update_field($r, $field, $value);
|
|
}
|
|
}
|
|
|
|
if (isset($staticsync_filepath_to_field)) {
|
|
update_field($r, $staticsync_filepath_to_field, $shortpath);
|
|
}
|
|
|
|
# Add any alternative files
|
|
$altpath = $fullpath . $staticsync_alternatives_suffix;
|
|
if ($staticsync_ingest && file_exists($altpath)) {
|
|
$adh = opendir($altpath);
|
|
while (($altfile = readdir($adh)) !== false) {
|
|
$filetype = filetype($altpath . "/" . $altfile);
|
|
if (($filetype == "file") && (substr($file, 0, 1) != ".") && (strtolower($file) != "thumbs.db")) {
|
|
# Create alternative file
|
|
# Find extension
|
|
$ext = explode(".", $altfile);
|
|
$ext = $ext[count($ext) - 1];
|
|
|
|
$description = str_replace("?", strtoupper($ext), $lang["originalfileoftype"]);
|
|
$file_size = filesize_unlimited($altpath . "/" . $altfile);
|
|
|
|
$aref = add_alternative_file($r, $altfile, $description, $altfile, $ext, $file_size);
|
|
$path = get_resource_path($r, true, '', true, $ext, -1, 1, false, '', $aref);
|
|
$result = copy($altpath . "/" . $altfile, $path); // Copy alternative file instead of rename so that permissions of filestore will be used
|
|
if ($result === false) {
|
|
# The copy failed.
|
|
debug(" - ERROR: Staticsync failed to copy alternative file from: " . $altpath . "/" . $altfile);
|
|
return false;
|
|
}
|
|
$use_error_exception_cache = $GLOBALS["use_error_exception"] ?? false;
|
|
$GLOBALS["use_error_exception"] = true;
|
|
try {
|
|
unlink($altpath . "/" . $altfile);
|
|
try {
|
|
chmod($path, 0777);
|
|
} catch (Exception $e) {
|
|
// Not fatal, just log
|
|
debug(" - ERROR: Staticsync failed to set permissions on ingested alternative file: " . $path . PHP_EOL . " - Error message: " . $e->getMessage() . PHP_EOL);
|
|
}
|
|
} catch (Exception $e) {
|
|
echo " - ERROR: failed to delete file from source. Please check correct permissions on: " . $syncdir . "/" . $shortpath . "\n - Error message: " . $e->getMessage() . PHP_EOL;
|
|
return false;
|
|
}
|
|
$GLOBALS["use_error_exception"] = $use_error_exception_cache;
|
|
}
|
|
}
|
|
} elseif (isset($staticsync_alternative_file_text)) {
|
|
$basefilename = str_ireplace(".$extension", '', $file);
|
|
$altfilematch = "/{$basefilename}{$staticsync_alternative_file_text}(.*)\.(.*)/";
|
|
|
|
echo " - Searching for alternative files for base file: " . $basefilename , PHP_EOL;
|
|
echo " - Checking " . $altfilematch . PHP_EOL;
|
|
|
|
$folder_files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($folder));
|
|
$altfiles = new RegexIterator($folder_files, $altfilematch, RecursiveRegexIterator::MATCH);
|
|
foreach ($altfiles as $altfile) {
|
|
staticsync_process_alt($altfile->getPathname(), $r);
|
|
echo " - Processed alternative: " . $shortpath . PHP_EOL;
|
|
}
|
|
}
|
|
|
|
# Add to collection
|
|
if ($staticsync_autotheme && !$skipfc_create) {
|
|
// Featured collection categories cannot contain resources. At this stage we need to distinguish
|
|
// between categories and collections by checking for children collections.
|
|
if (!is_featured_collection_category_by_children($collection)) {
|
|
$test = ps_query("SELECT " . columns_in("collection_resource") . " FROM collection_resource WHERE collection= ? AND resource= ?", ['i', $collection, 'i', $r]);
|
|
if (count($test) == 0) {
|
|
ps_query("INSERT INTO collection_resource (collection, resource, date_added) VALUES (?, ?, NOW())", ['i', $collection, 'i', $r]);
|
|
$featured_collection_parent = validate_collection_parent(get_collection($collection, false));
|
|
if (!in_array($featured_collection_parent, $GLOBALS['fcs_to_reorder'])) {
|
|
$GLOBALS['fcs_to_reorder'][] = $featured_collection_parent;
|
|
}
|
|
}
|
|
} else {
|
|
echo " - Error: Unable to add resource to a featured collection category!" . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
$done[$shortpath]["ref"] = $r;
|
|
$done[$shortpath]["processed"] = true;
|
|
$done[$shortpath]["modified"] = date('Y-m-d H:i:s', time());
|
|
update_disk_usage($r);
|
|
} else {
|
|
# Import failed - file still being uploaded?
|
|
echo " *** Skipping file - it was not possible to move the file (still being imported/uploaded?)" . PHP_EOL;
|
|
}
|
|
} elseif ($staticsync_ingest_force) {
|
|
// If the resource has a path but $ingest is true then the $ingest has been changed, need to copy original file into filestore
|
|
global $get_resource_path_fpcache;
|
|
$existing = $done[$shortpath]["ref"];
|
|
$alternative = isset($done[$shortpath]["alternative"]) ? $done[$shortpath]["alternative"] : -1;
|
|
|
|
echo " - File already imported - $shortpath (resource #$existing, alternative #$alternative). Ingesting.." . PHP_EOL;
|
|
|
|
$get_resource_path_fpcache[$existing] = ""; // Forces get_resource_path to ignore the syncdir file_path
|
|
$destination = get_resource_path($existing, true, "", true, $extension, -1, 1, false, "", $alternative);
|
|
$result = copy($syncdir . "/" . $shortpath, $destination); // Copy instead of rename so that permissions of filestore will be used
|
|
|
|
if ($result === false) {
|
|
# The copy failed.
|
|
debug(" - ERROR: Staticsync failed to copy file from: " . $syncdir . "/" . $shortpath);
|
|
return false;
|
|
}
|
|
|
|
$use_error_exception_cache = $GLOBALS["use_error_exception"] ?? false;
|
|
$GLOBALS["use_error_exception"] = true;
|
|
try {
|
|
unlink($syncdir . "/" . $shortpath);
|
|
try {
|
|
chmod($destination, 0777);
|
|
} catch (Exception $e) {
|
|
// Not fatal, just log
|
|
debug(" - ERROR: Staticsync failed to set permissions on ingested file: " . $destination . PHP_EOL . " - Error message: " . $e->getMessage());
|
|
}
|
|
} catch (Exception $e) {
|
|
echo " - ERROR: failed to delete file from source. Please check correct permissions on: " . $syncdir . "/" . $shortpath . PHP_EOL . " - Error message: " . $e->getMessage() . PHP_EOL;
|
|
return false;
|
|
}
|
|
$GLOBALS["use_error_exception"] = $use_error_exception_cache;
|
|
|
|
if ($alternative == -1) {
|
|
ps_query("UPDATE resource SET file_path=NULL WHERE ref = ?", ['i', $existing]);
|
|
} else {
|
|
ps_query("UPDATE resource_alt_files SET file_name = ? WHERE resource = ? AND ref= ?", ['s', $file, 'i', $existing, 'i', $alternative]);
|
|
}
|
|
} elseif (
|
|
!isset($done[$shortpath]["archive"]) // Check modified times and and update previews if no existing archive state is set,
|
|
|| (isset($resource_deletion_state) && $done[$shortpath]["archive"] != $resource_deletion_state) // or if resource is not in system deleted state,
|
|
|| (isset($staticsync_revive_state) && $done[$shortpath]["archive"] == $staticsync_deleted_state)
|
|
) { // or resource is currently in staticsync deleted state and needs to be reinstated
|
|
if (!file_exists($fullpath)) {
|
|
echo " - Warning: File '{$fullpath}' does not exist anymore!";
|
|
continue;
|
|
}
|
|
|
|
$filemod = filemtime($fullpath);
|
|
if (isset($done[$shortpath]["modified"]) && $filemod > strtotime($done[$shortpath]["modified"]) || (isset($staticsync_revive_state) && $done[$shortpath]["archive"] == $staticsync_deleted_state)) {
|
|
$count++;
|
|
# File has been modified since we last created previews. Create again.
|
|
$rd = ps_query("SELECT ref, has_image, file_modified, file_extension, archive FROM resource WHERE file_path= ?", ['s', $shortpath]);
|
|
if (count($rd) > 0) {
|
|
$rd = $rd[0];
|
|
$rref = $rd["ref"];
|
|
|
|
echo " - Resource $rref has changed, regenerating previews: $fullpath" . PHP_EOL;
|
|
extract_exif_comment($rref, $rd["file_extension"]);
|
|
|
|
# extract text from documents (e.g. PDF, DOC).
|
|
global $extracted_text_field;
|
|
if (isset($extracted_text_field)) {
|
|
if (isset($unoconv_path) && in_array($extension, $unoconv_extensions)) {
|
|
// omit, since the unoconv process will do it during preview creation below
|
|
} else {
|
|
global $offline_job_queue, $offline_job_in_progress;
|
|
if ($offline_job_queue && !$offline_job_in_progress) {
|
|
$extract_text_job_data = array(
|
|
'ref' => $rref,
|
|
'extension' => $extension,
|
|
);
|
|
|
|
job_queue_add('extract_text', $extract_text_job_data);
|
|
} else {
|
|
extract_text($rref, $extension);
|
|
}
|
|
}
|
|
}
|
|
|
|
# Store original filename in field, if set
|
|
global $filename_field;
|
|
if (isset($filename_field)) {
|
|
update_field($rref, $filename_field, $file);
|
|
}
|
|
if ($enable_thumbnail_creation_on_upload) {
|
|
create_previews($rref, false, $rd["file_extension"], false, false, -1, false, $staticsync_ingest);
|
|
}
|
|
$sql = '';
|
|
$params = [];
|
|
if (isset($staticsync_revive_state) && ($rd["archive"] == $staticsync_deleted_state)) {
|
|
$sql .= ", archive= ?";
|
|
$params[] = 'i';
|
|
$params[] = $staticsync_revive_state;
|
|
}
|
|
$params[] = 'i';
|
|
$params[] = $rref;
|
|
ps_query("UPDATE resource SET file_modified=NOW() " . $sql . ((!$enable_thumbnail_creation_on_upload) ? ", has_image=0, preview_attempts=0 " : "") . " WHERE ref= ?", $params);
|
|
|
|
if (isset($staticsync_revive_state) && ($rd["archive"] == $staticsync_deleted_state)) {
|
|
# Log this
|
|
resource_log($rref, LOG_CODE_STATUS_CHANGED, '', '', $staticsync_deleted_state, $staticsync_revive_state);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
closedir($dh);
|
|
}
|
|
|
|
function staticsync_process_alt($alternativefile, $ref = "", $alternative = "")
|
|
{
|
|
// Process an alternative file
|
|
global $staticsync_alternative_file_text, $syncdir, $lang, $staticsync_ingest, $alternative_file_previews,
|
|
$done, $filename_field, $view_title_field, $staticsync_title_includes_path, $staticsync_alt_suffixes, $staticsync_alt_suffix_array;
|
|
|
|
$shortpath = str_replace($syncdir . '/', '', $alternativefile);
|
|
if (!isset($done[$shortpath])) {
|
|
$alt_parts = pathinfo($alternativefile);
|
|
|
|
if (substr($alt_parts['filename'], 0, 1) == ".") {
|
|
return false;
|
|
}
|
|
|
|
if (isset($staticsync_alternative_file_text) && strpos($alternativefile, $staticsync_alternative_file_text) !== false) {
|
|
$altfilenameparts = explode($staticsync_alternative_file_text, $alt_parts['filename']);
|
|
$altbasename = $altfilenameparts[0];
|
|
$altdesc = $altfilenameparts[1];
|
|
$altname = str_replace("?", strtoupper($alt_parts["extension"]), $lang["fileoftype"]);
|
|
} elseif (isset($staticsync_alt_suffixes) && $staticsync_alt_suffixes && is_array($staticsync_alt_suffix_array)) {
|
|
// Check for files with a suffix defined in the $staticsync_alt_suffixes array
|
|
foreach ($staticsync_alt_suffix_array as $altsfx => $altname) {
|
|
$altsfxlen = mb_strlen($altsfx);
|
|
if (substr($alt_parts['filename'], -$altsfxlen) == $altsfx) {
|
|
$altbasename = substr($alt_parts['filename'], 0, -$altsfxlen);
|
|
$altdesc = strtoupper($alt_parts['extension']) . " " . $lang["file"];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($ref == "") {
|
|
// We need to find which resource this alternative file relates to
|
|
echo " - Searching for primary resource related to " . $alternativefile . " in " . $alt_parts['dirname'] . '/' . $altbasename . "." . PHP_EOL;
|
|
foreach ($done as $syncedfile => $synceddetails) {
|
|
$syncedfile_parts = pathinfo($syncedfile);
|
|
if (
|
|
strpos($syncdir . '/' . $syncedfile, $alt_parts['dirname'] . '/' . $altbasename . ".") !== false
|
|
|| (isset($altsfx) && $syncdir . '/' . $syncedfile_parts["filename"] . $altsfx . "." . $syncedfile_parts["extension"] == $alternativefile)
|
|
) {
|
|
// This synced file has the same base name as the resource
|
|
$ref = $synceddetails["ref"];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($ref == "") {
|
|
//Primary resource file may have been ingested on a previous run - try to locate it
|
|
$ingested = ps_array(
|
|
"SELECT resource value
|
|
FROM resource_node rn
|
|
LEFT JOIN node n ON n.ref=rn.node
|
|
WHERE n.resource_type_field = ?
|
|
AND rn.resource LIKE ?",
|
|
["i",$filename_field,"s",$altbasename . "%"]
|
|
);
|
|
|
|
if (count($ingested) < 1) {
|
|
echo " - No primary resource found for " . $alternativefile . ". Skipping file" . PHP_EOL;
|
|
debug("staticsync - No primary resource found for " . $alternativefile . ". Skipping file");
|
|
return false;
|
|
}
|
|
|
|
if (count($ingested) == 1) {
|
|
echo " - Found matching resource: " . $ingested[0] . PHP_EOL;
|
|
$ref = $ingested[0];
|
|
} else {
|
|
if ($staticsync_title_includes_path) {
|
|
$title_find = array('/', '_');
|
|
$title_repl = array(' - ', ' ');
|
|
$parentpath = ucfirst(str_ireplace($title_find, $title_repl, $shortpath));
|
|
|
|
echo " - This file has path: " . $parentpath . PHP_EOL;
|
|
foreach ($ingested as $ingestedref) {
|
|
$ingestedpath = get_data_by_field($ingestedref, $view_title_field);
|
|
echo "Found resource with same name. Path: " . $ingestedpath . PHP_EOL;
|
|
if (strpos($parentpath, $ingestedpath) !== false) {
|
|
echo " - Found matching resource: " . $ingestedref . PHP_EOL;
|
|
$ref = $ingestedref;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if ($ref == "") {
|
|
echo " - Multiple possible primary resources found for " . $alternativefile . ". (Resource IDs: " . implode(",", $ingested) . "). Skipping file" . PHP_EOL;
|
|
debug("staticsync - Multiple possible primary resources found for " . $alternativefile . ". (Resource IDs: " . implode(",", $ingested) . "). Skipping file");
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
echo " - Processing alternative file - '" . $alternativefile . "' for resource #" . $ref . PHP_EOL;
|
|
|
|
if ($alternative == "") {
|
|
// Create a new alternative file
|
|
$alt["file_size"] = filesize_unlimited($alternativefile);
|
|
$alt["extension"] = $alt_parts["extension"];
|
|
$alt["altdescription"] = $altdesc;
|
|
$alt["name"] = $altname;
|
|
|
|
$alt["ref"] = add_alternative_file($ref, $alt["name"], $alt["altdescription"], $alternativefile, $alt["extension"], $alt["file_size"]);
|
|
$alternative = $alt["ref"];
|
|
|
|
echo " - Created a new alternative file - '" . $alt["ref"] . "' for resource #" . $ref . PHP_EOL;
|
|
debug("Staticsync - Created a new alternative file - '" . $alt["ref"] . "' for resource #" . $ref);
|
|
$alt["path"] = get_resource_path($ref, true, '', false, $alt["extension"], -1, 1, false, '', $alt["ref"]);
|
|
echo " - Alternative file path - " . $alt["path"] . PHP_EOL;
|
|
debug("Staticsync - alternative file path - " . $alt["path"]);
|
|
$alt["basefilename"] = $altbasename;
|
|
|
|
if ($staticsync_ingest) {
|
|
echo " - Moving file to " . $alt["path"] . PHP_EOL;
|
|
$result = copy($alternativefile, $alt["path"]); // Copy alternative file instead of rename so that permissions of filestore will be used
|
|
|
|
if ($result === false) {
|
|
debug(" - ERROR: Staticsync failed to copy alternative file from: {$alternativefile}");
|
|
return false;
|
|
}
|
|
|
|
$use_error_exception_cache = $GLOBALS["use_error_exception"] ?? false;
|
|
$GLOBALS["use_error_exception"] = true;
|
|
try {
|
|
unlink($alternativefile);
|
|
try {
|
|
chmod($alt["path"], 0777);
|
|
} catch (Exception $e) {
|
|
// Not fatal, just log
|
|
debug(" - ERROR: Staticsync failed to set permissions on ingested alternative file: " . $alt["path"] . PHP_EOL . " - Error message: " . $e->getMessage() . PHP_EOL);
|
|
}
|
|
} catch (Exception $e) {
|
|
echo " - ERROR: failed to delete file from source. Please check correct permissions on: " . $alternativefile . PHP_EOL . " - Error message: " . $e->getMessage() . PHP_EOL;
|
|
return false;
|
|
}
|
|
$GLOBALS["use_error_exception"] = $use_error_exception_cache;
|
|
}
|
|
|
|
if ($alternative_file_previews) {
|
|
create_previews($ref, false, $alt["extension"], false, false, $alt["ref"], false, $staticsync_ingest);
|
|
}
|
|
|
|
hook("staticsync_after_alt", '', array($ref,$alt));
|
|
echo " - Added alternative file ref:" . $alt["ref"] . ", name: " . $alt["name"] . ". " . "(" . $alt["altdescription"] . ") Size: " . $alt["file_size"] . PHP_EOL;
|
|
debug("Staticsync - added alternative file ref:" . $alt["ref"] . ", name: " . $alt["name"] . ". " . "(" . $alt["altdescription"] . ") Size: " . $alt["file_size"]);
|
|
$done[$shortpath]["processed"] = true;
|
|
}
|
|
} elseif ($alternative != "" && $alternative_file_previews) {
|
|
// An existing alternative file has changed, update previews if required
|
|
debug("Alternative file changed, recreating previews");
|
|
create_previews($ref, false, pathinfo($alternativefile, PATHINFO_EXTENSION), false, false, $alternative, false, $staticsync_ingest);
|
|
ps_query("UPDATE resource_alt_files SET creation_date=NOW() WHERE ref= ?", ['i', $alternative]);
|
|
$done[$shortpath]["processed"] = true;
|
|
}
|
|
echo " - Completed path : " . $shortpath . PHP_EOL;
|
|
$done[$shortpath]["ref"] = $ref;
|
|
$done[$shortpath]["alternative"] = $alternative;
|
|
set_process_lock("staticsync"); // Update the lock so we know it is still processing resources
|
|
}
|
|
|
|
# Recurse through the folder structure.
|
|
ProcessFolder($syncdir);
|
|
|
|
debug("StaticSync: \$done = " . json_encode($done));
|
|
|
|
echo " - Checking for alternative files that have not been processed" . PHP_EOL;
|
|
|
|
foreach ($alternativefiles as $alternativefile) {
|
|
$shortpath = str_replace($syncdir . "/", '', $alternativefile);
|
|
echo " - Processing alternative file " . $shortpath . PHP_EOL;
|
|
debug("Staticsync - Processing altfile " . $shortpath);
|
|
|
|
if (array_key_exists($shortpath, $done) && isset($done[$shortpath]["alternative"]) && $done[$shortpath]["alternative"] > 0) {
|
|
echo " - Alternative '{$shortpath}' has already been processed. Skipping" . PHP_EOL;
|
|
continue;
|
|
}
|
|
|
|
if (!file_exists($alternativefile)) {
|
|
echo " - Warning: File '{$alternativefile}' does not exist anymore!";
|
|
continue;
|
|
}
|
|
|
|
if (!isset($done[$shortpath])) {
|
|
staticsync_process_alt($alternativefile);
|
|
} elseif ($alternative_file_previews) {
|
|
// File already synced but check if it has been modified as may need to update previews
|
|
$altfilemod = filemtime($alternativefile);
|
|
if (isset($done[$shortpath]["modified"]) && $altfilemod > strtotime($done[$shortpath]["modified"])) {
|
|
// Update the alternative file
|
|
staticsync_process_alt($alternativefile, $done[$shortpath]["resource"], $done[$shortpath]["alternative"]);
|
|
}
|
|
}
|
|
}
|
|
|
|
echo " - Checking deleted files" . PHP_EOL;
|
|
|
|
if (!$staticsync_ingest) {
|
|
# If not ingesting files, look for deleted files in the sync folder and archive the appropriate file from ResourceSpace.
|
|
echo "Looking for deleted files..." . PHP_EOL;
|
|
# For all resources with filepaths, check they still exist and archive if not.
|
|
$resources_to_archive = array();
|
|
$n = 0;
|
|
|
|
foreach ($done as $syncedfile => $synceddetails) {
|
|
if (!isset($synceddetails["processed"]) && isset($synceddetails["archive"]) && !(isset($staticsync_ignore_deletion_states) && in_array($synceddetails["archive"], $staticsync_ignore_deletion_states)) && $synceddetails["archive"] != $staticsync_deleted_state || isset($synceddetails["alternative"])) {
|
|
$resources_to_archive[$n]["file_path"] = $syncedfile;
|
|
$resources_to_archive[$n]["ref"] = $synceddetails["ref"];
|
|
$resources_to_archive[$n]["archive"] = isset($synceddetails["archive"]) ? $synceddetails["archive"] : "";
|
|
if (isset($synceddetails["alternative"])) {
|
|
$resources_to_archive[$n]["alternative"] = $synceddetails["alternative"];
|
|
}
|
|
$n++;
|
|
}
|
|
}
|
|
|
|
# ***for modified syncdir directories:
|
|
$syncdonemodified = hook("modifysyncdonerf");
|
|
if (!empty($syncdonemodified)) {
|
|
$resources_to_archive = $syncdonemodified;
|
|
}
|
|
|
|
// Get all the featured collections (including categories) that hold these resources
|
|
$fc_branches = get_featured_collections_by_resources(array_column($resources_to_archive, "ref"));
|
|
|
|
foreach ($resources_to_archive as $rf) {
|
|
$fp = $syncdir . '/' . $rf["file_path"];
|
|
if (isset($rf['syncdir']) && $rf['syncdir'] != '') {
|
|
# ***for modified syncdir directories:
|
|
$fp = $rf['syncdir'] . $rf["file_path"];
|
|
}
|
|
|
|
if ($fp != "" && !file_exists($fp)) {
|
|
// Additional check - make sure the archive state hasn't changed since the start of the script
|
|
$cas = ps_value("SELECT archive value FROM resource where ref = ?", ['i', $rf['ref']], 0);
|
|
if (isset($staticsync_ignore_deletion_states) && !in_array($cas, $staticsync_ignore_deletion_states)) {
|
|
if (!isset($rf["alternative"])) {
|
|
echo " - File no longer exists: " . $rf["ref"] . " " . $fp . PHP_EOL;
|
|
# Set to archived, unless state hasn't changed since script started.
|
|
if (isset($staticsync_deleted_state)) {
|
|
ps_query("UPDATE resource SET archive= ? WHERE ref= ?", ['i', $staticsync_deleted_state, 'i', $rf['ref']]);
|
|
} else {
|
|
delete_resource($rf["ref"]);
|
|
}
|
|
if (isset($resource_deletion_state) && $staticsync_deleted_state == $resource_deletion_state) {
|
|
// Only remove from collections if we are really deleting this. Some configurations may have a separate state or synced resources may be temporarily absent
|
|
ps_query("DELETE FROM collection_resource WHERE resource= ?", ['i', $rf['ref']]);
|
|
}
|
|
# Log this
|
|
resource_log($rf['ref'], LOG_CODE_STATUS_CHANGED, '', '', $rf["archive"], $staticsync_deleted_state);
|
|
} else {
|
|
echo " - Alternative file no longer exists: resource " . $rf["ref"] . " alt:" . $rf["alternative"] . " " . $fp . PHP_EOL;
|
|
ps_query("DELETE FROM resource_alt_files WHERE ref= ?", ['i', $rf['alternative']]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Remove any themes that are now empty as a result of deleted files.
|
|
echo " - Checking for empty featured collections" . PHP_EOL;
|
|
foreach ($fc_branches as $fc_branch) {
|
|
// Reverse the branch path to start from the leaf node. This way, when you reach the category you won't have any
|
|
// children nodes (ie a normal FC) left (if it will be the case) and we'll be able to delete the FC category.
|
|
$reversed_branch_path = array_reverse($fc_branch);
|
|
foreach ($reversed_branch_path as $fc) {
|
|
if (!can_delete_featured_collection($fc["ref"])) {
|
|
continue;
|
|
}
|
|
|
|
if (delete_collection($fc["ref"]) === false) {
|
|
echo " -- Unable to delete featured collection #{$fc["ref"]}" . PHP_EOL;
|
|
} else {
|
|
echo " -- Deleted featured collection #{$fc["ref"]}" . PHP_EOL;
|
|
}
|
|
}
|
|
}
|
|
|
|
echo " - Checking if featured collections have to be re-ordered (e.g if a category has become just a featured collection)" . PHP_EOL;
|
|
foreach ($fcs_to_reorder as $fc_parent) {
|
|
$new_fcs_order = reorder_all_featured_collections_with_parent($fc_parent);
|
|
log_activity("via Static Sync, re-ordering for parent #{$fc_parent}", LOG_CODE_REORDERED, implode(', ', $new_fcs_order), 'collection');
|
|
}
|
|
}
|
|
|
|
if (count($errors) > 0) {
|
|
echo PHP_EOL . "ERRORS: -" . PHP_EOL;
|
|
echo implode(PHP_EOL, $errors) . PHP_EOL;
|
|
if ($send_notification) {
|
|
$notify_users = get_notification_users("SYSTEM_ADMIN");
|
|
foreach ($notify_users as $notify_user) {
|
|
$admin_notify_users[] = $notify_user["ref"];
|
|
}
|
|
$message = "STATICSYNC ERRORS FOUND: - " . PHP_EOL . implode(PHP_EOL, $errors);
|
|
message_add($admin_notify_users, $message);
|
|
}
|
|
}
|
|
|
|
echo "\nStaticSync completed at " . date('Y-m-d H:i:s', time()) . PHP_EOL;
|
|
|
|
if ($suppress_output) {
|
|
ob_clean();
|
|
}
|
|
|
|
ps_query("UPDATE sysvars SET value=now() WHERE name='lastsync'");
|
|
clear_query_cache("sysvars");
|
|
clear_process_lock("staticsync");
|