7615 lines
331 KiB
PHP
7615 lines
331 KiB
PHP
<?php
|
|
/**
|
|
* Functions used to render HTML & Javascript
|
|
*
|
|
*/
|
|
|
|
|
|
/**
|
|
* Renders the HTML for the provided $field for inclusion in a search form, for example the
|
|
* advanced search page. Standard field titles are translated using $lang. Custom field titles are i18n translated.
|
|
*
|
|
* $field the field being rendered as an associative array of field data, i.e. one row from the resource_type_field table.
|
|
* $fields the array of fields data, i.e. multiple rows from the resource_type_field table.
|
|
* $name the input name to use in the form (post name)
|
|
* $value the default value to set for this field, if any
|
|
* $reset is non-blank if the caller requires the field to be reset
|
|
* @param array $searched_nodes Array of all the searched nodes previously
|
|
*/
|
|
function render_search_field($field,$fields,$value="",$autoupdate=false,$class="stdwidth",$forsearchbar=false,$limit_keywords=array(),
|
|
$searched_nodes = array(), $reset="",$simpleSearchFieldsAreHidden=false)
|
|
{
|
|
node_field_options_override($field);
|
|
|
|
global $auto_order_checkbox, $auto_order_checkbox_case_insensitive, $lang, $category_tree_open, $minyear, $daterange_search, $searchbyday,
|
|
$is_search, $values, $n, $simple_search_show_dynamic_as_dropdown, $clear_function, $simple_search_display_condition, $autocomplete_search,
|
|
$baseurl, $fields, $baseurl_short, $extrafooterhtml,$FIXED_LIST_FIELD_TYPES, $maxyear_extends_current, $DATE_FIELD_TYPES;
|
|
|
|
# Certain edit_fields/x.php functions check for bulk edit which must be defined as false prior to rendering the search field
|
|
$multiple=false;
|
|
$field['ref'] = (int) $field['ref'];
|
|
?>
|
|
<!-- RENDERING FIELD=<?php echo $field['ref'] . " " . escape($field['name']);?> -->
|
|
<?php
|
|
|
|
// set this to zero since this does not apply to collections
|
|
if (!isset($field['field_constraint'])){$field['field_constraint']=0;}
|
|
|
|
$name="field_" . ($forsearchbar ? escape($field["name"]) : $field["ref"]);
|
|
$id="field_" . $field["ref"];
|
|
|
|
# An array of conditions spanning all governed fields and all governing fields
|
|
$scriptconditions=array();
|
|
|
|
# Assume the field being rendered should be displayed
|
|
$displaycondition=true;
|
|
|
|
# If the field being rendered has a display condition
|
|
# For advanced search, always check the display condition
|
|
# For simple search, only check the display condition if the field is included in the simple_search_display_condition config array
|
|
if ( $field["display_condition"]!=""
|
|
&& ( !$forsearchbar || ($forsearchbar && !empty($simple_search_display_condition) && in_array($field['ref'],$simple_search_display_condition)) ) )
|
|
{
|
|
# Split the display condition of the field being rendered into an array of tests (if there are more than one, they are separated by a ";")
|
|
# Each test is in the form governing field = governing field value
|
|
# If the field being rendered is itself a governing field then "On Change" code must be generated for the governing field
|
|
# If the field being rendered is a governed field then "Checking" code must be generated for each governing field
|
|
$s=explode(";",$field["display_condition"]);
|
|
$condref=0;
|
|
foreach ($s as $condition) # Check each individual test
|
|
{
|
|
# Assume that the current test does not need to be checked
|
|
$displayconditioncheck=false;
|
|
$s=explode("=",$condition);
|
|
|
|
# Process each field to see if it is being referenced in the current test
|
|
if (!is_array($fields))
|
|
{
|
|
return false;
|
|
}
|
|
for ($cf=0;$cf<count($fields);$cf++) # Check each field to see if it is a governing field whose value needs to be checked
|
|
{
|
|
# If the field being processed is referenced in the current test, then it is a governing field
|
|
if ($s[0]==$fields[$cf]["name"])
|
|
{
|
|
# The script conditions array contains an entry for each governing field
|
|
$scriptconditions[$condref]["field"] = $fields[$cf]["ref"]; # governing field
|
|
$scriptconditions[$condref]["governedfield"] = $field["ref"]; # governed field
|
|
|
|
$scriptconditions[$condref]["name"] = $fields[$cf]["name"];
|
|
$scriptconditions[$condref]['type'] = $fields[$cf]['type'];
|
|
$scriptconditions[$condref]['display_as_dropdown'] = $fields[$cf]['display_as_dropdown'];
|
|
# Get the node references of the governing field
|
|
$scriptconditionnodes = get_nodes($fields[$cf]['ref'], null, (FIELD_TYPE_CATEGORY_TREE == $fields[$cf]['type'] ? true : false));
|
|
|
|
$checkvalues=$s[1];
|
|
# Prepare an array of values present in the test
|
|
$validvalues=explode("|",strtoupper($checkvalues));
|
|
$validvalues = array_map("i18n_get_translated", $validvalues);
|
|
$scriptconditions[$condref]['valid'] = array();
|
|
$scriptconditions[$condref]['validtext'] = array();
|
|
foreach($validvalues as $validvalue)
|
|
{
|
|
# The validtext array is for checking input values instead of their corresponding node references
|
|
$scriptconditions[$condref]['validtext'][] = strtolower($validvalue);
|
|
|
|
# Convert the value name into a node entry if it is a valid node within the governing field
|
|
$found_validvalue = get_node_by_name($scriptconditionnodes, $validvalue);
|
|
|
|
# If there is a node which corresponds to that value name then append its node reference to a list of valid nodes
|
|
if(0 != count($found_validvalue))
|
|
{
|
|
$scriptconditions[$condref]['valid'][] = (string)$found_validvalue['ref'];
|
|
|
|
# Is the node present in search result list of nodes
|
|
if(in_array($found_validvalue['ref'],$searched_nodes))
|
|
{
|
|
# Value being tested is present in the searched nodes array
|
|
$displayconditioncheck = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
# Suppress this field if none of the nodes (of the values) in the test match the searched nodes array
|
|
if (!$displayconditioncheck)
|
|
{
|
|
$displaycondition=false; # Do not render field
|
|
}
|
|
|
|
|
|
// Certain fixed list types allow for multiple nodes to be passed at the same time
|
|
|
|
// Generate a javascript function specific to the field being rendered
|
|
// This function will be invoked whenever any governing field changes
|
|
if(in_array($fields[$cf]['type'], $FIXED_LIST_FIELD_TYPES))
|
|
{
|
|
if(FIELD_TYPE_CATEGORY_TREE == $fields[$cf]['type'])
|
|
{
|
|
?>
|
|
<!-- SETUP HANDLER FOR GOVERNOR=<?php echo $fields[$cf]['ref']; ?> GOVERNED=<?php echo $field['ref']; ?>-->
|
|
<script type="text/javascript">
|
|
var wto;
|
|
jQuery(document).ready(function()
|
|
{
|
|
jQuery('#<?php echo $forsearchbar ? "SearchBox" : "CentralSpace" ?>').on('categoryTreeChanged', function(e,node)
|
|
{
|
|
// Debounce multiple events fired by the category tree
|
|
clearTimeout(wto);
|
|
wto=setTimeout(function() {
|
|
// Reflect the change of the governing field into the following governed field condition checker
|
|
console.debug("<?php echo "DISPCOND CATTREE CHANGEGOVERNOR=".$fields[$cf]['ref']; ?>");
|
|
for (i = 0; i<categoryTreeChecksArray.length; i++) {
|
|
categoryTreeChecksArray[i]();
|
|
}
|
|
}, 200);
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
elseif(FIELD_TYPE_DYNAMIC_KEYWORDS_LIST == $fields[$cf]['type'])
|
|
{
|
|
if ($forsearchbar) {
|
|
if ($simple_search_show_dynamic_as_dropdown) {
|
|
$checkname = "nodes_searched[{$fields[$cf]['ref']}]";
|
|
$jquery_selector = "select[name=\"{$checkname}\"]";
|
|
}
|
|
else {
|
|
$jquery_selector = "input[name=\"field_{$fields[$cf]["name"]}\"]";
|
|
}
|
|
?>
|
|
<!-- SETUP HANDLER FOR GOVERNOR=<?php echo $fields[$cf]['ref']; ?> GOVERNED=<?php echo $field['ref']; ?>-->
|
|
<script type="text/javascript">
|
|
jQuery(document).ready(function()
|
|
{
|
|
jQuery('<?php echo $jquery_selector; ?>').change(function ()
|
|
{
|
|
// Reflect the change of the governing field into the following governed field condition checker
|
|
console.debug("<?php echo "DISPCOND DYNAMKKD CHANGEGOVERNOR=".$fields[$cf]['ref']." CHECK GOVERNED=".$field['ref']; ?>");
|
|
checkSearchDisplayCondition<?php echo $field['ref']; ?>();
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
else { # Advanced search
|
|
?>
|
|
<!-- SETUP HANDLER FOR GOVERNOR=<?php echo $fields[$cf]['ref']; ?> GOVERNED=<?php echo $field['ref']; ?>-->
|
|
<script type="text/javascript">
|
|
jQuery(document).ready(function()
|
|
{
|
|
jQuery('#CentralSpace').on('dynamicKeywordChanged', function(e,node)
|
|
{
|
|
// Reflect the change of the governing field into the following governed field condition checker
|
|
console.debug("<?php echo "DISPCOND DYNAMKWD CHANGEGOVERNOR=".$fields[$cf]['ref']." CHECK GOVERNED=".$field['ref']; ?>");
|
|
checkSearchDisplayCondition<?php echo $field['ref']; ?>();
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# Otherwise FIELD_TYPE_CHECK_BOX_LIST or FIELD_TYPE_DROP_DOWN_LIST or FIELD_TYPE_RADIO_BUTTONS
|
|
|
|
# Simple search will always display these types as dropdowns
|
|
if ($forsearchbar) {
|
|
$checkname = "nodes_searched[{$fields[$cf]['ref']}]";
|
|
$jquery_selector = "select[name=\"{$checkname}\"]";
|
|
}
|
|
# Advanced search will display these as dropdowns if marked as such, otherwise they are displayed as checkbox lists to allow OR selection
|
|
else {
|
|
# Prepare selector on the assumption that its an input element (ie. a checkbox list or a radio button or a dropdown displayed as checkbox list)
|
|
$checkname = "nodes_searched[{$fields[$cf]['ref']}][]";
|
|
$jquery_selector = "input[name=\"{$checkname}\"]";
|
|
|
|
# If however its a drop down list then we should be processing select elements
|
|
if ($fields[$cf]['display_as_dropdown'])
|
|
{
|
|
$checkname = "nodes_searched[{$fields[$cf]['ref']}]";
|
|
$jquery_selector = "select[name=\"{$checkname}\"]";
|
|
}
|
|
}
|
|
?>
|
|
<!-- SETUP HANDLER FOR GOVERNOR=<?php echo $fields[$cf]['ref']; ?> GOVERNED=<?php echo $field['ref']; ?>-->
|
|
<script type="text/javascript">
|
|
jQuery(document).ready(function()
|
|
{
|
|
jQuery('<?php echo $jquery_selector; ?>').change(function ()
|
|
{
|
|
// Reflect the change of the governing field into the following governed field condition checker
|
|
console.debug("<?php echo "DISPCOND CHANGEGOVERNOR=".$fields[$cf]['ref']." CHECK GOVERNED=".$field['ref']; ?>");
|
|
checkSearchDisplayCondition<?php echo $field['ref']; ?>();
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
}
|
|
else
|
|
{ # Not one of the FIXED_LIST_FIELD_TYPES
|
|
?>
|
|
<!-- SETUP HANDLER FOR GOVERNOR=<?php echo $fields[$cf]['ref']; ?> GOVERNED=<?php echo $field['ref']; ?>-->
|
|
<script type="text/javascript">
|
|
jQuery(document).ready(function()
|
|
{
|
|
jQuery('#field_<?php echo $fields[$cf]["ref"]; ?>').change(function ()
|
|
{
|
|
// Reflect the change of the governing field into the following governed field condition checker
|
|
checkSearchDisplayCondition<?php echo $field['ref']; ?>();
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
}
|
|
} # see if next field needs to be checked
|
|
|
|
$condref++;
|
|
} # check next condition
|
|
|
|
?>
|
|
<?php echo "<!-- CHECK CONDITIONS FOR GOVERNED FIELD ".$field['name']." [".$field['ref']."] -->";
|
|
$function_has_category_tree_check=false;
|
|
?>
|
|
<script type="text/javascript">
|
|
|
|
checkSearchDisplayCondition<?php echo $field["ref"];?> = function ()
|
|
{
|
|
// Is the governed field resource type ok; if not then no checking necessary as its already hidden
|
|
const conditionalquestion = document.getElementById("question_<?php echo $n ?>");
|
|
if (conditionalquestion != null && conditionalquestion.dataset?.resource_type_ok != "1") { return; }
|
|
|
|
// Check the node passed in from the changed governing field
|
|
var idname<?php echo $field['ref']; ?> = "<?php echo $forsearchbar?"#simplesearch_".$field['ref']:"#question_".$n; ?>";
|
|
var ixThisField;
|
|
// Get current display state for governed field ("block" or "none")
|
|
field<?php echo $field['ref']; ?>status = jQuery(idname<?php echo $field['ref']; ?>).css('display');
|
|
newfield<?php echo $field['ref']; ?>status = 'none';
|
|
|
|
// Assume visible by default
|
|
field<?php echo $field['ref']; ?>visibility = true;
|
|
|
|
<?php
|
|
foreach($scriptconditions as $scriptcondition)
|
|
{
|
|
echo "// Checking values on field ".$scriptcondition['field']."\n";
|
|
# Example of $scriptconditions: [{"field":"73","type":"3","display_as_dropdown":"0","valid":["267","266"]}]
|
|
if ($scriptcondition['type'] == FIELD_TYPE_CATEGORY_TREE) {
|
|
$function_has_category_tree_check=true;
|
|
}
|
|
?>
|
|
|
|
field<?php echo $field['ref']; ?>valuefound = false;
|
|
fieldokvalues<?php echo $scriptcondition['field']; ?> = <?php echo json_encode($scriptcondition['valid']); ?>;
|
|
|
|
<?php
|
|
if (
|
|
$scriptcondition['type'] == FIELD_TYPE_DYNAMIC_KEYWORDS_LIST
|
|
&& $forsearchbar
|
|
&& !$simple_search_show_dynamic_as_dropdown
|
|
) {
|
|
?>
|
|
// When a dynamic keyword list is rendered as regular input field on simple search, the valid values to check against are the text values (not nodes)
|
|
fieldokvalues<?php echo $scriptcondition['field']; ?> = <?php echo json_encode($scriptcondition['validtext']); ?>;
|
|
<?php
|
|
}
|
|
?>
|
|
|
|
<?php echo "// CHECK IF GOVERNING ".$scriptcondition['name']." [".$scriptcondition['field']."] VALUE(S) ENABLE DISPLAY";?>
|
|
|
|
<?php
|
|
|
|
# Generate the javascript code necessary to condition the rendered field based on value(s) present in the governing field
|
|
|
|
# Prepare base name for selector
|
|
$checkname = "nodes_searched[{$scriptcondition['field']}]";
|
|
$js_conditional_statement = "fieldokvalues{$scriptcondition['field']}.indexOf(element.value) != -1";
|
|
|
|
# Prepare fallback selector
|
|
$jquery_condition_selector = "input[name=\"{$checkname}\"]";
|
|
|
|
if(in_array($scriptcondition['type'], $FIXED_LIST_FIELD_TYPES))
|
|
{
|
|
# Append additional brackets rendered on category tree and dynamic keyword list hidden inputs
|
|
if (in_array($scriptcondition['type'], array(FIELD_TYPE_CATEGORY_TREE, FIELD_TYPE_DYNAMIC_KEYWORDS_LIST)) ) {
|
|
$jquery_condition_selector = "input[name=\"{$checkname}[]\"]";
|
|
}
|
|
|
|
# Prepare selector for a checkbox list or a radio button or a dropdown list
|
|
if (in_array($scriptcondition['type'], array(FIELD_TYPE_CHECK_BOX_LIST, FIELD_TYPE_RADIO_BUTTONS, FIELD_TYPE_DROP_DOWN_LIST))) {
|
|
|
|
# Simple search will always display these types as dropdowns, so search for selected option
|
|
if ($forsearchbar) {
|
|
$jquery_condition_selector = "select[name=\"{$checkname}\"] option:selected";
|
|
}
|
|
# Advanced search will display these as dropdowns if marked as such, otherwise they are displayed as checkbox lists to allow OR selection
|
|
else {
|
|
# Prepare selector on the assumption that its an input element (ie. a checkbox list or a radio button or a dropdown displayed as checkbox list)
|
|
# so search for checked boxes
|
|
$jquery_condition_selector = "input[name=\"{$checkname}[]\"]:checked:enabled";
|
|
|
|
# If however its a drop down list then we should be searching for selected option
|
|
if ($scriptcondition['display_as_dropdown'])
|
|
{
|
|
$jquery_condition_selector = "select[name=\"{$checkname}\"] option:selected";
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
# Prepare selector for unusual dynamic keyword list configurations
|
|
if (
|
|
$scriptcondition['type'] == FIELD_TYPE_DYNAMIC_KEYWORDS_LIST
|
|
&& $forsearchbar
|
|
) {
|
|
if($simple_search_show_dynamic_as_dropdown) {
|
|
# Prepare selector for a dynamic keyword list configured to display as a dropdown list on simple search
|
|
$jquery_condition_selector = "select[name=\"{$checkname}\"] option:selected";
|
|
} else {
|
|
# Prepare selector for a dynamic keyword list rendered as regular input field
|
|
$jquery_condition_selector = "input[name=\"field_{$scriptcondition['name']}\"]";
|
|
}
|
|
}
|
|
|
|
?>
|
|
jQuery('<?php echo $jquery_condition_selector; ?>').each(function(index, element)
|
|
{
|
|
if(<?php echo $js_conditional_statement; ?>)
|
|
{
|
|
// The governing node is in the list of qualifying node(s) which enable this governed field
|
|
field<?php echo $field['ref']; ?>valuefound = true;
|
|
}
|
|
});
|
|
|
|
<?php
|
|
}?>
|
|
|
|
// If no governing node found then disable this governed field
|
|
if(!field<?php echo $field['ref']; ?>valuefound)
|
|
{
|
|
field<?php echo $field['ref']; ?>visibility = false;
|
|
}
|
|
|
|
<?php
|
|
echo "// End of checking values on field ".$scriptcondition['field']."\n\n ";
|
|
}
|
|
?>
|
|
|
|
// If not yet defined, initialise an array of governed fields to be hidden when resetting simple search
|
|
if(typeof fieldsToHideOnClear == "undefined")
|
|
{
|
|
fieldsToHideOnClear = new Array();
|
|
}
|
|
|
|
// If the governed field is enabled then set it to display
|
|
if(field<?php echo $field['ref']; ?>visibility)
|
|
{
|
|
newfield<?php echo $field['ref']; ?>status = 'block';
|
|
// This governed field will be shown, so remove it from array of fields to hide when resetting simple search
|
|
ixThisField = fieldsToHideOnClear.indexOf('<?php echo $field["ref"]; ?>');
|
|
fieldsToHideOnClear.splice(ixThisField,1);
|
|
}
|
|
else
|
|
{
|
|
// This governed field will be hidden, so add it to array of fields to hide when resetting simple search
|
|
ixThisField = fieldsToHideOnClear.indexOf('<?php echo $field["ref"]; ?>');
|
|
if (ixThisField < 0)
|
|
{
|
|
fieldsToHideOnClear.push('<?php echo $field["ref"]; ?>');
|
|
}
|
|
}
|
|
|
|
// If the governed field display state has changed then enact the change by sliding
|
|
if ( newfield<?php echo $field['ref']; ?>status != field<?php echo $field['ref']; ?>status )
|
|
{
|
|
console.debug("IDNAME " + idname<?php echo $field['ref']; ?>);
|
|
console.debug(" FIELD <?php echo $field['ref']; ?> STATUS '" + field<?php echo $field['ref']; ?>status+"'");
|
|
console.debug("NEWFIELD <?php echo $field['ref']; ?> STATUS '" + newfield<?php echo $field['ref']; ?>status+"'");
|
|
// Toggle the display state between "block" and "none", clearing any incomplete actions in the process
|
|
jQuery(idname<?php echo $field['ref']; ?>).slideToggle(function()
|
|
{
|
|
console.debug("SLIDETOGGLE FIELD <?php echo $field['ref']; ?>");
|
|
jQuery(this).clearQueue();
|
|
|
|
// If field is being made visible, check if section is visible and trigger the parent slide if not
|
|
if(newfield<?php echo $field['ref']; ?>status == 'block' && jQuery(this).parent().css('display') == 'none') {
|
|
jQuery(this).parent().prev('h1').click();
|
|
}
|
|
<?php
|
|
if ($forsearchbar) {
|
|
if ($field['type'] == FIELD_TYPE_CATEGORY_TREE) { ?>
|
|
jQuery('.search_tree_<?php echo $field['ref']; ?>_nodes').each(function(i, element){
|
|
jQuery('#'+element.value+'_anchor').click();
|
|
});
|
|
<?php } elseif (in_array($field['type'], $DATE_FIELD_TYPES)) { ?>
|
|
jQuery('#field_<?php echo $field['ref']; ?>-y').val('');
|
|
jQuery('#field_<?php echo $field['ref']; ?>-m').val('');
|
|
jQuery('#field_<?php echo $field['ref']; ?>-d').val('');
|
|
<?php } else { ?>
|
|
jQuery(idname<?php echo $field['ref']; ?> + ' #field_<?php echo $field['ref']; ?>').val('');
|
|
<?php
|
|
}
|
|
} ?>
|
|
});
|
|
|
|
// Adjust the border accordingly
|
|
if(jQuery(idname<?php echo $field['ref']; ?>).css('display') == 'block')
|
|
{
|
|
jQuery(idname<?php echo $field['ref']; ?>).css('border-top', '');
|
|
}
|
|
else
|
|
{
|
|
jQuery(idname<?php echo $field['ref']; ?>).css('border-top', 'none');
|
|
}
|
|
}
|
|
}
|
|
|
|
<?php
|
|
if ($function_has_category_tree_check) {
|
|
?>
|
|
categoryTreeChecksArray.push(checkSearchDisplayCondition<?php echo $field["ref"];?>);
|
|
<?php
|
|
}
|
|
?>
|
|
|
|
</script>
|
|
<?php
|
|
if($forsearchbar)
|
|
{
|
|
// add the display condition check to the clear function
|
|
$clear_function.="checkSearchDisplayCondition".$field['ref']."();";
|
|
}
|
|
|
|
} // Endif rendered field with a display condition
|
|
|
|
$is_search = true;
|
|
|
|
if (!$forsearchbar)
|
|
{
|
|
?>
|
|
<div class="Question ConditionalVisibility" data-resource_type_ok="" data-for_resource_types="<?php
|
|
// Add class for each supported resource type to allow showing/hiding on advanced search
|
|
if($field["resource_types"] == "Collections")
|
|
{
|
|
echo "Collections";
|
|
}
|
|
elseif($field["global"] == 1)
|
|
{
|
|
echo "Global";
|
|
}
|
|
else
|
|
{
|
|
echo (string)$field["resource_types"];
|
|
}
|
|
?>" id="question_<?php echo $n ?>" data-has_display_condition="<?php echo !$displaycondition ? '1' : '0'; ?>" data-question_field_ref="<?php echo $field['ref']; ?>"<?php
|
|
if (strlen((string) $field["tooltip_text"])>=1)
|
|
{
|
|
echo "title=\"" . escape(lang_or_i18n_get_translated($field["tooltip_text"], "fieldtooltip-")) . "\"";
|
|
}
|
|
?>>
|
|
<label><?php echo escape(lang_or_i18n_get_translated($field["title"], "fieldtitle-")) ?></label>
|
|
<?php
|
|
}
|
|
else
|
|
{
|
|
hook("modifysearchfieldtitle");
|
|
?>
|
|
<div class="SearchItem" id="simplesearch_<?php echo $field["ref"]; ?>" <?php if (!$displaycondition || $simpleSearchFieldsAreHidden) {?>style="display:none;"<?php } if (strlen($field["tooltip_text"] ?? "" ) >= 1){ echo "title=\"" . escape(lang_or_i18n_get_translated($field["tooltip_text"], "fieldtooltip-")) . "\"";} ?> ><label for="simplesearch_<?php echo $field["ref"]; ?>"><?php echo escape(lang_or_i18n_get_translated($field["title"], "fieldtitle-")) ?></label><br/>
|
|
|
|
<?php
|
|
#hook to modify field type in special case. Returning zero (to get a standard text box) doesn't work, so return 1 for type 0, 2 for type 1, etc.
|
|
if(hook("modifyfieldtype")){$fields[$n]["type"]=hook("modifyfieldtype")-1;}
|
|
}
|
|
|
|
# Generate markup for field
|
|
switch ($field["type"]) {
|
|
case FIELD_TYPE_TEXT_BOX_SINGLE_LINE:
|
|
case FIELD_TYPE_TEXT_BOX_MULTI_LINE:
|
|
case FIELD_TYPE_TEXT_BOX_LARGE_MULTI_LINE:
|
|
case FIELD_TYPE_TEXT_BOX_FORMATTED_AND_TINYMCE:
|
|
case $forsearchbar && $field["type"]==FIELD_TYPE_DYNAMIC_KEYWORDS_LIST && !$simple_search_show_dynamic_as_dropdown:
|
|
case FIELD_TYPE_WARNING_MESSAGE:
|
|
# Dynamic keyword list behaviour replaced with regular input field under these circumstances
|
|
if ((int)$field['field_constraint']==0)
|
|
{
|
|
?><input class="<?php echo escape($class) ?>" type=text name="<?php echo escape($name) ?>" id="<?php echo escape($id) ?>" value="<?php echo escape((string)$value)?>" <?php if ($autoupdate) { ?>onChange="UpdateResultCount();"<?php } if(!$forsearchbar){ ?> onKeyPress="if (!(updating)) {setTimeout('UpdateResultCount()',2000);updating=true;}"<?php } if($forsearchbar){?>onKeyUp="if('' != jQuery(this).val()){FilterBasicSearchOptions('<?php echo escape((string)$field["name"]) ?>',[<?php echo escape((string)$field["resource_types"]) ?>]);}"<?php } ?>><?php
|
|
# Add to the clear function so clicking 'clear' clears this box.
|
|
$clear_function.="document.getElementById('field_" . ($forsearchbar? $field["ref"] : escape((string)$field["name"])) . "').value='';";
|
|
}
|
|
// number view - manipulate the form value (don't send these but send a compiled numrange value instead
|
|
elseif ((int)$field['field_constraint']==1)
|
|
{
|
|
// parse value for to/from simple search
|
|
$minmax=explode('|',str_replace("numrange","",$value));
|
|
($minmax[0]=='')?$minvalue='':$minvalue=str_replace("neg","-",$minmax[0]);
|
|
(isset($minmax[1]))?$maxvalue=str_replace("neg","-",$minmax[1]):$maxvalue='';
|
|
echo escape($lang["from"]); ?><input id="<?php echo escape($name) ?>_min" onChange="jQuery('#<?php echo escape($name) ?>').val('numrange'+jQuery(this).val().replace('-','neg')+'|'+jQuery('#<?php echo escape($name) ?>_max').val().replace('-','neg'));" class="NumberSearchWidth" type="number" value="<?php echo escape($minvalue)?>"><?php echo escape($lang["to"]); ?><input id="<?php echo escape($name) ?>_max" onChange="jQuery('#<?php echo escape($name) ?>').val('numrange'+jQuery('#<?php echo escape($name) ?>_min').val().replace('-','neg')+'|'+jQuery(this).val().replace('-','neg'));" class="NumberSearchWidth" type="number" value="<?php echo escape($maxvalue)?>">
|
|
<input id="<?php echo escape($name) ?>" name="<?php echo escape($name) ?>" type="hidden" value="<?php echo escape($value) ?>">
|
|
<?php
|
|
# Add to the clear function so clicking 'clear' clears this box.
|
|
$clear_function.="document.getElementById('".$name."_max').value='';";
|
|
$clear_function.="document.getElementById('".$name."_min').value='';";
|
|
$clear_function.="document.getElementById('".$name."').value='';";
|
|
}
|
|
|
|
|
|
|
|
if ($forsearchbar && $autocomplete_search) {
|
|
# Auto-complete search functionality
|
|
?></div>
|
|
<script type="text/javascript">
|
|
|
|
jQuery(document).ready(function () {
|
|
|
|
jQuery("#field_<?php echo escape($field["ref"])?>").autocomplete( { source: "<?php echo $baseurl?>/pages/ajax/autocomplete_search.php?field=<?php echo escape($field["name"]) ?>&fieldref=<?php echo escape($field["ref"]) ?>"} );
|
|
})
|
|
|
|
</script>
|
|
<div class="SearchItem">
|
|
<?php }
|
|
|
|
break;
|
|
|
|
case FIELD_TYPE_CHECK_BOX_LIST:
|
|
case FIELD_TYPE_DROP_DOWN_LIST:
|
|
case $forsearchbar && $field["type"]==FIELD_TYPE_DYNAMIC_KEYWORDS_LIST && $simple_search_show_dynamic_as_dropdown:
|
|
if(!hook("customchkboxes", "", array($field, $value, $autoupdate, $class, $forsearchbar, $limit_keywords)))
|
|
{
|
|
global $checkbox_ordered_vertically;
|
|
|
|
# -------- Show a check list or dropdown for dropdowns and check lists?
|
|
# By default show a checkbox list for both (for multiple selections this enabled OR functionality)
|
|
|
|
# Translate all options
|
|
$adjusted_dropdownoptions=hook("adjustdropdownoptions");
|
|
if ($adjusted_dropdownoptions){$options=$adjusted_dropdownoptions;}
|
|
|
|
$node_options = array_column($field["node_options"], "name");
|
|
|
|
if((bool) $field['automatic_nodes_ordering'])
|
|
{
|
|
$field['node_options'] = reorder_nodes($field['node_options']);
|
|
}
|
|
|
|
$order_by_resetter = 0;
|
|
foreach($field['node_options'] as $node_index => $node)
|
|
{
|
|
// Special case for vertically ordered checkboxes.
|
|
// Order by needs to be reset as per the new order so that we can reshuffle them using the order by as a reference
|
|
if($checkbox_ordered_vertically)
|
|
{
|
|
$field['node_options'][$node_index]['order_by'] = $order_by_resetter++;
|
|
}
|
|
}
|
|
|
|
if ($field["display_as_dropdown"] || $forsearchbar)
|
|
{
|
|
# Show as a dropdown box
|
|
$name = "nodes_searched[{$field['ref']}]";
|
|
?>
|
|
<select class="<?php echo escape($class) ?>" name="<?php echo escape($name) ?>" id="<?php echo escape($id) ?>"
|
|
<?php if ($autoupdate) { ?>onChange="UpdateResultCount();"<?php }
|
|
if($forsearchbar){ ?>onChange="FilterBasicSearchOptions('<?php echo escape($field["name"]) ?>',<?php echo escape(($field["global"] == 1 ? "[0]" : "[" . escape((string)$field["resource_types"]) . "]")) ?>);" <?php } ?>>
|
|
<option value=""></option>
|
|
<?php
|
|
foreach($field['node_options'] as $node)
|
|
{
|
|
if('' != trim($node['name']))
|
|
{
|
|
?>
|
|
<option value="<?php echo escape(trim($node['ref'])); ?>" <?php if (0 < count($searched_nodes) && in_array($node['ref'], $searched_nodes)) { ?>selected<?php } ?>><?php echo escape(trim(i18n_get_translated($node['name']))); ?></option>
|
|
<?php
|
|
}
|
|
}
|
|
?></select><?php
|
|
if($forsearchbar)
|
|
{
|
|
// Add to the clear function so clicking 'clear' clears this box.
|
|
$clear_function .= "document.getElementById('{$id}').selectedIndex = -1;";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# Show as a checkbox list (default)
|
|
$setnames=trim_array(explode(";",$value));
|
|
$wrap=0;
|
|
|
|
$l = average_length($node_options);
|
|
switch($l)
|
|
{
|
|
case $l > 40: $cols = 1; break;
|
|
case $l > 25: $cols = 2; break;
|
|
case $l > 15: $cols = 3; break;
|
|
case $l > 10: $cols = 4; break;
|
|
case $l > 5: $cols = 5; break;
|
|
default: $cols = 10;
|
|
}
|
|
|
|
$height = ceil(count($field['node_options']) / $cols);
|
|
|
|
global $checkbox_ordered_vertically, $checkbox_vertical_columns;
|
|
if($checkbox_ordered_vertically)
|
|
{
|
|
if(!hook('rendersearchchkboxes'))
|
|
{
|
|
# ---------------- Vertical Ordering (only if configured) -----------
|
|
?>
|
|
<table cellpadding=4 cellspacing=0>
|
|
<tbody>
|
|
<tr>
|
|
<?php
|
|
for($i = 0; $i < $height; $i++)
|
|
{
|
|
for($j = 0; $j < $cols; $j++)
|
|
{
|
|
$order_by = ($height * $j) + $i;
|
|
|
|
$node_index_to_be_reshuffled = array_search($order_by, array_column($field['node_options'], 'order_by', 'ref'));
|
|
|
|
if(false === $node_index_to_be_reshuffled)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
$node = $field['node_options'][$node_index_to_be_reshuffled];
|
|
?>
|
|
<td valign=middle>
|
|
<input id="nodes_searched_<?php echo $node['ref']; ?>" class="nodes_input_checkbox" type="checkbox" name="nodes_searched[<?php echo $field['ref']; ?>][]" value="<?php echo $node['ref']; ?>" <?php if((0 < count($searched_nodes) && in_array($node['ref'], $searched_nodes)) || in_array(i18n_get_translated($node['name']),$setnames)) { ?>checked<?php } ?> <?php if($autoupdate) { ?>onClick="UpdateResultCount();"<?php } ?>>
|
|
<label class="customFieldLabel" for="nodes_searched_<?php echo $node['ref']; ?>">
|
|
<?php echo escape(i18n_get_translated($node['name'])); ?>
|
|
</label>
|
|
</td>
|
|
<?php
|
|
}
|
|
?>
|
|
</tr>
|
|
<tr>
|
|
<?php
|
|
}
|
|
?>
|
|
</tbody>
|
|
</table>
|
|
<?php
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# ---------------- Horizontal Ordering (Standard) ---------------------
|
|
?>
|
|
<table cellpadding=4 cellspacing=0>
|
|
<tr>
|
|
<?php
|
|
foreach($field['node_options'] as $node)
|
|
{
|
|
$wrap++;
|
|
|
|
if($wrap > $cols)
|
|
{
|
|
$wrap = 1;
|
|
?>
|
|
</tr>
|
|
<tr>
|
|
<?php
|
|
}
|
|
|
|
if('' != $node['name'])
|
|
{
|
|
?>
|
|
<td valign=middle>
|
|
<input id="nodes_searched_<?php echo $node['ref']; ?>" class="nodes_input_checkbox" type="checkbox" name="nodes_searched[<?php echo $field['ref']; ?>][]" value="<?php echo $node['ref']; ?>" <?php if ((0 < count($searched_nodes) && in_array($node['ref'], $searched_nodes)) || in_array(i18n_get_translated($node['name']),$setnames)) {?>checked<?php } ?> <?php if ($autoupdate) { ?>onClick="UpdateResultCount();"<?php } ?>>
|
|
<label class="customFieldLabel" for="nodes_searched_<?php echo $node['ref']; ?>">
|
|
<?php echo escape(i18n_get_translated($node['name'])); ?>
|
|
</label>
|
|
</td>
|
|
<?php
|
|
}
|
|
}
|
|
?>
|
|
</tr>
|
|
</table>
|
|
<?php
|
|
}
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FIELD_TYPE_DATE_AND_OPTIONAL_TIME:
|
|
case FIELD_TYPE_EXPIRY_DATE:
|
|
case FIELD_TYPE_DATE:
|
|
case FIELD_TYPE_DATE_RANGE:
|
|
$found_year='';$found_month='';$found_day='';$found_start_year='';$found_start_month='';$found_start_day='';$found_end_year='';$found_end_month='';$found_end_day='';
|
|
if (!$forsearchbar && $daterange_search)
|
|
{
|
|
render_date_range_field($name, $value, true, $autoupdate, array(), $reset);
|
|
}
|
|
else
|
|
{
|
|
$s=explode("|",$value);
|
|
if(is_array($s))
|
|
{
|
|
$found_year = $s[0];
|
|
$found_month = (array_key_exists(1, $s)) ? $s[1] : '';
|
|
$found_day = (array_key_exists(2, $s)) ? $s[2] : '';
|
|
}
|
|
?>
|
|
<select name="<?php echo escape($name);?>-y" id="<?php echo $id?>-y" class="SearchWidth<?php if ($forsearchbar){ echo "Half";} ?>" style="width:120px;" <?php if ($autoupdate) { ?>onChange="UpdateResultCount();"<?php } ?>>
|
|
<option value=""><?php echo escape($lang["anyyear"])?></option>
|
|
<?php
|
|
$y=date("Y");
|
|
$y += $maxyear_extends_current;
|
|
for ($d=$y;$d>=$minyear;$d--)
|
|
{
|
|
?><option <?php if ($d==$found_year) { ?>selected<?php } ?>><?php echo $d?></option><?php
|
|
}
|
|
?>
|
|
</select>
|
|
|
|
<?php if ($forsearchbar && $searchbyday) { ?><br /><?php } ?>
|
|
|
|
<select name="<?php echo escape($name);?>-m" id="<?php echo $id?>-m" class="SearchWidth<?php if ($forsearchbar){ echo "Half SearchWidthRight";} ?>" style="width:120px;" <?php if ($autoupdate) { ?>onChange="UpdateResultCount();"<?php } ?>>
|
|
<option value=""><?php echo escape($lang["anymonth"])?></option>
|
|
<?php
|
|
for ($d=1;$d<=12;$d++)
|
|
{
|
|
$m=str_pad($d,2,"0",STR_PAD_LEFT);
|
|
?><option <?php if ($d==$found_month) { ?>selected<?php } ?> value="<?php echo $m?>"><?php echo escape($lang["months"][$d-1])?></option><?php
|
|
}
|
|
?>
|
|
</select>
|
|
|
|
<?php if (!$forsearchbar || ($forsearchbar && $searchbyday))
|
|
{
|
|
?>
|
|
<select name="<?php echo escape($name);?>-d" id="<?php echo $id?>-d" class="SearchWidth<?php if ($forsearchbar){ echo "Half";} ?>" style="width:120px;" <?php if ($autoupdate) { ?>onChange="UpdateResultCount();"<?php } ?>>
|
|
<option value=""><?php echo escape($lang["anyday"])?></option>
|
|
<?php
|
|
for ($d=1;$d<=31;$d++)
|
|
{
|
|
$m=str_pad($d,2,"0",STR_PAD_LEFT);
|
|
?><option <?php if ($d==$found_day) { ?>selected<?php } ?> value="<?php echo $m?>"><?php echo $m?></option><?php
|
|
}
|
|
?>
|
|
</select>
|
|
<?php
|
|
}
|
|
if($forsearchbar)
|
|
{
|
|
# Add to the clear function so clicking 'clear' clears this box.
|
|
$clear_function.="
|
|
document.getElementById('field_" . $field["ref"] . "-y').selectedIndex=0;
|
|
document.getElementById('field_" . $field["ref"] . "-m').selectedIndex=0;
|
|
";
|
|
if($searchbyday)
|
|
{
|
|
$clear_function.="document.getElementById('field_" . $field["ref"] . "-d').selectedIndex=0;";
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case FIELD_TYPE_CATEGORY_TREE:
|
|
global $category_tree_add_parents, $category_tree_search_use_and;
|
|
|
|
$set = preg_split('/[;\|]/', cleanse_string($value, true));
|
|
$name = "nodes_searched[{$field['ref']}][]";
|
|
|
|
/*
|
|
For search, category trees work slightly different than the intended behaviour shown in edit_fields/7.php:
|
|
Intended behaviour:
|
|
1. Selecting a sub (child) node will automatically select all parent nodes up to and including the root level,
|
|
unless the option $category_tree_add_parents is set to false
|
|
|
|
On search this should work like this:
|
|
Selecting a sub (child) node will NOT select all parent nodes unless the system is configured to search using AND
|
|
*/
|
|
$category_tree_add_parents = $category_tree_search_use_and;
|
|
|
|
if($forsearchbar)
|
|
{
|
|
$original_category_tree_open = $category_tree_open;
|
|
$category_tree_open = true;
|
|
$treeonly = true;
|
|
$status_box_elements = '';
|
|
|
|
?>
|
|
<script type="text/javascript">
|
|
jQuery(document).ready(function()
|
|
{
|
|
jQuery('#SearchBox').on('categoryTreeChanged', function(e,node)
|
|
{
|
|
FilterBasicSearchOptions('<?php echo escape($field["name"]) ?>',[<?php echo escape((string)$field["resource_types"]) ?>]);
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
|
|
foreach($searched_nodes as $node)
|
|
{
|
|
$n_details = array();
|
|
|
|
if(get_node($node, $n_details)===false)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if($n_details["resource_type_field"] != $field["ref"])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Show previously searched options on the status box
|
|
$status_box_elements .= "
|
|
<div id=\"tree_{$field['ref']}_selected_{$n_details['ref']}\" class=\"tree_{$field['ref']}_options_status\">
|
|
<span id=\"nodes_searched_{$field['ref']}_statusbox_option_{$n_details['ref']}\">{$n_details['name']}</span><br />
|
|
</div>";
|
|
}
|
|
?>
|
|
<div id="field_<?php echo escape($field['name']); ?>">
|
|
<div id="nodes_searched_<?php echo $field['ref']; ?>_statusbox" class="MiniCategoryBox">
|
|
<?php echo $status_box_elements; ?>
|
|
</div>
|
|
<a href="#"
|
|
onClick="
|
|
jQuery('#cattree_<?php echo $field['name']; ?>').slideToggle();
|
|
|
|
return false;"><?php echo escape($lang['showhidetree']); ?></a>
|
|
<div id="cattree_<?php echo $field['name']; ?>" class="RecordPanel PopupCategoryTree">
|
|
<?php
|
|
include __DIR__ . '/../pages/edit_fields/7.php';
|
|
|
|
// Reset category_tree_open because normally searchbar occurs before edit/ advanced search page
|
|
$category_tree_open = $original_category_tree_open;
|
|
?>
|
|
</div>
|
|
|
|
</div>
|
|
<?php
|
|
# Add to clear function
|
|
$clear_function .= "
|
|
jQuery('#search_tree_{$field['ref']}').jstree({
|
|
'core' : {
|
|
'themes' : {
|
|
'name' : 'default-dark',
|
|
'icons': false
|
|
}
|
|
}
|
|
}).deselect_all();
|
|
|
|
/* remove the hidden inputs */
|
|
var elements = document.getElementsByName('nodes_searched[{$field['ref']}][]');
|
|
while(elements[0])
|
|
{
|
|
elements[0].parentNode.removeChild(elements[0]);
|
|
}
|
|
|
|
/* update status box */
|
|
var node_statusbox = document.getElementById('nodes_searched_{$field['ref']}_statusbox');
|
|
while(node_statusbox.lastChild)
|
|
{
|
|
node_statusbox.removeChild(node_statusbox.lastChild);
|
|
}
|
|
";
|
|
}
|
|
else
|
|
{
|
|
# For advanced search and elsewhere, include the category tree.
|
|
include __DIR__ . "/../pages/edit_fields/7.php";
|
|
}
|
|
break;
|
|
|
|
case FIELD_TYPE_DYNAMIC_KEYWORDS_LIST:
|
|
include __DIR__ . '/../pages/edit_fields/9.php';
|
|
break;
|
|
|
|
case FIELD_TYPE_RADIO_BUTTONS:
|
|
// auto save is not needed when searching
|
|
$edit_autosave = false;
|
|
$display_as_radiobuttons = false;
|
|
$display_as_checkbox = true;
|
|
$name = "nodes_searched[{$field['ref']}][]";
|
|
|
|
if($forsearchbar || $field['display_as_dropdown'])
|
|
{
|
|
$display_as_dropdown = true;
|
|
$display_as_checkbox = false;
|
|
$name = "nodes_searched[{$field['ref']}]";
|
|
|
|
$clear_function .= "document.getElementsByName('{$name}')[0].selectedIndex = -1;";
|
|
}
|
|
|
|
include __DIR__ . '/../pages/edit_fields/12.php';
|
|
// need to adjust the field's name value
|
|
?>
|
|
<script type="text/javascript">
|
|
jQuery("#field_<?php echo $field['ref']; ?>").attr('name', 'field_<?php echo $field["name"]; ?>');
|
|
</script>
|
|
<?php
|
|
break;
|
|
} ## END CASE
|
|
?>
|
|
<div class="clearerleft"> </div>
|
|
</div>
|
|
<!-- ************************************************ -->
|
|
<?php
|
|
} # End of render_search_field
|
|
|
|
/**
|
|
* Renders sort order functionality as a dropdown box
|
|
*
|
|
*/
|
|
function render_sort_order(array $order_fields,$default_sort_order)
|
|
{
|
|
global $order_by, $baseurl_short, $lang, $search, $archive, $restypes, $k, $sort, $date_field;
|
|
|
|
// use query strings here as this is used to render elements and sometimes it
|
|
// can depend on other params
|
|
$modal = ('true' == getval('modal', ''));
|
|
$access = getval('access', '');
|
|
$sort = validate_sort_value($sort) ? mb_strtoupper($sort) : 'DESC';
|
|
?>
|
|
<select id="sort_order_selection" onChange="UpdateResultOrder();" aria-label="<?php echo escape($lang["sortorder"]) ?>">
|
|
|
|
<?php
|
|
$options = '';
|
|
foreach($order_fields as $name => $label)
|
|
{
|
|
// date shows as 'field'.$date_field rather than 'date' for collection searches so let's fix it
|
|
if($name=='field'.$date_field)
|
|
{
|
|
$name='date';
|
|
}
|
|
|
|
// Are we constructing the option for the default order (ie. the first entry in the order_fields array)
|
|
$current_is_default = ($name == $default_sort_order);
|
|
|
|
// Is the currently set order that of the current field
|
|
$selected = ($order_by == $name || ($name=='date' && $order_by=='field'.$date_field));
|
|
|
|
// Build the option:
|
|
$option = '<option value="' . $name . '"';
|
|
|
|
// Set selection attribute if necessary
|
|
if(($selected && $current_is_default) || $selected)
|
|
{
|
|
$option .= ' selected';
|
|
}
|
|
|
|
$option .= sprintf('
|
|
data-url="%spages/search.php?search=%s&order_by=%s&archive=%s&k=%s&restypes=%s&access=%s"
|
|
',
|
|
$baseurl_short,
|
|
urlencode($search),
|
|
$name,
|
|
urlencode($archive),
|
|
urlencode($k),
|
|
urlencode($restypes),
|
|
urlencode($access)
|
|
);
|
|
|
|
$option .= '>';
|
|
$option .= $label;
|
|
$option .= '</option>';
|
|
|
|
// Add option to the options list
|
|
$options .= $option;
|
|
}
|
|
|
|
hook('render_sort_order_add_option', '', array($options));
|
|
echo $options;
|
|
?>
|
|
</select>
|
|
|
|
<a href="#" class="update_result_order_button" onClick="UpdateResultOrder(true);" aria-label="<?php echo escape($sort === "ASC" ? $lang['sortorder-asc'] : $lang['sortorder-desc']) ?>">
|
|
<i id="sort_selection_toggle" class="fa fa-sort-amount-<?php echo mb_strtolower($sort); ?>"></i>
|
|
</a>
|
|
|
|
<script>
|
|
function UpdateResultOrder(toggle_order)
|
|
{
|
|
var selected_option = jQuery('#sort_order_selection :selected');
|
|
var option_url = selected_option.data('url');
|
|
var sort_by = jQuery('#sort_order_selection').find(":selected").val();
|
|
|
|
if (toggle_order)
|
|
{
|
|
var selected_sort_option='<?php echo $sort == 'ASC' ? 'DESC' : 'ASC'; ?>';
|
|
}
|
|
else
|
|
{
|
|
if(sort_by == 'resourcetype' || sort_by == 'collection')
|
|
{
|
|
// The default sort should be ascending when sorting by resource type
|
|
var selected_sort_option = 'ASC';
|
|
}
|
|
else
|
|
{
|
|
var selected_sort_option = 'DESC';
|
|
}
|
|
}
|
|
option_url += '&sort=' + selected_sort_option;
|
|
<?php echo $modal ? 'Modal' : 'CentralSpace'; ?>Load(option_url);
|
|
}
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Renders a dropdown option
|
|
*
|
|
*/
|
|
function render_dropdown_option($value, $label, array $data_attr = array(), $extra_tag_attributes = '')
|
|
{
|
|
$result = '<option value="' . escape($value) . '"';
|
|
|
|
// Add any extra tag attributes
|
|
if(trim($extra_tag_attributes) !== '')
|
|
{
|
|
$result .= ' ' . $extra_tag_attributes;
|
|
}
|
|
|
|
// Add any data attributes you may need
|
|
foreach($data_attr as $data_attr_key => $data_attr_value)
|
|
{
|
|
$data_attr_key = str_replace(' ', '_', $data_attr_key);
|
|
|
|
$result .= ' data-' . $data_attr_key . '="' . $data_attr_value . '"';
|
|
}
|
|
|
|
$result .= '>' . escape($label) . '</option>';
|
|
|
|
return $result;
|
|
}
|
|
|
|
|
|
/**
|
|
* Renders search actions functionality as a dropdown box
|
|
*
|
|
* @param array $collection_data Collection data
|
|
* @param boolean $top_actions Set to true if actions are to be rendered in the search filter bar (above results)
|
|
* @param boolean $two_line Display on two lines
|
|
* @param string $id Selector HTML ID
|
|
* @param array $resource_data Resource data
|
|
* @param boolean $optionsonly Render only options
|
|
* @param string $forpage Specifically target for which page actions apply
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_actions(array $collection_data, $top_actions = true, $two_line = true, $id = '',$resource_data=array(),$optionsonly=false, $forpage="")
|
|
{
|
|
if(hook('prevent_running_render_actions'))
|
|
{
|
|
return;
|
|
}
|
|
|
|
global $baseurl, $lang, $k, $pagename, $order_by, $sort, $USER_SELECTION_COLLECTION;
|
|
|
|
$is_selection_collection = isset($collection_data['ref']) && $collection_data['ref'] == $USER_SELECTION_COLLECTION;
|
|
|
|
// globals that could also be passed as a reference
|
|
global $result /*search result*/;
|
|
|
|
$action_selection_id = ($forpage!=""?$forpage:$pagename) . '_action_selection' . $id;
|
|
if(!$top_actions)
|
|
{
|
|
$action_selection_id .= '_bottom';
|
|
}
|
|
if(isset($collection_data['ref']))
|
|
{
|
|
$action_selection_id .= '_' . str_replace("-","_",$collection_data['ref']);
|
|
}
|
|
|
|
|
|
if(!$optionsonly)
|
|
{?>
|
|
|
|
<div class="ActionsContainer <?php if($top_actions) { echo 'InpageNavLeftBlock'; } ?>"
|
|
data-actions-loaded="<?php echo (int) $is_selection_collection; ?>"
|
|
>
|
|
<?php
|
|
|
|
if($two_line)
|
|
{
|
|
?>
|
|
<br />
|
|
<?php
|
|
}
|
|
?>
|
|
<select onchange="action_onchange_<?php echo escape($action_selection_id); ?>(this.value);"
|
|
id="<?php echo escape($action_selection_id); ?>"
|
|
<?php if(!$top_actions) { ?>
|
|
class="SearchWidth"
|
|
<?php } else { ?>
|
|
accesskey="A"
|
|
<?php } ?>
|
|
aria-label="<?php echo escape($lang["actions"]) ?>">
|
|
<?php } ?>
|
|
<option class="SelectAction" selected disabled hidden value=""><?php echo escape($lang["actions-select"])?></option>
|
|
<?php
|
|
|
|
// Collection Actions
|
|
$collection_actions_array = compile_collection_actions($collection_data, $top_actions, $resource_data);
|
|
// Usual search actions
|
|
$search_actions_array = compile_search_actions($top_actions);
|
|
|
|
// Remove certain actions that apply only to searches
|
|
if(!$top_actions)
|
|
{
|
|
$action_index_to_remove = array_search('search_items_disk_usage', array_column($search_actions_array, 'value'));
|
|
unset($search_actions_array[$action_index_to_remove]);
|
|
$search_actions_array = array_values($search_actions_array);
|
|
|
|
$action_index_to_remove = array_search('save_search_items_to_collection', array_column($search_actions_array, 'value'));
|
|
unset($search_actions_array[$action_index_to_remove]);
|
|
$search_actions_array = array_values($search_actions_array);
|
|
|
|
if($forpage === "themes")
|
|
{
|
|
$action_index_to_remove = array_search('remove_collection', array_column($collection_actions_array, 'value'));
|
|
unset($collection_actions_array[$action_index_to_remove]);
|
|
$collection_actions_array = array_values($collection_actions_array);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @var A global variable that allows other parts in ResourceSpace to append extra options to the actions
|
|
* unified dropdown (plugins can use existing hooks).
|
|
*/
|
|
$render_actions_extra_options = array();
|
|
if(
|
|
isset($GLOBALS["render_actions_extra_options"])
|
|
&& is_array($GLOBALS["render_actions_extra_options"])
|
|
&& !empty($GLOBALS["render_actions_extra_options"]))
|
|
{
|
|
$render_actions_extra_options = $GLOBALS["render_actions_extra_options"];
|
|
}
|
|
|
|
$actions_array = array_merge($collection_actions_array, $search_actions_array, $render_actions_extra_options);
|
|
unset($render_actions_extra_options);
|
|
|
|
$modify_actions_array = hook('modify_unified_dropdown_actions_options', '', array($actions_array,$top_actions));
|
|
|
|
if(!empty($modify_actions_array))
|
|
{
|
|
$actions_array = $modify_actions_array;
|
|
}
|
|
|
|
/**
|
|
* @var A global variable that allows other parts in ResourceSpace to filter actions options (plugins can use
|
|
* existing hooks).
|
|
*/
|
|
if(isset($GLOBALS["render_actions_filter"]) && is_callable($GLOBALS["render_actions_filter"]))
|
|
{
|
|
$actions_array = array_filter($actions_array, $GLOBALS["render_actions_filter"]);
|
|
unset($GLOBALS["render_actions_filter"]);
|
|
}
|
|
|
|
// Sort array into category groups
|
|
usort($actions_array, function($a, $b){
|
|
if(isset($a['category']) && isset($b['category']))
|
|
{
|
|
if($a['category'] == $b['category'])
|
|
{
|
|
// Same category, check for order_by. If no order_by add to end of category
|
|
if(isset($a['order_by']) && (!isset($b['order_by']) || ($b['order_by'] > $a['order_by'])))
|
|
{
|
|
return -1;
|
|
}
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return $a['category'] - $b['category'];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return isset($a['category']) ? -1 : 1;
|
|
}
|
|
});
|
|
|
|
// loop and display
|
|
$options='';
|
|
$lastcategory = 0;
|
|
for($a = 0; $a < count($actions_array); $a++)
|
|
{
|
|
// Is this a new category?
|
|
if(!isset($actions_array[$a]['category']))
|
|
{
|
|
$actions_array[$a]['category'] = 999;
|
|
}
|
|
if($lastcategory != $actions_array[$a]['category'])
|
|
{
|
|
if($a > 0)
|
|
{
|
|
$options .= "</optgroup>\n";
|
|
}
|
|
$options .= "<optgroup label='" . escape($lang["collection_actiontype_" . $actions_array[$a]['category']]) . "'>\n";
|
|
}
|
|
|
|
if(!isset($actions_array[$a]['data_attr']))
|
|
{
|
|
$actions_array[$a]['data_attr'] = array();
|
|
}
|
|
|
|
if(!isset($actions_array[$a]['extra_tag_attributes']))
|
|
{
|
|
$actions_array[$a]['extra_tag_attributes'] = '';
|
|
}
|
|
|
|
$options .= render_dropdown_option($actions_array[$a]['value'], $actions_array[$a]['label'], $actions_array[$a]['data_attr'], $actions_array[$a]['extra_tag_attributes']);
|
|
|
|
$add_to_options = hook('after_render_dropdown_option', '', array($actions_array, $a));
|
|
if($add_to_options != '')
|
|
{
|
|
$options .= $add_to_options;
|
|
}
|
|
if($a == count($actions_array))
|
|
{
|
|
$options .= "\n</optgroup>\n";
|
|
}
|
|
$lastcategory = $actions_array[$a]['category'];
|
|
}
|
|
|
|
echo $options;
|
|
|
|
if(!$optionsonly)
|
|
{ ?>
|
|
</select>
|
|
<?php } ?>
|
|
<script>
|
|
function action_onchange_<?php echo $action_selection_id; ?>(v)
|
|
{
|
|
if(v == '')
|
|
{
|
|
return false;
|
|
}
|
|
|
|
v = v.match(/^[^~]*/i)[0]; // Remove unique value identifier: ~id
|
|
|
|
switch(v)
|
|
{
|
|
<?php
|
|
if(0 !== count($collection_data) && collection_readable($collection_data['ref']))
|
|
{
|
|
?>
|
|
case 'select_collection':
|
|
ChangeCollection(<?php echo $collection_data['ref']; ?>, '');
|
|
break;
|
|
|
|
case 'remove_collection':
|
|
if(confirm("<?php echo escape($lang['removecollectionareyousure']); ?>")) {
|
|
// most likely will need to be done the same way as delete_collection
|
|
var post_data = {
|
|
ajax: true,
|
|
dropdown_actions: true,
|
|
remove: <?php echo urlencode($collection_data['ref']); ?>,
|
|
<?php echo generateAjaxToken("remove_collection"); ?>
|
|
};
|
|
|
|
jQuery.post('<?php echo $baseurl; ?>/pages/collection_manage.php', post_data, 'json')
|
|
.always(function(){
|
|
CollectionDivLoad('<?php echo $baseurl; ?>/pages/collections.php');
|
|
});
|
|
|
|
}
|
|
break;
|
|
|
|
case 'purge_collection':
|
|
if(confirm('<?php echo escape($lang["purgecollectionareyousure"]); ?>'))
|
|
{
|
|
document.getElementById('collectionpurge').value='".urlencode($collections[$n]["ref"])."';
|
|
document.getElementById('collectionform').submit();
|
|
}
|
|
break;
|
|
|
|
case 'relate_all':
|
|
var collection = <?php echo urlencode($collection_data['ref']);?>;
|
|
jQuery.ajax({
|
|
type: 'POST',
|
|
url: baseurl_short + 'pages/ajax/relate_resources.php?collection=' + collection,
|
|
data: {<?php echo generateAjaxToken("relate_resources"); ?>},
|
|
success: function(data) {
|
|
if (data.trim() == "SUCCESS") {
|
|
styledalert('<?php echo escape($lang["complete"])?>', '<?php echo escape($lang['relateallresources_confirmation'])?>');
|
|
}
|
|
},
|
|
error: function (err) {
|
|
console.log("AJAX error : " + JSON.stringify(err, null, 2));
|
|
}
|
|
});
|
|
break;
|
|
|
|
case 'unrelate_all':
|
|
var collection = <?php echo urlencode($collection_data['ref']);?>;
|
|
jQuery.ajax({
|
|
type: 'POST',
|
|
url: baseurl_short + 'pages/ajax/unrelate_resources.php?collection=' + collection,
|
|
data: {<?php echo generateAjaxToken("unrelate_resources"); ?>},
|
|
success: function(data) {
|
|
if (data.trim() == "SUCCESS") {
|
|
styledalert('<?php echo escape($lang["complete"])?>', '<?php echo escape($lang['unrelateallresources_confirmation'])?>');
|
|
}
|
|
},
|
|
error: function (err) {
|
|
console.log("AJAX error : " + JSON.stringify(err, null, 2));
|
|
}
|
|
});
|
|
break;
|
|
<?php
|
|
}
|
|
|
|
if((!$top_actions || !empty($collection_data)) && $collection_data['type'] != COLLECTION_TYPE_REQUEST)
|
|
{
|
|
global $search;
|
|
$search_collection='';
|
|
if(substr($search,0,11)=='!collection')
|
|
{
|
|
$search_trimmed = substr($search,11); // The collection search must always be the first part of the search string
|
|
$search_elements = split_keywords($search_trimmed, false, false, false, false, true);
|
|
$search_collection = (int)$search_elements[0];
|
|
}
|
|
?>
|
|
case 'delete_collection':
|
|
if(confirm('<?php echo escape($lang["collectiondeleteconfirm"]); ?>')) {
|
|
var post_data = {
|
|
ajax: true,
|
|
dropdown_actions: true,
|
|
delete: <?php echo urlencode($collection_data['ref']); ?>,
|
|
<?php echo generateAjaxToken("delete_collection"); ?>
|
|
};
|
|
|
|
jQuery.post('<?php echo $baseurl; ?>/pages/collection_manage.php', post_data, function(response) {
|
|
if(response.success === 'Yes')
|
|
{
|
|
CollectionDivLoad('<?php echo $baseurl; ?>/pages/collections.php?collection=' + response.redirect_to_collection + '&k=' + response.k + '&nc=' + response.nc);
|
|
|
|
if(basename(document.URL).substr(0, 17) === 'collection_manage')
|
|
{
|
|
CentralSpaceLoad(document.URL);
|
|
}
|
|
else if(basename(document.URL).substr(0, 6) === 'search' && '<?php echo $search_collection?>'=='<?php echo $collection_data["ref"]; ?>')
|
|
{
|
|
CentralSpaceLoad('<?php echo $baseurl; ?>/pages/search.php?search=!collection' + response.redirect_to_collection, true);
|
|
}
|
|
else if(basename(document.URL).substr(0, 20) === 'collections_featured'){
|
|
CentralSpaceLoad(document.URL);
|
|
}
|
|
}
|
|
}, 'json');
|
|
}
|
|
break;
|
|
<?php
|
|
}
|
|
|
|
// Add extra collection actions javascript case through plugins
|
|
// Note: if you are just going to a different page, it should be easily picked by the default case
|
|
$extra_options_js_case = hook('render_actions_add_option_js_case', '', array($action_selection_id));
|
|
if(trim($extra_options_js_case) !== '')
|
|
{
|
|
echo $extra_options_js_case;
|
|
}
|
|
?>
|
|
|
|
case 'save_search_to_collection':
|
|
var option_url = jQuery('#<?php echo $action_selection_id; ?> option:selected').data('url');
|
|
CollectionDivLoad(option_url);
|
|
break;
|
|
|
|
case 'save_search_to_dash':
|
|
var option_url = jQuery('#<?php echo $action_selection_id; ?> option:selected').data('url');
|
|
var option_link = jQuery('#<?php echo $action_selection_id; ?> option:selected').data('link');
|
|
|
|
// Dash requires to have some search parameters (even if they are the default ones)
|
|
if((basename(option_link).substr(0, 10)) != 'search.php')
|
|
{
|
|
option_link = (window.location.href).replace(window.baseurl, '');
|
|
}
|
|
|
|
option_url += '&link=' + option_link;
|
|
|
|
CentralSpaceLoad(option_url);
|
|
break;
|
|
|
|
case 'save_search_smart_collection':
|
|
var option_url = jQuery('#<?php echo $action_selection_id; ?> option:selected').data('url');
|
|
CollectionDivLoad(option_url);
|
|
break;
|
|
|
|
case 'save_search_items_to_collection':
|
|
var option_url = jQuery('#<?php echo $action_selection_id; ?> option:selected').data('url');
|
|
CollectionDivLoad(option_url);
|
|
break;
|
|
|
|
case 'empty_collection':
|
|
if(!confirm('<?php echo escape($lang["emptycollectionareyousure"]); ?>'))
|
|
{
|
|
break;
|
|
}
|
|
|
|
var option_url = jQuery('#<?php echo $action_selection_id; ?> option:selected').data('url');
|
|
CollectionDivLoad(option_url);
|
|
break;
|
|
|
|
case 'copy_collection':
|
|
var option_url = jQuery('#<?php echo $action_selection_id; ?> option:selected').data('url');
|
|
ModalLoad(option_url, false, true);
|
|
break;
|
|
|
|
<?php
|
|
if(!$top_actions || $is_selection_collection)
|
|
{
|
|
?>
|
|
case 'delete_all_in_collection':
|
|
if(confirm('<?php echo escape($lang["deleteallsure"]); ?>'))
|
|
{
|
|
api('delete_resources_in_collection',
|
|
{'collection': '<?php echo (int) $collection_data["ref"]; ?>'},
|
|
function(response)
|
|
{
|
|
console.debug('Deleted resources in collection');
|
|
if (response) {
|
|
<?php
|
|
if ($is_selection_collection)
|
|
{
|
|
?>
|
|
CentralSpaceLoad(window.location.href, null, null, false);
|
|
<?php
|
|
}
|
|
else
|
|
{
|
|
?>
|
|
CollectionDivLoad('<?php echo $baseurl; ?>/pages/collections.php?collection=<?php echo (int) $collection_data["ref"]; ?>');
|
|
<?php
|
|
}
|
|
?>
|
|
}
|
|
else
|
|
{
|
|
styledalert("<?php echo escape($lang["error"]); ?>", "<?php echo escape($lang["error-editpermissiondenied"]); ?>");
|
|
}
|
|
},
|
|
<?php echo generate_csrf_js_object('delete_all_in_collection'); ?>
|
|
);
|
|
}
|
|
break;
|
|
<?php
|
|
}
|
|
?>
|
|
|
|
<?php
|
|
if(!$top_actions)
|
|
{
|
|
?>
|
|
case 'hide_collection':
|
|
var action = 'hidecollection';
|
|
var collection = <?php echo urlencode($collection_data['ref']);?>;
|
|
var mycol = jQuery('#<?php echo $action_selection_id; ?> option:selected').data('mycol');
|
|
|
|
jQuery.ajax({
|
|
type: 'POST',
|
|
url: baseurl_short + 'pages/ajax/showhide_collection.php?action=' + action + '&collection=' + collection,
|
|
data: {<?php echo generateAjaxToken("hide_collection"); ?>},
|
|
success: function(data) {
|
|
if (data.trim() == "HIDDEN") {
|
|
CollectionDivLoad('<?php echo $baseurl; ?>/pages/collections.php?collection='+mycol);
|
|
}
|
|
},
|
|
error: function (err) {
|
|
console.log("AJAX error : " + JSON.stringify(err, null, 2));
|
|
}
|
|
});
|
|
break;
|
|
<?php
|
|
}
|
|
?>
|
|
|
|
default:
|
|
var option_url = jQuery('#<?php echo $action_selection_id; ?> option:selected').data('url');
|
|
var option_callback = jQuery('#<?php echo $action_selection_id; ?> option:selected').data('callback');
|
|
var option_no_ajax = jQuery('#<?php echo $action_selection_id; ?> option:selected').data('no-ajax');
|
|
|
|
// If action option has a defined data-callback attribute, then we can call it
|
|
// IMPORTANT: never allow callback data attribute to be input/saved by user. Only ResourceSpace should
|
|
// generate the callbacks - key point is "generate"
|
|
if(typeof option_callback !== "undefined")
|
|
{
|
|
eval(option_callback);
|
|
}
|
|
|
|
// If action option has a defined data-url attribute, then we can CentralSpaceLoad it
|
|
if(typeof option_url !== "undefined")
|
|
{
|
|
if (typeof option_no_ajax == "undefined")
|
|
{
|
|
CentralSpaceLoad(option_url, true);
|
|
}
|
|
else
|
|
{
|
|
window.location.href = option_url;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
// Go back to no action option
|
|
jQuery('#<?php echo $action_selection_id; ?> option[value=""]').prop('selected', true);
|
|
|
|
|
|
}
|
|
</script>
|
|
|
|
<?php if (!$optionsonly)
|
|
{?>
|
|
</div>
|
|
<?php
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* @param string $name
|
|
* @param array $current Current selected values (eg. array(1, 3) for Admins and Super admins user groups selected)
|
|
* @param int $size How many options to show before user has to scroll
|
|
*/
|
|
function render_user_group_multi_select($name, array $current = array(), $size = 10, $style = '')
|
|
{
|
|
?>
|
|
<select id="<?php echo escape($name); ?>" class="MultiSelect" name="<?php echo escape($name); ?>[]" multiple="multiple" size="<?php echo $size; ?>" style="<?php echo $style; ?>">
|
|
<?php
|
|
foreach(get_usergroups() as $usergroup)
|
|
{
|
|
?>
|
|
<option value="<?php echo (int) $usergroup['ref']; ?>"<?php echo in_array($usergroup['ref'], $current) ? ' selected' : ''; ?>><?php echo escape($usergroup['name']); ?></option>
|
|
<?php
|
|
}
|
|
?>
|
|
</select>
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* Renders a list of user groups
|
|
*
|
|
* @param string $name
|
|
* @param array $current Current selected values (eg. array(1, 3) for Admins and Super admins user groups selected)
|
|
* @param string $style CSS styling that will apply to the outer container (ie. table element)
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_user_group_checkbox_select($name, array $current = array(), $style = '')
|
|
{
|
|
?>
|
|
<table id="<?php echo escape($name); ?>"<?php if('' !== $style) { ?>style="<?php echo $style; ?>"<?php } ?>>
|
|
<tbody>
|
|
<?php
|
|
foreach(get_usergroups(true) as $group)
|
|
{
|
|
?>
|
|
<tr>
|
|
<td><input id="<?php echo escape($name . '_' . $group['ref']); ?>" type="checkbox" name="<?php echo escape($name); ?>[]" value="<?php echo $group['ref']; ?>"<?php if(in_array($group['ref'], $current)) { ?> checked<?php } ?> /></td>
|
|
<td><label for="<?php echo escape($name . '_' . $group['ref']); ?>"><?php echo $group['name']; ?></label></td>
|
|
</tr>
|
|
<?php
|
|
}
|
|
?>
|
|
</tbody>
|
|
</table>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* render_text_input_question - Used to display a question with simple text input
|
|
*
|
|
* @param string $label Label of question
|
|
* @param string $input Name of input field
|
|
* @param string $additionaltext Text to to display after input
|
|
* @param boolean $numeric Set to true to force numeric input
|
|
* @param array $ctx Rendering context. Should be used to inject different elements (e.g set the div class)
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_text_question($label, $input, $additionaltext="", $numeric=false, $extra="", $current="", array $ctx = array())
|
|
{
|
|
$div_class = array("Question");
|
|
if(isset($ctx["div_class"]) && is_array($ctx["div_class"]) && !empty($ctx["div_class"]))
|
|
{
|
|
$div_class = array_merge($div_class, $ctx["div_class"]);
|
|
}
|
|
?>
|
|
<div id="question_<?php echo $input; ?>" class="<?php echo implode(" ", $div_class); ?>" >
|
|
<label for="<?php echo escape($input); ?>_input"><?php echo $label; ?></label>
|
|
<?php
|
|
printf('<input name="%s" id="%s_input" type="%s" value="%s"%s/>',
|
|
escape($input),
|
|
escape($input),
|
|
$numeric ? "number" : "text",
|
|
escape((string) $current),
|
|
$extra
|
|
);
|
|
|
|
echo $additionaltext;
|
|
?>
|
|
<div class="clearerleft"> </div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* render_split_text_question - Used to display a question with two inputs e.g. for a from/to range
|
|
*
|
|
* @param string $label Label of question
|
|
* @param array $inputs Array of input names and labels(eg. array('pixelwidthmin'=>'From','pixelwidthmin'=>'To')
|
|
* @param string $additionaltext (optional) Text to to display after input
|
|
* @param boolean $numeric Set to true to force numeric input
|
|
*/
|
|
function render_split_text_question($label, $inputs = array(), $additionaltext="", $numeric=false, $extra="", $currentvals=array())
|
|
{
|
|
?>
|
|
<div class="Question" id = "pixelwidth">
|
|
<label><?php echo $label; ?></label>
|
|
<div>
|
|
<?php
|
|
foreach ($inputs as $inputname=>$inputtext)
|
|
{
|
|
echo "<div class=\"SplitSearch\">" . $inputtext . "</div>\n";
|
|
echo "<input name=\"" . $inputname . "\" class=\"SplitSearch\" type=\"text\"". ($numeric?"numericinput":"") . "\" value=\"" . $currentvals[$inputname] . "\"" . $extra . " />\n";
|
|
}
|
|
echo $additionaltext;
|
|
?>
|
|
</div>
|
|
</div>
|
|
<div class="clearerleft"> </div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* render_dropdown_question - Used to display a question with a dropdown selector
|
|
*
|
|
* @param string $label Label of question
|
|
* @param string $inputname Name of input field
|
|
* @param array $options Array of options (value and text pairs) (eg. array('pixelwidthmin'=>'From','pixelwidthmin'=>'To')
|
|
* @param string $current The current selected value
|
|
* @param string $extra Extra attributes used on the selector element
|
|
* @param array $ctx Rendering context. Should be used to inject different elements (e.g set the div class, add onchange for select)
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_dropdown_question($label, $inputname, $options = array(), $current="", $extra="", array $ctx = array())
|
|
{
|
|
$div_class = array("Question");
|
|
if(isset($ctx["div_class"]) && is_array($ctx["div_class"]) && !empty($ctx["div_class"]))
|
|
{
|
|
$div_class = array_merge($div_class, $ctx["div_class"]);
|
|
}
|
|
$input_class = isset($ctx["input_class"]) ? $ctx["input_class"] : "stdwidth";
|
|
|
|
$onchange = (isset($ctx["onchange"]) && trim($ctx["onchange"]) != "" ? trim($ctx["onchange"]) : "");
|
|
$onchange = ($onchange != "" ? sprintf("onchange=\"%s\"", $onchange) : "");
|
|
|
|
$extra .= " {$onchange}";
|
|
?>
|
|
<div class="<?php echo escape(implode(" ", $div_class)); ?>">
|
|
<label><?php echo escape($label); ?></label>
|
|
<select name="<?php echo escape($inputname); ?>" class="<?php echo escape($input_class); ?>" id="<?php echo escape($inputname); ?>" <?php echo $extra; ?>>
|
|
<?php
|
|
foreach ($options as $optionvalue=>$optiontext)
|
|
{
|
|
?>
|
|
<option value="<?php echo escape(trim((string)$optionvalue))?>" <?php if (trim((string)$optionvalue)==trim((string)$current)) {?>selected<?php } ?>><?php echo escape(trim((string)$optiontext))?></option>
|
|
<?php
|
|
}
|
|
?>
|
|
</select>
|
|
<div class="clearerleft"></div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Render a table row (tr) for a single access key
|
|
*
|
|
* @param array $record Access key record details
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_access_key_tr(array $record)
|
|
{
|
|
global $baseurl, $baseurl_short, $lang;
|
|
$link = '';
|
|
$type = '';
|
|
$edit_link = '';
|
|
|
|
// Set variable dependent on type (ie. Resource / Collection)
|
|
if('' == $record['collection'] && '' != $record['resource'])
|
|
{
|
|
// For resource
|
|
$link = $baseurl . '?r=' . urlencode($record['resource']) . '&k=' . urlencode($record['access_key']);
|
|
$type = $lang['share-resource'];
|
|
$edit_link = sprintf('%spages/resource_share.php?ref=%s&editaccess=%s&editexpiration=%s&editaccesslevel=%s&editgroup=%s&backurl=%s',
|
|
$baseurl_short,
|
|
urlencode($record['resource']),
|
|
urlencode($record['access_key']),
|
|
urlencode($record['expires']),
|
|
urlencode($record['access']),
|
|
urlencode($record['usergroup']),
|
|
urlencode("/pages/team/team_external_shares.php")
|
|
);
|
|
}
|
|
else
|
|
{
|
|
// For collection
|
|
$link = $baseurl . '?c=' . urlencode($record['collection']) . '&k=' . urlencode($record['access_key']);
|
|
$type = $lang['sharecollection'];
|
|
$edit_link = sprintf('%spages/collection_share.php?ref=%s&editaccess=%s&editexpiration=%s&editaccesslevel=%s&editgroup=%s&backurl=%s',
|
|
$baseurl_short,
|
|
urlencode($record['collection']),
|
|
urlencode($record['access_key']),
|
|
urlencode($record['expires']),
|
|
urlencode($record['access']),
|
|
urlencode($record['usergroup']),
|
|
urlencode("/pages/team/team_external_shares.php")
|
|
);
|
|
}
|
|
?>
|
|
|
|
|
|
<tr id="access_key_<?php echo $record['access_key']; ?>">
|
|
<td>
|
|
<div class="ListTitle">
|
|
<a href="<?php echo $link; ?>" target="_blank"><?php echo escape($record['access_key']); ?></a>
|
|
</div>
|
|
</td>
|
|
<td><?php echo escape($type); ?></td>
|
|
<td><?php echo escape(resolve_users($record['users'])); ?></td>
|
|
<td><?php echo escape($record['emails']); ?></td>
|
|
<td><?php echo escape(nicedate($record['maxdate'], true, true, true)); ?></td>
|
|
<td><?php echo escape(nicedate($record['lastused'], true, true, true)); ?></td>
|
|
<td><?php echo escape(('' == $record['expires']) ? $lang['never'] : nicedate($record['expires'], false)); ?></td>
|
|
<td><?php echo escape((-1 == $record['access']) ? '' : $lang['access' . $record['access']]); ?></td>
|
|
<td>
|
|
<div class="ListTools">
|
|
<a href="#" onClick="delete_access_key('<?php echo $record['access_key']; ?>', '<?php echo $record['resource']; ?>', '<?php echo $record['collection']; ?>');"><?php echo LINK_CARET ?><?php echo escape($lang['action-delete']); ?></a>
|
|
<a href="<?php echo $edit_link; ?>"><?php echo LINK_CARET ?><?php echo escape($lang['action-edit']); ?></a>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Checks whether a specified field should be displayed based on various conditions.
|
|
*
|
|
* This function evaluates several criteria to determine if a field is visible in the resource editing interface.
|
|
* It takes into account the field's active status, permissions for viewing and editing, upload conditions,
|
|
* and any custom hooks that may hide the field.
|
|
*
|
|
* @param array $field The field configuration array containing information about the field's settings.
|
|
* @return bool Returns true if the field should be displayed; false otherwise.
|
|
*/
|
|
function is_field_displayed($field)
|
|
{
|
|
global $ref, $resource, $upload_review_mode;
|
|
|
|
# Conditions under which the field is not displayed
|
|
return !(
|
|
($field['active']==0)
|
|
# Field does not have individual write access allowed; and does not have edit access allowed on upload
|
|
|| (checkperm("F*") && !checkperm("F-" . $field["ref"]) && !($ref < 0 && checkperm("P" . $field["ref"])))
|
|
# Field has write access denied directly
|
|
|| checkperm("F" . $field["ref"])
|
|
# Field is hidden on upload
|
|
|| (($ref < 0 || $upload_review_mode) && $field["hide_when_uploading"])
|
|
# Other field conditions
|
|
|| hook('edithidefield', '', array('field' => $field))
|
|
|| hook('edithidefield2', '', array('field' => $field)));
|
|
}
|
|
|
|
/**
|
|
* Displays a field in the resource edit interface.
|
|
*
|
|
* This function handles the rendering of various types of fields based on their configurations and context.
|
|
* It supports multiple modes, such as batch editing, and adjusts the display based on user permissions,
|
|
* errors from previous saves, and whether the field is being copied from another resource.
|
|
*
|
|
* @param int $n The index of the field in the form.
|
|
* @param array $field The field configuration array containing settings and metadata for the field.
|
|
* @param bool $newtab Indicates if the field should be displayed in a new tab.
|
|
* @param bool $modal Indicates if the field is part of a modal dialog.
|
|
*/
|
|
function display_field($n, $field, $newtab=false,$modal=false)
|
|
{
|
|
debug_function_call(__FUNCTION__, [$n, $field['ref'], $newtab, $modal]);
|
|
|
|
global $use, $ref, $original_fields, $multiple, $lastglobal,$is_template, $language, $lang,
|
|
$blank_edit_template, $edit_autosave, $errors, $tabs_on_edit, $collapsible_sections, $ctrls_to_save,
|
|
$embedded_data_user_select, $embedded_data_user_select_fields, $show_error, $save_errors, $baseurl, $is_search,
|
|
$all_selected_nodes,$original_nodes, $FIXED_LIST_FIELD_TYPES, $TEXT_FIELD_TYPES, $DATE_FIELD_TYPES, $upload_review_mode, $check_edit_checksums, $locked_fields, $lastedited, $copyfrom, $fields;
|
|
|
|
// Set $is_search to false in case page request is not an ajax load and $is_search hs been set from the searchbar
|
|
$is_search=false;
|
|
|
|
if(!isset($locked_fields))
|
|
{
|
|
$locked_fields = explode(",",getval("lockedfields",""));
|
|
}
|
|
|
|
if(!isset($copyfrom))
|
|
{
|
|
$copyfrom = getval('copyfrom', '');
|
|
}
|
|
|
|
$name="field_" . $field["ref"];
|
|
$value=$field["value"];
|
|
$value=trim((string) $value);
|
|
$use_copyfrom=true;
|
|
$omit_when_copying_enacted=false;
|
|
if ($use != $ref && ($field["omit_when_copying"]))
|
|
{
|
|
debug("display_field: reverting copied value for field " . $field["ref"] . " as omit_when_copying is enabled");
|
|
# Return this field value back to the original value, instead of using the value from the copied resource/metadata template
|
|
# This is triggered if field has the 'omit_when_copying' flag set
|
|
reset($original_fields);
|
|
$use_copyfrom=false;
|
|
foreach ($original_fields as $original_field)
|
|
{
|
|
if ($original_field["ref"]==$field["ref"])
|
|
{
|
|
$value=$original_field["value"];
|
|
}
|
|
}
|
|
$selected_nodes = $original_nodes;
|
|
$omit_when_copying_enacted=true;
|
|
}
|
|
elseif(($ref<0 || $upload_review_mode) && isset($locked_fields) && in_array($field["ref"], $locked_fields) && $lastedited > 0)
|
|
{
|
|
// Get value from last edited resource
|
|
debug("display_field: locked field " . $field['ref'] . ". Using nodes from last resource edited - " . $lastedited);
|
|
$selected_nodes = get_resource_nodes($lastedited,$field["ref"]);
|
|
}
|
|
else
|
|
{
|
|
$selected_nodes = $all_selected_nodes;
|
|
if (in_array($field["type"], $DATE_FIELD_TYPES) && !$GLOBALS['use_native_input_for_date_field'])
|
|
{
|
|
$submitted_val = sanitize_date_field_input($field["ref"], false);
|
|
}
|
|
else
|
|
{
|
|
$submitted_val = getval("field_" . $field['ref'], "");
|
|
}
|
|
if(!empty($save_errors) && $submitted_val != "")
|
|
{
|
|
// Set to the value that was submitted
|
|
$value = $submitted_val;
|
|
}
|
|
}
|
|
|
|
$displaycondition=true;
|
|
if ($field["display_condition"] != "") {
|
|
// Check if field has a display condition set and render the client side check display condition functions
|
|
$displaycondition = check_display_condition($n, $field, $fields, true, $use);
|
|
debug(sprintf('$displaycondition = %s', json_encode($displaycondition)));
|
|
}
|
|
|
|
if ($multiple &&
|
|
( (getval("copyfrom","") == "" && getval('metadatatemplate', '') == "")
|
|
|| str_replace(array(" ",","),"",(string)$value)=="") )
|
|
{
|
|
debug('Blank the value for multi-edits unless copying data from resource');
|
|
$value="";
|
|
}
|
|
|
|
if ($field["global"] == 0 && $lastglobal && $collapsible_sections) { ?>
|
|
</div>
|
|
<h2 class="CollapsibleSectionHead" id="resource_type_properties"><?php echo escape($lang["typespecific"]); ?></h2>
|
|
<div class="CollapsibleSection" id="ResourceProperties<?php if ($ref<0) {echo "Upload";} ?>TypeSpecificSection">
|
|
<?php
|
|
}
|
|
|
|
# Blank form if 'reset form' has been clicked
|
|
if('' != getval('resetform', ''))
|
|
{
|
|
$value = '';
|
|
|
|
if(in_array($field['type'], $FIXED_LIST_FIELD_TYPES))
|
|
{
|
|
$selected_nodes = array();
|
|
}
|
|
$user_set_values = array();
|
|
}
|
|
// Copy from resource should only show values from the resource we are copying from
|
|
elseif($ref != $use && $copyfrom != '')
|
|
{
|
|
$user_set_values = array();
|
|
|
|
if(in_array($field['type'], $FIXED_LIST_FIELD_TYPES))
|
|
{
|
|
$field['node_options'] = array_filter($field['node_options'], 'node_is_active');
|
|
}
|
|
}
|
|
else
|
|
{
|
|
debug("display_field: getting all user selected values from form data for field " . $field['ref']);
|
|
$user_set_values = getval('nodes', [], false, 'is_array');
|
|
debug(sprintf('$user_set_values = %s', json_encode($user_set_values)));
|
|
}
|
|
|
|
/****************************** Errors on saving ***************************************/
|
|
$field_save_error = false;
|
|
if (
|
|
isset($show_error)
|
|
&& isset($save_errors)
|
|
&& array_key_exists($field['ref'], $save_errors)
|
|
) {
|
|
$field_save_error = true;
|
|
}
|
|
|
|
if ($multiple && !hook("replace_edit_all_checkbox","",array($field["ref"])))
|
|
{
|
|
# Multiple items, a toggle checkbox appears which activates the question
|
|
?>
|
|
<div class="Question edit_multi_checkbox">
|
|
<input name="editthis_<?php echo escape($name) ?>"
|
|
id="editthis_<?php echo $n?>"
|
|
type="checkbox"
|
|
value="yes"
|
|
<?php if($field_save_error){?> checked<?php } ?>
|
|
onClick="batch_edit_toggle_edit_multi_checkbox_question(<?php echo (int) $n; ?>);" <?php if(getval("copyfrom","")!="" && $use_copyfrom && $value!=""){echo " checked" ;} ?>>
|
|
<label for="editthis<?php echo $n?>"><?php echo escape($field["title"]) ?></label>
|
|
<div class="clearerleft"></div>
|
|
</div>
|
|
<!-- End of edit_multi_checkbox -->
|
|
<?php
|
|
}
|
|
if ($multiple && !hook("replace_edit_all_mode_select","",array($field["ref"])))
|
|
{
|
|
# When editing multiple, give option to select Replace All Text or Find and Replace
|
|
$onchangejs = '';
|
|
if (in_array($field['type'], $FIXED_LIST_FIELD_TYPES))
|
|
{
|
|
$onchangejs = 'setActionPromptText(' . (int) $n . '); ';
|
|
}
|
|
$onchangejs .= "var fr = document.getElementById('findreplace_" . (int) $n . "');\n";
|
|
$onchangejs .= "var q = document.getElementById('question_" . (int) $n . "');\n";
|
|
if ($field["type"] == FIELD_TYPE_CATEGORY_TREE)
|
|
{
|
|
$onchangejs .= "if (this.value=='RM'){branch_limit_field['field_" . $field["ref"] . "']=1;}else{branch_limit_field['field_" . $field["ref"] . "']=0;}";
|
|
}
|
|
elseif (in_array($field["type"], $TEXT_FIELD_TYPES ))
|
|
{
|
|
$onchangejs .= "
|
|
var cf = document.getElementById('copy_from_field_" . $field["ref"] . "');";
|
|
|
|
if ($field["type"] == FIELD_TYPE_TEXT_BOX_FORMATTED_AND_TINYMCE) {
|
|
$onchangejs .= "
|
|
var rff = document.getElementById('remove_from_field_" . (int) $n . "');
|
|
|
|
if (this.value == 'CF') {
|
|
cf.style.display = 'block';
|
|
fr.style.display = 'none';
|
|
q.style.display = 'none';
|
|
rff.style.display = 'none';
|
|
} else if (this.value == 'FR') {
|
|
fr.style.display = 'block';
|
|
cf.style.display = 'none';
|
|
q.style.display = 'none';
|
|
rff.style.display = 'none';
|
|
} else if (this.value == 'RM') {
|
|
fr.style.display = 'none';
|
|
cf.style.display = 'none';
|
|
q.style.display = 'none';
|
|
rff.style.display = 'block';
|
|
} else {
|
|
fr.style.display = 'none';
|
|
cf.style.display = 'none';
|
|
q.style.display = 'block';
|
|
rff.style.display = 'none';
|
|
}";
|
|
} else {
|
|
$onchangejs .= "
|
|
if (this.value == 'CF') {
|
|
cf.style.display = 'block';
|
|
fr.style.display = 'none';
|
|
q.style.display = 'none';
|
|
} else if (this.value == 'FR') {
|
|
fr.style.display = 'block';
|
|
cf.style.display = 'none';
|
|
q.style.display = 'none';
|
|
} else {
|
|
fr.style.display = 'none';
|
|
cf.style.display = 'none';
|
|
q.style.display = 'block';
|
|
}";
|
|
}
|
|
|
|
}
|
|
?>
|
|
<div class="Question" id="modeselect_<?php echo $n?>" style="<?php if($value=="" && !$field_save_error ){echo "display:none;";} ?>padding-bottom:0;margin-bottom:0;">
|
|
<label for="modeselectinput"><?php echo escape($lang["editmode"])?></label>
|
|
<select id="modeselectinput_<?php echo $n?>" name="modeselect_<?php echo $field["ref"]; ?>" class="stdwidth" onChange="<?php echo $onchangejs;hook ("edit_all_mode_js"); ?>">
|
|
<option value="RT"><?php echo escape($lang["replacealltext"])?></option>
|
|
<?php
|
|
if (in_array($field["type"], $TEXT_FIELD_TYPES ))
|
|
{
|
|
# 'Find and replace', prepend and 'copy from field' options apply to text boxes only.
|
|
?>
|
|
<option value="FR"<?php if(getval("modeselect_" . $field["ref"],"")=="FR"){?> selected<?php } ?>><?php echo escape($lang["findandreplace"])?></option>
|
|
<option value="CF"<?php if(getval("modeselect_" . $field["ref"],"")=="CF"){?> selected<?php } ?>><?php echo escape($lang["edit_copy_from_field"])?></option>
|
|
<option value="PP"<?php if(getval("modeselect_" . $field["ref"],"")=="PP"){?> selected<?php } ?>><?php echo escape($lang["prependtext"])?></option>
|
|
<?php
|
|
}
|
|
if((in_array($field['type'], $TEXT_FIELD_TYPES)) || in_array($field['type'], [FIELD_TYPE_CHECK_BOX_LIST, FIELD_TYPE_CATEGORY_TREE, FIELD_TYPE_DYNAMIC_KEYWORDS_LIST]))
|
|
{
|
|
# Append applies to text boxes, checkboxes ,category tree and dynamic keyword fields onl.
|
|
?>
|
|
<option value="AP"<?php if(getval("modeselect_" . $field["ref"],"")=="AP"){?> selected<?php } ?>><?php echo escape($lang["appendtext"])?></option>
|
|
<?php
|
|
}
|
|
if (
|
|
# Remove applies to text boxes, checkboxes, dropdowns, category trees and dynamic keywords only.
|
|
in_array($field['type'], array_merge($TEXT_FIELD_TYPES, array(FIELD_TYPE_CHECK_BOX_LIST, FIELD_TYPE_DROP_DOWN_LIST, FIELD_TYPE_CATEGORY_TREE, FIELD_TYPE_DYNAMIC_KEYWORDS_LIST)))
|
|
# And it only applies if the field is optional
|
|
&& $field['required'] == 0
|
|
) {
|
|
?>
|
|
<option value="RM"<?php if(getval("modeselect_" . $field["ref"],"")=="RM"){?> selected<?php } ?>><?php echo escape($lang["removetext"])?></option>
|
|
<?php
|
|
}
|
|
hook ("edit_all_extra_modes","",[$field]);
|
|
?>
|
|
</select>
|
|
</div><!-- End of modeselect_<?php echo $n?> -->
|
|
|
|
<?php
|
|
if (in_array($field["type"], $TEXT_FIELD_TYPES))
|
|
{
|
|
render_field_selector_question("","copy_from_field_" . $field["ref"], array(), "stdwidth", true);
|
|
}
|
|
?>
|
|
|
|
<div class="Question" id="findreplace_<?php echo $n?>" style="display:none;border-top:none;">
|
|
<label> </label>
|
|
<?php echo escape($lang["find"])?> <input type="text" name="find_<?php echo $field["ref"]; ?>" class="shrtwidth">
|
|
<?php echo escape($lang["andreplacewith"])?> <input type="text" name="replace_<?php echo $field["ref"]; ?>" class="shrtwidth">
|
|
</div><!-- End of findreplace_<?php echo $n?> -->
|
|
|
|
<?php
|
|
if ($field['type'] == FIELD_TYPE_TEXT_BOX_FORMATTED_AND_TINYMCE && $field['required'] == 0) {
|
|
?>
|
|
<div class="Question" id="remove_from_field_<?php echo $n?>" style="display:none;border-top:none;">
|
|
<label> </label>
|
|
<textarea
|
|
class="stdwidth MultiLine"
|
|
rows=6
|
|
cols=50
|
|
name="remove_<?php echo $field["ref"]; ?>"
|
|
id="remove_<?php echo $field["ref"]; ?>"
|
|
></textarea>
|
|
</div><!-- End of remove_from_field_<?php echo $n?> -->
|
|
<?php
|
|
}?>
|
|
|
|
<?php hook ("edit_all_after_findreplace","",array($field,$n));
|
|
}
|
|
|
|
if ($multiple && in_array($field['type'], $FIXED_LIST_FIELD_TYPES))
|
|
{
|
|
?>
|
|
<div class="Question" class="stdwidth" style="display:none;" id="displayexisting_<?php echo (int) $n; ?>" data-rtfid="<?php echo (int) $field['ref']; ?>">
|
|
<div class="questionSpacer"></div>
|
|
<p><?php echo escape($lang["edit_multiple_existing_values"]) . ':'; ?></p>
|
|
<div class="questionSpacer"></div>
|
|
<div>
|
|
<div class="displayexisting_options" id="displayexisting_options_<?php echo (int) $n; ?>" data-questionid="<?php echo (int) $n; ?>"></div>
|
|
<div class="questionSpacer"></div>
|
|
<input type="button" id="displayexisting_options_more_<?php echo (int) $n; ?>" style="display:none;" value="+ <?php echo escape($lang["edit_multiple_show_more"]); ?>" onclick="showMoreSelectedOptions(<?php echo (int) $n; ?>);">
|
|
</div>
|
|
</div>
|
|
<?php
|
|
}
|
|
?>
|
|
<div class="Question <?php if($upload_review_mode && in_array($field["ref"],$locked_fields)){echo " lockedQuestion ";} if($field_save_error) { echo 'FieldSaveError'; } ?>" id="question_<?php echo $n . ($multiple ? '' : '_' . $use); ?>"<?php
|
|
if (($multiple && !$field_save_error) || !$displaycondition || $newtab)
|
|
{?>style="border-top:none;<?php
|
|
if (($multiple && $value=="") || !$displaycondition)
|
|
{
|
|
debug('Hide this');
|
|
?>
|
|
display:none;
|
|
<?php
|
|
}
|
|
?>"<?php
|
|
}
|
|
?>>
|
|
<?php
|
|
if ($multiple && in_array($field['type'], $FIXED_LIST_FIELD_TYPES))
|
|
{
|
|
?>
|
|
<div id="ActionPrompt_<?php echo (int) $n; ?>">
|
|
<div class="questionSpacer"></div>
|
|
<p id="ActionPromptText_<?php echo (int) $n; ?>"></p>
|
|
</div>
|
|
<?php
|
|
}
|
|
$labelname = $name;
|
|
|
|
// Add _selector to label so it will keep working:
|
|
if($field['type'] == 9)
|
|
{
|
|
$labelname .= '_selector';
|
|
}
|
|
|
|
// Add -d to label so it will keep working
|
|
if($field['type'] == 4)
|
|
{
|
|
$labelname .= '-d';
|
|
}
|
|
?>
|
|
<label for="<?php echo escape($labelname)?>" <?php if($field['type']==FIELD_TYPE_DATE_RANGE) {echo " class='daterangelabel'";} ?> >
|
|
<?php
|
|
if (!$multiple)
|
|
{
|
|
echo escape($field["title"]);
|
|
if (!$is_template && $field["required"]==1)
|
|
{
|
|
echo "<sup>*</sup>";
|
|
}
|
|
}
|
|
if ($upload_review_mode)
|
|
{
|
|
renderLockButton($field["ref"], $locked_fields);
|
|
}
|
|
?>
|
|
</label>
|
|
|
|
<?php
|
|
# Autosave display
|
|
if ($edit_autosave || $ctrls_to_save)
|
|
{
|
|
?>
|
|
<div class="AutoSaveStatus">
|
|
<span id="AutoSaveStatus<?php echo $field["ref"]; ?>" style="display:none;"></span>
|
|
</div>
|
|
<?php
|
|
}
|
|
# Define some Javascript for help actions (applies to all fields)
|
|
# Help actions for TinyMCE fields are set in pages/edit_fields/8.php
|
|
if (trim($field["help_text"]==""))
|
|
{
|
|
# No helptext; so no javascript for toggling
|
|
$help_js="";
|
|
}
|
|
else
|
|
{
|
|
if ( in_array($field["type"],array(2,3,4,6,7,10,12,14)) )
|
|
{
|
|
# For the selected field types the helptext is always shown; so no javascript toggling
|
|
$help_js="";
|
|
}
|
|
else
|
|
{
|
|
# For all other field types setup javascript to toggle helptext depending on loss or gain of focus
|
|
$help_js="onBlur=\"HideHelp(" . $field["ref"] . ");return false;\" onFocus=\"ShowHelp(" . $field["ref"] . ");return false;\"";
|
|
}
|
|
}
|
|
|
|
#hook to modify field type in special case. Returning zero (to get a standard text box) doesn't work, so return 1 for type 0, 2 for type 1, etc.
|
|
$modified_field_type="";
|
|
$modified_field_type=(hook("modifyfieldtype"));
|
|
if ($modified_field_type){$field["type"]=$modified_field_type-1;}
|
|
|
|
hook("addfieldextras");
|
|
# ---------------------------- Show field -----------------------------------
|
|
$type = $field['type'];
|
|
|
|
// Default to text type.
|
|
if('' == $type)
|
|
{
|
|
$type = 0;
|
|
}
|
|
|
|
// The visibility status (block/none) will be sent to the server for validation purposes
|
|
echo "<input id='field_" . (int) $field['ref'] . "_displayed' name='" . "field_" . (int) $field['ref'] . "_displayed' type='hidden' value='block'>";
|
|
|
|
if(!hook('replacefield', '', array($field['type'], $field['ref'], $n)))
|
|
{
|
|
global $auto_order_checkbox, $auto_order_checkbox_case_insensitive, $FIXED_LIST_FIELD_TYPES, $is_search;
|
|
|
|
// Establish the full set of selected nodes to be rendered for this field
|
|
// Do this only if the field's selected nodes haven't previously been adjusted to take account of omit_when_copying
|
|
|
|
if (!$omit_when_copying_enacted && isset($field['nodes'])) {
|
|
$selected_nodes = array_unique(array_merge($selected_nodes, explode(",", $field['nodes'])));
|
|
}
|
|
|
|
debug(sprintf('$selected_nodes = %s', json_encode($selected_nodes)));
|
|
|
|
if(in_array($field['type'], $FIXED_LIST_FIELD_TYPES))
|
|
{
|
|
$name = "nodes[{$field['ref']}]";
|
|
|
|
// Sometimes we need to pass multiple options
|
|
if(in_array($field['type'], array(FIELD_TYPE_CHECK_BOX_LIST, FIELD_TYPE_CATEGORY_TREE)))
|
|
{
|
|
$name = "nodes[{$field['ref']}][]";
|
|
}
|
|
elseif(FIELD_TYPE_DYNAMIC_KEYWORDS_LIST == $field['type'])
|
|
{
|
|
$name = "field_{$field['ref']}";
|
|
}
|
|
|
|
$field_nodes = [];
|
|
foreach ($selected_nodes as $selected_node) {
|
|
// Check node is valid
|
|
if (!isset($field['node_options'][$selected_node])) {
|
|
continue;
|
|
}
|
|
$field_nodes[] = $selected_node;
|
|
}
|
|
sort($field_nodes);
|
|
debug(sprintf('$field_nodes = %s', json_encode($field_nodes)));
|
|
if(!$multiple && getval("copyfrom","") == "" && getval('metadatatemplate', '') == "" && $check_edit_checksums)
|
|
{
|
|
echo "<input id='field_" . (int) $field['ref'] . "_checksum' name='" . "field_" . (int) $field['ref'] . "_checksum' type='hidden' value='" . md5(implode(",",$field_nodes)) . "'>";
|
|
echo "<input id='field_" . (int) $field['ref'] . "_currentval' name='" . "field_" . (int) $field['ref'] . "_currentval' type='hidden' value='" . implode(",",$field_nodes) . "'>";
|
|
}
|
|
}
|
|
elseif($field['type']==FIELD_TYPE_DATE_RANGE && !$blank_edit_template && getval("copyfrom","") == "" && getval('metadatatemplate', '') == "" && $check_edit_checksums)
|
|
{
|
|
$field['node_options'] = get_nodes($field['ref'], null, false);
|
|
$field_nodes = array();
|
|
foreach($selected_nodes as $selected_node)
|
|
{
|
|
if(in_array($selected_node,array_column($field['node_options'],"ref")))
|
|
{
|
|
$field_nodes[] = $selected_node;
|
|
}
|
|
}
|
|
sort($field_nodes);
|
|
debug(sprintf('$field_nodes = %s', json_encode($field_nodes)));
|
|
echo "<input id='field_" . (int) $field['ref'] . "_checksum' name='" . "field_" . (int) $field['ref'] . "_checksum' type='hidden' value='" . md5(implode(",",$field_nodes)) . "'>";
|
|
}
|
|
elseif(!$multiple && !$blank_edit_template && getval("copyfrom","")=="" && getval('metadatatemplate', '') == "" && $check_edit_checksums)
|
|
{
|
|
echo "<input id='field_" . (int) $field['ref'] . "_checksum' name='" . "field_" . (int) $field['ref'] . "_checksum' type='hidden' value='" . md5(trim(preg_replace('/\s\s+/', ' ', (string) $field['value']))) . "'>";
|
|
}
|
|
elseif ($field['type'] === FIELD_TYPE_DATE && $GLOBALS['use_native_input_for_date_field'])
|
|
{
|
|
if ($GLOBALS['blank_date_upload_template'] && $value !== '' && $ref <= 0)
|
|
{
|
|
$value = '';
|
|
}
|
|
}
|
|
|
|
$is_search = false;
|
|
|
|
include "edit_fields/{$type}.php";
|
|
$lastglobal = $field['global']==1;
|
|
}
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# Display any error messages from previous save
|
|
if (array_key_exists($field["ref"],$errors))
|
|
{
|
|
?>
|
|
<div class="FormError">!! <?php echo $errors[$field["ref"]]; ?> !!</div>
|
|
<?php
|
|
}
|
|
|
|
if (trim($field["help_text"]!=""))
|
|
{
|
|
# Show inline help for this field.
|
|
# For certain field types that have no obvious focus, the help always appears
|
|
?>
|
|
<div class="FormHelp" style="padding:0;<?php if ( in_array($field["type"],array(2,3,4,6,7,10,12,14)) ) { ?> clear:left;<?php } else { ?> display:none;<?php } ?>" id="help_<?php echo $field["ref"]; ?>"><div class="FormHelpInner"><?php echo nl2br(trim(i18n_get_translated($field["help_text"])))?></div></div>
|
|
<?php
|
|
}
|
|
if(($embedded_data_user_select || (isset($embedded_data_user_select_fields) && in_array($field["ref"],$embedded_data_user_select_fields))) && ($ref<0 && !$multiple))
|
|
{
|
|
?>
|
|
<table id="exif_<?php echo $field["ref"]; ?>" class="ExifOptions" cellpadding="3" cellspacing="3" <?php if ($embedded_data_user_select){?> style="display: none;" <?php } ?>>
|
|
<tbody>
|
|
<tr>
|
|
<td>
|
|
<?php echo " " . escape($lang["embeddedvalue"]) . ": " ?>
|
|
</td>
|
|
<td width="10" valign="middle">
|
|
<input type="radio" id="exif_extract_<?php echo $field["ref"]; ?>" name="exif_option_<?php echo $field["ref"]; ?>" value="yes" checked>
|
|
</td>
|
|
<td align="left" valign="middle">
|
|
<label class="customFieldLabel" for="exif_extract_<?php echo $field["ref"]; ?>"><?php echo escape($lang["embedded_metadata_extract_option"]) ?></label>
|
|
</td>
|
|
|
|
|
|
<td width="10" valign="middle">
|
|
<input type="radio" id="no_exif_<?php echo $field["ref"]; ?>" name="exif_option_<?php echo $field["ref"]; ?>" value="no">
|
|
</td>
|
|
<td align="left" valign="middle">
|
|
<label class="customFieldLabel" for="no_exif_<?php echo $field["ref"]; ?>"><?php echo escape($lang["embedded_metadata_donot_extract_option"]) ?></label>
|
|
</td>
|
|
|
|
|
|
<td width="10" valign="middle">
|
|
<input type="radio" id="exif_append_<?php echo $field["ref"]; ?>" name="exif_option_<?php echo $field["ref"]; ?>" value="append">
|
|
</td>
|
|
<td align="left" valign="middle">
|
|
<label class="customFieldLabel" for="exif_append_<?php echo $field["ref"]; ?>"><?php echo escape($lang["embedded_metadata_append_option"]) ?></label>
|
|
</td>
|
|
|
|
|
|
<td width="10" valign="middle">
|
|
<input type="radio" id="exif_prepend_<?php echo $field["ref"]; ?>" name="exif_option_<?php echo $field["ref"]; ?>" value="prepend">
|
|
</td>
|
|
<td align="left" valign="middle">
|
|
<label class="customFieldLabel" for="exif_prepend_<?php echo $field["ref"]; ?>"><?php echo escape($lang["embedded_metadata_prepend_option"]) ?></label>
|
|
</td>
|
|
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<?php
|
|
}
|
|
?>
|
|
<div class="clearerleft"> </div>
|
|
</div><!-- end of question_<?php echo $n?> div -->
|
|
<?php
|
|
|
|
hook('afterfielddisplay', '', array($n, $field));
|
|
}
|
|
|
|
/**
|
|
* Renders a date range input field for resource editing.
|
|
*
|
|
* This function creates a set of input fields for selecting a start and end date. It supports EDTF format
|
|
* and includes validation for the entered dates. It also provides functionality for handling multiple edit modes
|
|
* and integrates with the autosave feature.
|
|
*
|
|
* @param string $name The base name for the input fields.
|
|
* @param string $value The value of the date range (in a specific format).
|
|
* @param bool $forsearch Indicates if the field is being used for a search query.
|
|
* @param bool $autoupdate Indicates if the field should trigger an update on change.
|
|
* @param array $field The field configuration array containing settings and metadata for the field.
|
|
* @param string $reset An optional parameter indicating if the form should be reset.
|
|
*/
|
|
function render_date_range_field($name,$value,$forsearch=true,$autoupdate=false,$field=array(),$reset="")
|
|
{
|
|
$found_year='';$found_month='';$found_day='';$found_start_year='';$found_start_month='';$found_start_day='';$found_end_year='';$found_end_month='';$found_end_day='';
|
|
global $daterange_edtf_support,$lang, $minyear,$date_d_m_y, $edit_autosave,$forsearchbar, $maxyear_extends_current;
|
|
if($forsearch)
|
|
{
|
|
// Get the start/end date from the string
|
|
$startpos = strpos($value,"start");
|
|
$endpos = strpos($value,"end");
|
|
$startvalue = $startpos !== false ? substr($value,$startpos+5,($endpos ? ($endpos - ($startpos + 5)) : null)) : "";
|
|
$endvalue = $endpos !== false ? substr($value,strpos($value,"end")+3,10) : "";
|
|
}
|
|
else
|
|
{
|
|
if($value!="" && strpos($value,",")!==false)
|
|
{
|
|
// Extract the start date from the value obtained from get_resource_field_data
|
|
$rangevalues = explode(",",$value);
|
|
$startvalue = $rangevalues[0];
|
|
$endvalue = $rangevalues[1];
|
|
}
|
|
elseif(strlen($value)==10 && strpos($value,"-") !== false)
|
|
{
|
|
$startvalue = $value;
|
|
$endvalue = "";
|
|
}
|
|
else
|
|
{
|
|
$startvalue = "";
|
|
$endvalue = "";
|
|
}
|
|
}
|
|
|
|
$startvalue = trim($startvalue);
|
|
$endvalue = trim($endvalue);
|
|
|
|
$ss=explode("-",$startvalue);
|
|
if (count($ss)>=1)
|
|
{
|
|
$found_start_year = $ss[0] ?? "";
|
|
$found_start_month = $ss[1] ?? "";
|
|
$found_start_day = $ss[2] ?? "";
|
|
}
|
|
$se=explode("-",$endvalue);
|
|
if (count($se)>=1)
|
|
{
|
|
$found_end_year = $se[0] ?? "";
|
|
$found_end_month = $se[1] ?? "";
|
|
$found_end_day = $se[2] ?? "";
|
|
}
|
|
|
|
// If the form has been submitted (but not reset) but data was not saved get the submitted values
|
|
if($reset == "")
|
|
{
|
|
foreach(array("start_y", "start-m","start-d","end-y","end-m","end-d") as $subpart)
|
|
{
|
|
if(getval($name . "_" . $subpart,"") != "")
|
|
{
|
|
${"found_" . $subpart} = escape(getval($name . "_" . $subpart,""));
|
|
}
|
|
}
|
|
}
|
|
|
|
if($daterange_edtf_support)
|
|
{
|
|
// Use EDTF format for date input
|
|
?>
|
|
<input class="<?php echo $forsearch?"SearchWidth":"stdwidth"; ?>" name="<?php echo escape($name); ?>_edtf" id="<?php echo escape($name); ?>_edtf" type="text" value="<?php echo escape(($startvalue != "" | $endvalue !="") ? $startvalue . "/" . $endvalue : ""); ?>" style="display:none;" disabled <?php if ($forsearch && $autoupdate) { ?>onChange="UpdateResultCount();"<?php } if($forsearch && !$forsearchbar){ ?> onKeyPress="if (!(updating)) {setTimeout('UpdateResultCount()',2000);updating=true;}"<?php } elseif (!$forsearch && $edit_autosave){?>onChange="AutoSave('<?php echo (int) $field["ref"]; ?>');"<?php } ?>>
|
|
<?php
|
|
}?>
|
|
<!-- date range search start -->
|
|
<!--- start date -->
|
|
<div class="stdwidth indent <?php echo escape($name); ?>_range" id="<?php echo escape($name); ?>_start">
|
|
<label class="InnerLabel"><?php echo escape($lang["fromdate"])?></label>
|
|
|
|
<?php
|
|
if($date_d_m_y)
|
|
{
|
|
?>
|
|
<label class="accessibility-hidden" for="<?php echo escape($name) ?>_start-d"><?php echo escape($lang["day"]); ?></label>
|
|
<select name="<?php echo escape($name); ?>_start-d" id="<?php echo escape($name); ?>_start-d"
|
|
<?php
|
|
if ($forsearch && $autoupdate)
|
|
{ ?>onChange="UpdateResultCount();"<?php }
|
|
elseif (!$forsearch && $edit_autosave)
|
|
{?>onChange="if(sufficientDateParts('<?php echo escape($name); ?>_start')){AutoSave('<?php echo $field["ref"]; ?>');}"<?php } ?>
|
|
>
|
|
<option value=""><?php echo escape($forsearch?$lang["anyday"]:$lang["day"]); ?></option>
|
|
<?php
|
|
for ($d=1;$d<=31;$d++)
|
|
{
|
|
$m=str_pad($d,2,"0",STR_PAD_LEFT);
|
|
?><option <?php if ($d==$found_start_day) { ?>selected<?php } ?> value="<?php echo $m?>"><?php echo $m?></option><?php
|
|
}
|
|
?>
|
|
</select>
|
|
<label class="accessibility-hidden" for="<?php echo escape($name) ?>_start-m"><?php echo escape($lang["month"]); ?></label>
|
|
<select name="<?php echo escape($name); ?>_start-m" id="<?php echo escape($name); ?>_start-m"
|
|
<?php
|
|
if ($forsearch && $autoupdate)
|
|
{ ?>onChange="UpdateResultCount();"<?php }
|
|
elseif (!$forsearch && $edit_autosave)
|
|
{?>onChange="if(sufficientDateParts('<?php echo escape($name); ?>_start')){AutoSave('<?php echo $field["ref"]; ?>');}"<?php } ?>
|
|
>
|
|
<option value=""><?php echo escape($forsearch?$lang["anymonth"]:$lang["month"]); ?></option>
|
|
<?php
|
|
for ($d=1;$d<=12;$d++)
|
|
{
|
|
$m=str_pad($d,2,"0",STR_PAD_LEFT);
|
|
?><option <?php if ($d==$found_start_month) { ?>selected<?php } ?> value="<?php echo $m?>"><?php echo escape($lang["months"][$d-1])?></option><?php
|
|
}?>
|
|
</select>
|
|
<?php
|
|
}
|
|
else
|
|
{
|
|
?>
|
|
<label class="accessibility-hidden" for="<?php echo escape($name) ?>_start-m"><?php echo escape($lang["month"]); ?></label>
|
|
<select name="<?php echo escape($name); ?>_start-m" id="<?php echo escape($name); ?>_start-m"
|
|
<?php
|
|
if ($forsearch && $autoupdate)
|
|
{ ?>onChange="UpdateResultCount();"<?php }
|
|
elseif (!$forsearch && $edit_autosave)
|
|
{?>onChange="if(sufficientDateParts('<?php echo escape($name); ?>_start')){AutoSave('<?php echo $field["ref"]; ?>');}"<?php } ?>
|
|
>
|
|
<option value=""><?php echo escape($forsearch?$lang["anymonth"]:$lang["month"]); ?></option>
|
|
<?php
|
|
for ($d=1;$d<=12;$d++)
|
|
{
|
|
$m=str_pad($d,2,"0",STR_PAD_LEFT);
|
|
?><option <?php if ($d==$found_start_month) { ?>selected<?php } ?> value="<?php echo $m?>"><?php echo escape($lang["months"][$d-1]) ?></option><?php
|
|
}?>
|
|
</select>
|
|
<label class="accessibility-hidden" for="<?php echo escape($name) ?>_start-d"><?php echo escape($lang["day"]); ?></label>
|
|
<select name="<?php echo escape($name); ?>_start-d" id="<?php echo escape($name); ?>_start-d"
|
|
<?php
|
|
if ($forsearch && $autoupdate)
|
|
{ ?>onChange="UpdateResultCount();"<?php }
|
|
elseif (!$forsearch && $edit_autosave)
|
|
{?>onChange="if(sufficientDateParts('<?php echo escape($name); ?>_start')){AutoSave('<?php echo $field["ref"]; ?>');}"<?php } ?>
|
|
>
|
|
<option value=""><?php echo escape($forsearch?$lang["anyday"]:$lang["day"]); ?></option>
|
|
<?php
|
|
for ($d=1;$d<=31;$d++)
|
|
{
|
|
$m=str_pad($d,2,"0",STR_PAD_LEFT);
|
|
?><option <?php if ($d==$found_start_day) { ?>selected<?php } ?> value="<?php echo $m?>"><?php echo $m?></option><?php
|
|
}
|
|
?>
|
|
</select>
|
|
<?php
|
|
}
|
|
if($forsearch)
|
|
{?>
|
|
<label class="accessibility-hidden" for="<?php echo escape($name) ?>_start-y"><?php echo escape($lang["year"]); ?></label>
|
|
<select name="<?php echo escape($name) ?>_start-y" id="<?php echo escape($name); ?>_start-y"
|
|
<?php
|
|
if ($forsearch && $autoupdate)
|
|
{ ?>onChange="UpdateResultCount();"<?php }
|
|
elseif (!$forsearch && $edit_autosave)
|
|
{?>onChange="if(sufficientDateParts('<?php echo escape($name); ?>_start')){AutoSave('<?php echo $field["ref"]; ?>');}"<?php } ?>
|
|
>
|
|
<option value=""><?php echo escape($forsearch?$lang["anyyear"]:$lang["year"]); ?></option>
|
|
<?php
|
|
$y=date("Y");
|
|
$y += $maxyear_extends_current;
|
|
for ($d=$y;$d>=$minyear;$d--)
|
|
{
|
|
?><option <?php if ($d==$found_start_year) { ?>selected<?php } ?>><?php echo $d?></option><?php
|
|
}?>
|
|
</select>
|
|
<?php
|
|
}
|
|
else
|
|
{?>
|
|
<label class="accessibility-hidden" for="<?php echo escape($name) ?>_end-y"><?php echo escape($lang["year"]); ?></label>
|
|
<input size="5" name="<?php echo escape($name) ?>_start-y" id="<?php echo escape($name) ?>_start-y" type="text" value="<?php echo $found_start_year ?>"
|
|
<?php
|
|
if ($forsearch && $autoupdate)
|
|
{ ?>onChange="UpdateResultCount();"<?php }
|
|
if($forsearch && !$forsearchbar)
|
|
{ ?> onKeyPress="if (!(updating)) {setTimeout('UpdateResultCount()',2000);updating=true;}"<?php }
|
|
elseif (!$forsearch && $edit_autosave)
|
|
{?>onChange="if(sufficientDateParts('<?php echo escape($name); ?>_start')){AutoSave('<?php echo $field["ref"]; ?>');}"<?php } ?>>
|
|
<?php
|
|
}?>
|
|
</div>
|
|
|
|
<div class="clearerleft"> </div>
|
|
|
|
<!--- to date -->
|
|
<label class='daterangelabel'></label>
|
|
|
|
<div class="stdwidth indent <?php echo escape($name); ?>_range" id="<?php echo escape($name); ?>_to" >
|
|
<label class="InnerLabel"><?php echo escape($lang["todate"])?></label>
|
|
<?php
|
|
if($date_d_m_y)
|
|
{
|
|
?>
|
|
<label class="accessibility-hidden" for="<?php echo escape($name) ?>_end-d"><?php echo escape($lang["day"]); ?></label>
|
|
<select name="<?php echo escape($name); ?>_end-d" id="<?php echo escape($name); ?>_end-d"
|
|
<?php
|
|
if ($forsearch && $autoupdate)
|
|
{ ?>onChange="UpdateResultCount();"<?php }
|
|
elseif (!$forsearch && $edit_autosave)
|
|
{?>onChange="if(sufficientDateParts('<?php echo escape($name); ?>_end')){AutoSave('<?php echo $field["ref"]; ?>');}"<?php } ?>
|
|
>
|
|
<option value=""><?php echo escape($forsearch?$lang["anyday"]:$lang["day"]); ?></option>
|
|
<?php
|
|
for ($d=1;$d<=31;$d++)
|
|
{
|
|
$m=str_pad($d,2,"0",STR_PAD_LEFT);
|
|
?><option <?php if ($d==$found_end_day) { ?>selected<?php } ?> value="<?php echo $m?>"><?php echo $m?></option><?php
|
|
}?>
|
|
</select>
|
|
<label class="accessibility-hidden" for="<?php echo escape($name) ?>_end-m"><?php echo escape($lang["month"]); ?></label>
|
|
<select name="<?php echo escape($name); ?>_end-m" id="<?php echo escape($name); ?>_end-m"
|
|
<?php
|
|
if ($forsearch && $autoupdate)
|
|
{ ?>onChange="UpdateResultCount();"<?php }
|
|
elseif (!$forsearch && $edit_autosave)
|
|
{?>onChange="if(sufficientDateParts('<?php echo escape($name); ?>_end')){AutoSave('<?php echo $field["ref"]; ?>');}"<?php } ?>
|
|
>
|
|
<option value=""><?php echo escape($forsearch?$lang["anymonth"]:$lang["month"]); ?></option>
|
|
<?php
|
|
for ($d=1;$d<=12;$d++)
|
|
{
|
|
$m=str_pad($d,2,"0",STR_PAD_LEFT);
|
|
?><option <?php if ($d==$found_end_month) { ?>selected<?php } ?> value="<?php echo $m?>"><?php echo escape($lang["months"][$d-1])?></option><?php
|
|
}?>
|
|
</select>
|
|
<?php
|
|
}
|
|
else
|
|
{
|
|
?>
|
|
<label class="accessibility-hidden" for="<?php echo escape($name) ?>_end-m"><?php echo escape($lang["month"]); ?></label>
|
|
<select name="<?php echo escape($name); ?>_end-m" id="<?php echo escape($name); ?>_end-m" <?php
|
|
if (!$forsearch && $edit_autosave)
|
|
{?>onChange="if(sufficientDateParts('<?php echo escape($name); ?>_end')){AutoSave('<?php echo $field["ref"]; ?>');}"<?php }
|
|
else
|
|
{?>onChange="UpdateResultCount();"<?php } ?>
|
|
>
|
|
<option value=""><?php echo escape($forsearch?$lang["anymonth"]:$lang["month"]); ?></option>
|
|
<?php
|
|
for ($d=1;$d<=12;$d++)
|
|
{
|
|
$m=str_pad($d,2,"0",STR_PAD_LEFT);
|
|
?><option <?php if ($d==$found_end_month) { ?>selected<?php } ?> value="<?php echo $m?>"><?php echo escape($lang["months"][$d-1]) ?></option><?php
|
|
}?>
|
|
</select>
|
|
<label class="accessibility-hidden" for="<?php echo escape($name) ?>_end-d"><?php echo escape($lang["day"]); ?></label>
|
|
<select name="<?php echo escape($name); ?>_end-d" id="<?php echo escape($name); ?>_end-d"
|
|
<?php
|
|
if ($forsearch && $autoupdate)
|
|
{ ?>onChange="UpdateResultCount();"<?php }
|
|
elseif (!$forsearch && $edit_autosave)
|
|
{?>onChange="if(sufficientDateParts('<?php echo escape($name); ?>_end')){AutoSave('<?php echo $field["ref"]; ?>');}"<?php } ?>
|
|
>
|
|
<option value=""><?php echo escape($forsearch?$lang["anyday"]:$lang["day"]); ?></option>
|
|
<?php
|
|
for ($d=1;$d<=31;$d++)
|
|
{
|
|
$m=str_pad($d,2,"0",STR_PAD_LEFT);
|
|
?><option <?php if ($d==$found_end_day) { ?>selected<?php } ?> value="<?php echo $m?>"><?php echo $m?></option><?php
|
|
}
|
|
?>
|
|
</select>
|
|
<?php
|
|
}
|
|
if($forsearch)
|
|
{?>
|
|
<label class="accessibility-hidden" for="<?php echo escape($name) ?>_end-y"><?php echo escape($lang["year"]); ?></label>
|
|
<select name="<?php echo escape($name); ?>_end-y" id="<?php echo escape($name); ?>_end-y"
|
|
<?php
|
|
if ($forsearch && $autoupdate) { ?>onChange="UpdateResultCount();"<?php }
|
|
elseif (!$forsearch && $edit_autosave)
|
|
{?>onChange="if(sufficientDateParts('<?php echo escape($name); ?>_end')){AutoSave('<?php echo $field["ref"]; ?>');}"<?php } ?>
|
|
>
|
|
<option value=""><?php echo escape($forsearch?$lang["anyyear"]:$lang["year"]); ?></option>
|
|
<?php
|
|
$y=date("Y");
|
|
$y += $maxyear_extends_current;
|
|
for ($d=$y;$d>=$minyear;$d--)
|
|
{
|
|
?><option <?php if ($d==$found_end_year ) { ?>selected<?php } ?>><?php echo $d?></option><?php
|
|
}
|
|
?>
|
|
</select>
|
|
<?php
|
|
}
|
|
else
|
|
{?>
|
|
<label class="accessibility-hidden" for="<?php echo escape($name) ?>_end-y"><?php echo escape($lang["year"]); ?></label>
|
|
<input size="5" name="<?php echo escape($name) ?>_end-y" id="<?php echo escape($name) ?>_end-y" type="text" value="<?php echo $found_end_year ?>"
|
|
<?php
|
|
|
|
if ($forsearch && $autoupdate)
|
|
{ ?>onChange="UpdateResultCount();"<?php }
|
|
if($forsearch && !$forsearchbar)
|
|
{ ?> onKeyPress="if (!(updating)) {setTimeout('UpdateResultCount()',2000);updating=true;}"<?php }
|
|
elseif (!$forsearch && $edit_autosave)
|
|
{?>onChange="if(sufficientDateParts('<?php echo escape($name); ?>_end')){AutoSave('<?php echo $field["ref"]; ?>');}"<?php } ?>>
|
|
<?php
|
|
}
|
|
|
|
if($forsearch !== true)
|
|
{
|
|
?>
|
|
<script>
|
|
// Get value of the date element before the change
|
|
jQuery('[name^=<?php echo escape($name); ?>]').on('focus', function(){
|
|
jQuery.data(this, 'current', jQuery(this).val());
|
|
});
|
|
//Check the value of the date after the change
|
|
jQuery('[name^=<?php echo escape($name); ?>_start]').on('change', function(){
|
|
let day = jQuery('[name=<?php echo escape($name); ?>_start-d]').val().trim();
|
|
let month = jQuery('[name=<?php echo escape($name); ?>_start-m]').val().trim();
|
|
let year = jQuery('[name=<?php echo escape($name); ?>_start-y]').val().trim();
|
|
if (year != "" && !jQuery.isNumeric(year))
|
|
{
|
|
styledalert(<?php echo "'" . escape($lang["error"] . "','" . $lang["invalid_date_generic"]) . "'" ?>);
|
|
jQuery(this).val(jQuery.data(this, 'current'));
|
|
}
|
|
if(jQuery.isNumeric(year) && jQuery.isNumeric(day) && jQuery.isNumeric(month)){
|
|
//format date string into yyyy-mm-dd
|
|
let date_string = year + '-' + month + '-' + day;
|
|
//get a timestamp from the date string and then convert that back to yyyy-mm-dd
|
|
let date = new Date(date_string).toISOString().split('T')[0];
|
|
//check if the before and after are the same, if a date like 2021-02-30 is selected date would be 2021-03-02
|
|
if(date_string !== date){
|
|
styledalert(<?php echo "'" . escape($lang["error"] . "','" . $lang["invalid_date_generic"]) . "'" ?>);
|
|
jQuery(this).val(jQuery.data(this, 'current'))
|
|
}
|
|
}
|
|
})
|
|
//Same again but for the end of the date range
|
|
jQuery('[name^=<?php echo escape($name); ?>_end]').on('change', function(){
|
|
let day = jQuery('[name=<?php echo escape($name); ?>_end-d]').val().trim();
|
|
let month = jQuery('[name=<?php echo escape($name); ?>_end-m]').val().trim();
|
|
let year = jQuery('[name=<?php echo escape($name); ?>_end-y]').val().trim();
|
|
if (year != "" && !jQuery.isNumeric(year))
|
|
{
|
|
styledalert(<?php echo "'" . escape($lang["error"] . "','" . $lang["invalid_date_generic"]) . "'" ?>);
|
|
jQuery(this).val(jQuery.data(this, 'current'));
|
|
}
|
|
if(jQuery.isNumeric(year) && jQuery.isNumeric(day) && jQuery.isNumeric(month)){
|
|
//format date string into yyyy-mm-dd
|
|
let date_string = year + '-' + month + '-' + day;
|
|
//get a timestamp from the date string and then convert that back to yyyy-mm-dd
|
|
let date = new Date(date_string).toISOString().split('T')[0];
|
|
//check if the before and after are the same, if a date like 2021-02-30 is selected date would be 2021-03-02
|
|
if(date_string !== date){
|
|
styledalert(<?php echo "'" . escape($lang["error"] . "','" . $lang["invalid_date_generic"]) . "'" ?>);
|
|
jQuery(this).val(jQuery.data(this, 'current'))
|
|
}
|
|
}
|
|
})
|
|
</script>
|
|
<?php } ?>
|
|
<!-- date range search end date-->
|
|
</div>
|
|
<div class="clearerleft"></div>
|
|
<?php if($daterange_edtf_support)
|
|
{?>
|
|
<a href="#" onclick="if(jQuery('#<?php echo escape($name); ?>_edtf').prop('disabled')){jQuery('#<?php echo escape($name); ?>_edtf').prop('disabled',false);jQuery('#<?php echo escape($name); ?>_edtf').show();jQuery('.<?php echo escape($name); ?>_range').hide();}else{jQuery('#<?php echo escape($name); ?>_edtf').prop('disabled',true);jQuery('#<?php echo escape($name); ?>_edtf').hide();jQuery('.<?php echo escape($name); ?>_range').show();}return false;">
|
|
<i aria-hidden="true" class="fa fa-caret-right"></i>
|
|
<?php echo "EDTF"; ?>
|
|
</a>
|
|
<?php
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Renders a full breadcrumbs trail.
|
|
*
|
|
* @param array $links List of link "objects" that create the trail
|
|
* @param string $pre_links Pre-rendered links in HTML form
|
|
* @param string $class Extra classes for the main container div
|
|
*
|
|
* @return void
|
|
*/
|
|
function renderBreadcrumbs(array $links, $pre_links = '', $class = '')
|
|
{
|
|
global $lang;
|
|
/*
|
|
NOTE: implemented as seen on themes and search. There is a lot of room for improvement UI wise
|
|
|
|
TODO: search_title_processing.php is using it intensively and at the moment there are differences in terms of
|
|
rendered HTML between themes/ search and search_title_processing.php. We should refactor all places were breadcrumbs
|
|
are being created and make sure they all use this function (or any future related functions - like generateBreadcrumb() ).
|
|
*/
|
|
|
|
if(0 === count($links))
|
|
{
|
|
return;
|
|
}
|
|
?>
|
|
<div class="BreadcrumbsBox <?php echo $class; ?>">
|
|
<div class="SearchBreadcrumbs">
|
|
<?php
|
|
if('' !== $pre_links && $pre_links !== strip_tags($pre_links))
|
|
{
|
|
echo $pre_links . ' ' . LINK_CHEVRON_RIGHT;
|
|
}
|
|
|
|
for($i = 0; $i < count($links); $i++)
|
|
{
|
|
$anchor = isset($links[$i]['href']);
|
|
$anchor_attrs = (isset($links[$i]["attrs"]) && is_array($links[$i]["attrs"]) && !empty($links[$i]["attrs"]) ? $links[$i]["attrs"] : array());
|
|
$anchor_attrs = join(" ", $anchor_attrs);
|
|
|
|
// search_title_processing.php is building spans with different class names. We need to allow HTML in link titles.
|
|
$title = get_inner_html_from_tag(strip_tags_and_attributes($links[$i]['title']), "p");
|
|
|
|
if(0 < $i)
|
|
{
|
|
echo LINK_CHEVRON_RIGHT;
|
|
}
|
|
|
|
if ($anchor) { ?>
|
|
<a href="<?php echo escape($links[$i]['href']); ?>"
|
|
<?php if (isset($links[$i]["menu"]) && $links[$i]["menu"]) { ?>
|
|
onclick="ModalClose(); return ModalLoad(this, true, true, 'right');"
|
|
<?php } else { ?>
|
|
onclick="return CentralSpaceLoad(this, true);"
|
|
<?php }
|
|
echo escape($anchor_attrs); ?>>
|
|
<?php } ?>
|
|
|
|
<span><?php echo $title; ?></span>
|
|
|
|
<?php if ($anchor) { ?>
|
|
</a>
|
|
<?php }
|
|
|
|
if (isset($links[$i]['help']))
|
|
{
|
|
render_help_link($links[$i]['help']);
|
|
}
|
|
}
|
|
?>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* Render a blank tile used for call to actions (e.g: on featured collections, a tile for creating new collections)
|
|
*
|
|
* @param string $url URL
|
|
* @param array $ctx Rendering options determined by the outside context
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_new_featured_collection_cta(string $url, array $ctx)
|
|
{
|
|
if('' === $url)
|
|
{
|
|
return;
|
|
}
|
|
|
|
$full_width = (isset($ctx["full_width"]) && $ctx["full_width"]);
|
|
$centralspaceload = (isset($ctx["centralspaceload"]) && $ctx["centralspaceload"]);
|
|
$html_h2_span_class = (isset($ctx["html_h2_span_class"]) && trim($ctx["html_h2_span_class"]) != "" ? trim($ctx["html_h2_span_class"]) : "fas fa-plus-circle");
|
|
|
|
$html_tile_class = array("FeaturedSimplePanel", "HomePanel", "DashTile", "FeaturedSimpleTile", "FeaturedCallToActionTile");
|
|
$html_contents_h2_class = array();
|
|
|
|
if($full_width)
|
|
{
|
|
$html_tile_class[] = "FullWidth";
|
|
$html_contents_h2_class[] = "MarginZeroAuto";
|
|
}
|
|
|
|
$onclick_fn = ($centralspaceload ? "CentralSpaceLoad(this, true);" : "ModalLoad(this, true, true);");
|
|
?>
|
|
<div id="FeaturedSimpleTile" class="<?php echo implode(" ", $html_tile_class); ?>">
|
|
<a href="<?php echo $url; ?>" onclick="return <?php echo $onclick_fn; ?>">
|
|
<div class="FeaturedSimpleTileContents">
|
|
<div class="FeaturedSimpleTileText">
|
|
<h2 class="<?php echo implode(" ", $html_contents_h2_class); ?>"><span class="<?php echo $html_h2_span_class; ?>"></span></h2>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Renders social media links in order to share a particular link
|
|
*
|
|
* @param string $url The URL to be shared on social media networks
|
|
*
|
|
* @return void
|
|
*/
|
|
function renderSocialMediaShareLinksForUrl($url)
|
|
{
|
|
global $social_media_links;
|
|
|
|
if (in_array("facebook", $social_media_links)) { ?>
|
|
<!-- Facebook -->
|
|
<a target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=<?php echo urlencode($url); ?>"><i class="fa-brands fa-xl fa-square-facebook" aria-hidden="true"></i></a>
|
|
<?php
|
|
}
|
|
|
|
if (in_array("twitter", $social_media_links)) { ?>
|
|
<!-- Twitter -->
|
|
<a target="_blank" href="https://twitter.com/intent/tweet?url=<?php echo urlencode($url); ?>"><i class="fa-brands fa-xl fa-square-x-twitter" aria-hidden="true"></i></a>
|
|
<?php
|
|
}
|
|
|
|
if (in_array("linkedin", $social_media_links)) { ?>
|
|
<!-- LinkedIn -->
|
|
<a target="_blank" href="https://www.linkedin.com/shareArticle?mini=true&url=<?php echo urlencode($url); ?>"><i class="fa-brands fa-xl fa-linkedin" aria-hidden="true"></i></a>
|
|
<?php
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Renders a lock button for a field - used to 'lock' metadata in upload_review_mode
|
|
*
|
|
* @param string $name The field identifier e.g. 'resource_type', '18'
|
|
* @param array $locked_fields - Array of locked field identifiers
|
|
*
|
|
* @return void
|
|
*/
|
|
function renderLockButton($name, $locked_fields=array())
|
|
{
|
|
global $lang;
|
|
?>
|
|
<button type="submit" class="lock_icon" id="lock_icon_<?php echo escape($name) ; ?>" onClick="toggleFieldLock('<?php echo escape($name) ; ?>');return false;" title="<?php echo escape($lang['lock-tooltip']); ?>">
|
|
<i aria-hidden="true" class="fa <?php if(in_array($name,$locked_fields)){echo "fa-lock";} else {echo "fa-unlock";} ?> fa-fw"></i>
|
|
</button>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Renders an image, with width and height specified for centering in div
|
|
*
|
|
* @param array $resource An array of resource data from search results
|
|
* @param string $img_url URL to image file
|
|
* @param string $display size to use - from search results
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_resource_image($resource, $img_url, $display="thumbs")
|
|
{
|
|
global $view_title_field;
|
|
|
|
list($width, $height, $margin) = calculate_image_display($resource, $img_url, $display);
|
|
|
|
$margin = (is_numeric($margin)) ? $margin . "px" : $margin;
|
|
|
|
// Produce a 'softer' colour for the loading preview (extracted colours tend to have a very high saturation)
|
|
if ( (isset($resource["image_red"]) && isset($resource["image_green"]) && isset($resource["image_blue"]))
|
|
&& (is_int_loose($resource["image_red"]) && is_int_loose($resource["image_green"]) && is_int_loose($resource["image_blue"])) )
|
|
{
|
|
$preview_red=100+($resource["image_red"]/1000)*156;
|
|
$preview_green=100+($resource["image_green"]/1000)*156;
|
|
$preview_blue=100+($resource["image_blue"]/1000)*156;
|
|
}
|
|
else
|
|
{
|
|
$preview_red=$preview_green=$preview_blue=255;
|
|
}
|
|
?>
|
|
<div class="ImageColourWrapper"
|
|
style="background-color: rgb(<?php echo $preview_red ?>,<?php echo $preview_green ?>,<?php echo $preview_blue ?>);
|
|
width:<?php echo $width ?>px;height:<?php echo $height ?>px;margin:<?php echo $margin ?> auto 0 auto;
|
|
<?php
|
|
$blurbleedstopper = hook("stopblurbleed");
|
|
if ($blurbleedstopper) { echo $blurbleedstopper; }
|
|
?>">
|
|
<img border="0" width="<?php echo $width ?>" height="<?php echo $height ?>"
|
|
src="<?php echo $img_url ?>"
|
|
alt="<?php echo str_replace(array("\"","'"),"",escape(i18n_get_translated(strip_tags(strip_tags_and_attributes($resource["field".$view_title_field] ?? ""))))); ?>"
|
|
/></div>
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* Calculations width, height and margin-top property for resource image to display in ResourcePanel
|
|
*
|
|
* @param array{'thumb_width': positive-int, 'thumb_height': positive-int} $imagedata
|
|
* @param string $img_url
|
|
* @param string $display
|
|
*
|
|
* @return array Returns a tuple of width, height and margin
|
|
*/
|
|
function calculate_image_display(array $imagedata, string $img_url, string $display="thumbs"): array
|
|
{
|
|
if(
|
|
'' != $imagedata['thumb_width']
|
|
&& '' != $imagedata['thumb_height']
|
|
&& $imagedata['thumb_width'] > 0
|
|
&& $imagedata['thumb_height'] > 0
|
|
)
|
|
{
|
|
$ratio = $imagedata["thumb_width"] / $imagedata["thumb_height"];
|
|
}
|
|
else
|
|
{
|
|
$size = $img_url != "" ? getimagesize($img_url) : [];
|
|
$ratio = isset($size[0]) ? $size[0] / $size[1] : 1;
|
|
}
|
|
|
|
switch($display)
|
|
{
|
|
case "xlthumbs":
|
|
$defaultwidth = 320;
|
|
$defaultheight = 320;
|
|
break;
|
|
|
|
case "thumbs":
|
|
$defaultwidth = 200;
|
|
$defaultheight = 200;
|
|
break;
|
|
|
|
case "list":
|
|
$defaultwidth = 40;
|
|
$defaultheight = 40;
|
|
break;
|
|
|
|
case "col":
|
|
$defaultwidth = $imagedata['thumb_width'];
|
|
$defaultheight = $imagedata['thumb_height'];
|
|
break;
|
|
|
|
default:
|
|
$defaultwidth = 75;
|
|
$defaultheight = 75;
|
|
break;
|
|
}
|
|
|
|
if ($ratio > 1)
|
|
{
|
|
$width = $defaultwidth;
|
|
$height = round($defaultwidth / $ratio);
|
|
$margin = floor(($defaultheight - $height ) / 2);
|
|
}
|
|
elseif ($ratio < 1)
|
|
{
|
|
# portrait image dimensions
|
|
$height = $defaultheight;
|
|
$width = round($defaultheight * $ratio);
|
|
$margin = floor(($defaultheight - $height ) / 2);
|
|
}
|
|
else
|
|
{
|
|
# square image or no image dimensions
|
|
$height = $defaultheight;
|
|
$width = $defaultwidth;
|
|
$margin = "auto";
|
|
}
|
|
|
|
return array($width, $height, $margin);
|
|
}
|
|
|
|
/**
|
|
* Render the share options (used on collection_share.php and resource_share.php)
|
|
*
|
|
* @param array $shareopts Array of share options. If not set will use the old getval() methods
|
|
* "password" bool Has a password been set for this share? (password will not actually be displayed)
|
|
* "editaccesslevel" int Current access level of share
|
|
* "editexpiration" string Current expiration date
|
|
* "editgroup" int ID of existing share group
|
|
* @return void
|
|
*/
|
|
function render_share_options($shareopts=array())
|
|
{
|
|
global $lang, $usergroup,$minaccess,$allowed_external_share_groups,$resource_share_expire_never;
|
|
global $resource_share_expire_days,$resource_share_expire_days_default;
|
|
|
|
$password = $shareopts['password'] ?? getval('password', '');
|
|
$editaccesslevel = $shareopts['editaccesslevel'] ?? getval('editaccesslevel', '');
|
|
$editexpiration = $shareopts['editexpiration'] ?? getval('editexpiration', null);
|
|
$editgroup = $shareopts['editgroup'] ?? getval('editgroup', '');
|
|
|
|
if (
|
|
$editexpiration === "" && $resource_share_expire_days_default > 0
|
|
|| $editexpiration != "" && date('Y-m-d', strtotime($editexpiration)) < date('Y-m-d',time())
|
|
) {
|
|
$editexpiration = date('Y-m-d',time() + (60*60*24*$resource_share_expire_days_default));
|
|
}
|
|
|
|
if(!hook('replaceemailaccessselector'))
|
|
{?>
|
|
<div class="Question" id="question_access">
|
|
<label for="archive"><?php echo escape($lang["access"]) ?></label>
|
|
<select class="stdwidth" name="access" id="access">
|
|
<?php
|
|
# List available access levels. The highest level must be the minimum user access level.
|
|
for ($n=$minaccess;$n<=1;$n++)
|
|
{
|
|
$selected = $editaccesslevel == $n;
|
|
?>
|
|
<option value="<?php echo $n?>" <?php if ($selected) {echo "selected";} ?>><?php echo escape($lang["access" . $n])?></option>
|
|
<?php
|
|
}
|
|
?>
|
|
</select>
|
|
<div class="clearerleft"> </div>
|
|
</div><?php
|
|
} #hook replaceemailaccessselector
|
|
|
|
if(!hook('replaceemailexpiryselector'))
|
|
{
|
|
?>
|
|
<div class="Question">
|
|
<label><?php echo escape($lang["expires"]) ?></label>
|
|
<select name="expires" class="stdwidth">
|
|
<?php
|
|
if($resource_share_expire_never)
|
|
{ ?>
|
|
<option value=""><?php echo escape($lang["never"])?></option><?php
|
|
}
|
|
for ($n=1;$n<=$resource_share_expire_days;$n++)
|
|
{
|
|
$date = time() + (60*60*24*$n);
|
|
$ymd_date = date('Y-m-d', $date);
|
|
$selected = (substr($editexpiration ?? "",0,10) == $ymd_date);
|
|
$date_text = nicedate($ymd_date,false,true);
|
|
$option_class = '';
|
|
$day_date = date('D', $date);
|
|
if (($day_date == "Sun") || ($day_date == "Sat"))
|
|
{
|
|
$option_class = 'optionWeekend';
|
|
}
|
|
?>
|
|
<option class="<?php echo $option_class ?>" value="<?php echo $ymd_date ?>" <?php if ($selected) {echo "selected";} ?>><?php echo $date_text ?></option>
|
|
<?php
|
|
} ?>
|
|
</select>
|
|
<div class="clearerleft"> </div>
|
|
</div>
|
|
<?php
|
|
}
|
|
if (checkperm("x"))
|
|
{
|
|
# Allow the selection of a user group to inherit permissions from
|
|
# for this share (the default is to use the current user's user group).
|
|
?>
|
|
<div class="Question">
|
|
<label for="groupselect"><?php echo escape($lang["share_using_permissions_from_user_group"]); ?></label>
|
|
<select id="groupselect" name="usergroup" class="stdwidth">
|
|
<?php $grouplist = get_usergroups(true);
|
|
foreach ($grouplist as $group)
|
|
{
|
|
if(!empty($allowed_external_share_groups) && !in_array($group['ref'], $allowed_external_share_groups))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
$selected = $editgroup == $group["ref"] || ($editgroup == "" && $usergroup == $group["ref"]);
|
|
?>
|
|
<option value="<?php echo $group["ref"]; ?>" <?php if ($selected) {echo "selected";} ?>><?php echo $group["name"]; ?></option>
|
|
<?php
|
|
}
|
|
?>
|
|
</select>
|
|
<div class="clearerleft"> </div>
|
|
</div>
|
|
<?php
|
|
}
|
|
elseif(!checkperm("x") && !empty($allowed_external_share_groups) && in_array($usergroup, $allowed_external_share_groups))
|
|
{
|
|
?>
|
|
<input type="hidden" name="usergroup" value="<?php echo $usergroup; ?>">
|
|
<?php
|
|
}
|
|
render_share_password_question(!$password);
|
|
hook("additionalresourceshare");
|
|
?>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Renders a metadata field selector
|
|
*
|
|
* @param string $label label for the field
|
|
* @param string $name name of form select
|
|
* @param array $ftypes Array of integer field type ids to include. See definitions.php. Will return all types if incorrect value or empty array supplied.
|
|
* @param string $class array CSS class to apply
|
|
* @param boolean $hidden optionally hide the question usng CSS display:none
|
|
* @param array $current Current selected value
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_field_selector_question($label, $name, $ftypes, $class = "stdwidth", $hidden = false, $current = 0)
|
|
{
|
|
global $lang;
|
|
$fieldtypefilter = "";
|
|
$parameters = array();
|
|
|
|
// Check only valid field types supplied. An empty array is valid i.e. return all types.
|
|
$ftypes = array_filter($ftypes, function($t) {global $field_types; return is_int($t) && in_array($t, array_keys($field_types));});
|
|
|
|
if(count($ftypes)>0)
|
|
{
|
|
$fieldtypefilter = " WHERE type IN (" . ps_param_insert(count($ftypes)) . ")";
|
|
$parameters = ps_param_fill($ftypes, "i");
|
|
}
|
|
|
|
$fields = ps_query("SELECT " . columns_in("resource_type_field") . " from resource_type_field " . (($fieldtypefilter=="")?"":$fieldtypefilter) . " ORDER BY title, name", $parameters, "schema");
|
|
|
|
echo "<div class='Question' id='" . escape($name) . "'" . ($hidden ? " style='display:none;border-top:none;'" : "") . ">";
|
|
echo "<label for='" . escape($name) . "' >" . escape($label) . "</label>";
|
|
echo "<select name='" . escape($name) . "' id='" . escape($name) . "' class='" . $class . "'>";
|
|
echo "<option value='' selected >" . escape($lang["select"]) . "</option>";
|
|
foreach($fields as $field)
|
|
{
|
|
$selected = ($field["ref"] == $current ? "selected" : "");
|
|
echo "<option value='{$field['ref']}' {$selected}>" . lang_or_i18n_get_translated($field['title'],'fieldtitle-') . "</option>";
|
|
}
|
|
echo "</select>";
|
|
echo "<div class='clearerleft'></div>";
|
|
echo "</div>";
|
|
}
|
|
|
|
|
|
/**
|
|
* Render a filter bar button
|
|
*
|
|
* @param string $text Button text
|
|
* @param string $attr Button attributes
|
|
* @param string $icon HTML for icon element (e.g "<i aria-hidden="true" class="fa fa-fw fa-upload"></i>")
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_filter_bar_button($text, $attr, $icon)
|
|
{
|
|
?>
|
|
<div class="InpageNavLeftBlock">
|
|
<button type="button" <?php echo $attr; ?>><?php echo $icon . escape($text); ?></button>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* Render "Upload here" button.
|
|
*
|
|
* This applies to search results that are either a special search "!collection" and/or consist of purely the following:
|
|
* - Nodes
|
|
* - Resource type
|
|
* - Workflow (archive) state
|
|
*
|
|
* For free text searches this SHOULD NOT work!
|
|
*
|
|
* @param array{search: string, restypes: string, archive: string, advsearch?: 'true'|''} $search_params
|
|
* @param boolean $return_params_only Exception to the rule! Rather than render, return the upload here params
|
|
*
|
|
* @return void|array
|
|
*/
|
|
function render_upload_here_button(array $search_params, $return_params_only = false)
|
|
{
|
|
if(!(checkperm('c') || checkperm('d')))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(!isset($search_params['search']) || !isset($search_params['restypes']) || !isset($search_params['archive']))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(
|
|
isset($search_params['search'])
|
|
&& (
|
|
mb_substr($search_params['search'], 0, 11) != '!collection'
|
|
&& empty(resolve_nodes_from_string($search_params['search']))
|
|
)
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
$upload_here_params = array();
|
|
|
|
$upload_endpoint = 'pages/upload_batch.php';
|
|
if(!$GLOBALS['upload_then_edit'])
|
|
{
|
|
$upload_endpoint = 'pages/edit.php';
|
|
$upload_here_params['ref'] = 0 - $GLOBALS['userref'];
|
|
$upload_here_params['uploader'] = $GLOBALS['top_nav_upload_type'];
|
|
}
|
|
|
|
$upload_here_params['upload_here'] = true;
|
|
$upload_here_params['search'] = $search_params['search'];
|
|
|
|
// Special search !collection
|
|
if (mb_substr($search_params['search'], 0, 11) == '!collection') {
|
|
$collection = explode(' ', $search_params['search']);
|
|
$collection = str_replace('!collection', '', $collection[0]);
|
|
$collection = explode(',', $collection);
|
|
$collection = (int) $collection[0];
|
|
|
|
//Check the user is able to upload to this collection before continuing
|
|
if(!collection_writeable($collection)) {return;}
|
|
|
|
$smart_collection = get_saved_searches($collection)[0] ?? [];
|
|
if ($smart_collection !== []) {
|
|
$search_params = array_merge(
|
|
$search_params,
|
|
array_intersect_key($smart_collection, array_flip(['search', 'restypes', 'archive']))
|
|
);
|
|
$upload_here_params['search'] = $search_params['search'];
|
|
} else {
|
|
$upload_here_params['collection_add'] = $collection;
|
|
}
|
|
}
|
|
|
|
if (isset($search_params['advsearch']) && $search_params['advsearch'] == 'true')
|
|
{
|
|
$upload_here_params['advsearch'] = 'true';
|
|
}
|
|
|
|
// If resource types is a list then always select the first resource type the user has access to
|
|
$resource_types = explode(',', $search_params['restypes']);
|
|
foreach($resource_types as $resource_type)
|
|
{
|
|
if(!checkperm("XU{$resource_type}"))
|
|
{
|
|
$upload_here_params['resource_type'] = $resource_type;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Archive can be a list (e.g from advanced search) so always select the first archive state user access to,
|
|
// favouring the Active one
|
|
$search_archive = explode(',', $search_params['archive']);
|
|
$use_default = false;
|
|
|
|
if (count($search_archive) == 1 && $search_archive[0] == "")
|
|
{
|
|
$search_archive = array();
|
|
$use_default = true;
|
|
}
|
|
|
|
// Check access to Active state
|
|
if(in_array(0, $search_archive) && checkperm("e0"))
|
|
{
|
|
$upload_here_params['status'] = 0;
|
|
$search_archive = array();
|
|
}
|
|
// Check remaining states
|
|
foreach($search_archive as $archive)
|
|
{
|
|
if($archive == '' || !is_numeric($archive))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(checkperm("e{$archive}"))
|
|
{
|
|
$upload_here_params['status'] = $archive;
|
|
$search_archive = array();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (count($search_archive) != 0 || $use_default)
|
|
{
|
|
// None of the supplied archive states were accessible with e permission so use default.
|
|
$upload_here_params['status'] = get_default_archive_state();
|
|
}
|
|
|
|
// Option to return out just the upload params
|
|
if ($return_params_only)
|
|
{
|
|
return $upload_here_params;
|
|
}
|
|
|
|
$upload_here_url = generateURL("{$GLOBALS['baseurl']}/{$upload_endpoint}", $upload_here_params);
|
|
$attributes = "onclick=\"CentralSpaceLoad('{$upload_here_url}');\"";
|
|
|
|
render_filter_bar_button($GLOBALS['lang']['upload_here'], $attributes, UPLOAD_ICON);
|
|
}
|
|
|
|
/**
|
|
* Renders the trash bin. This is used to delete dash tiles and remove resources from collections
|
|
*
|
|
* @param string $type type of trash_bin
|
|
*
|
|
* @return string|void
|
|
*/
|
|
|
|
function render_trash($type, $deletetext,$forjs=false)
|
|
{
|
|
$trash_html = '<div id="' . $type . '_bin" class="trash_bin ui-droppable ui-droppable-active ui-state-hover"><span class="trash_bin_text"><i class="fa fa-trash" aria-hidden="true"></i></span></div>
|
|
<div id="trash_bin_delete_dialog" style="display:none;"></div>
|
|
<div id="delete_permanent_dialog" style="display:none;text-align:left;">' . $deletetext . '</div>
|
|
';
|
|
if($forjs)
|
|
{
|
|
return str_replace(array("\r","\n"),"",$trash_html);
|
|
}
|
|
else
|
|
{
|
|
echo $trash_html;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Renders the browse bar
|
|
*
|
|
* @return void
|
|
*/
|
|
|
|
function render_browse_bar()
|
|
{
|
|
global $lang, $browse_bar_workflow, $enable_themes;
|
|
$bb_html = '<div id="BrowseBarContainer" style="display:none;">';
|
|
$bb_html .= '<div id="BrowseBar" class="BrowseBar">';
|
|
$bb_html .= '<div id="BrowseBarContent" >';
|
|
|
|
//Browse row template
|
|
// script will replace %BROWSE_TYPE%, %BROWSE_EXPAND_CLASS%, %BROWSE_CLASS% %BROWSE_LEVEL%, %BROWSE_EXPAND%, %BROWSE_NAME%, %BROWSE_TEXT%, %BROWSE_ID%
|
|
$bb_html .= "
|
|
<div id='BrowseBarTemplate' style='display: none;'>
|
|
<div class='BrowseBarItem BrowseRowOuter %BROWSE_DROP%' data-browse-id='%BROWSE_ID%' data-browse-parent='%BROWSE_PARENT%' data-browse-loaded='0' data-browse-status='closed' data-browse-level='%BROWSE_LEVEL%' style='display: none;'>
|
|
<div class='BrowseRowInner' >
|
|
%BROWSE_INDENT%
|
|
%BROWSE_EXPAND%
|
|
%BROWSE_TEXT%
|
|
%BROWSE_REFRESH%
|
|
</div><!-- End of BrowseRowInner -->
|
|
</div><!-- End of BrowseRowOuter -->
|
|
</div><!-- End of BrowseBarTemplate -->
|
|
";
|
|
|
|
// Add root elements
|
|
$bb_html .= generate_browse_bar_item("R", $lang['browse_by_tag']);
|
|
if($enable_themes)
|
|
{
|
|
$bb_html .= generate_browse_bar_item("FC", $lang["themes"]);
|
|
}
|
|
if(!checkperm('b'))
|
|
{
|
|
$bb_html .= generate_browse_bar_item("C", $lang["mycollections"]);
|
|
}
|
|
|
|
if($browse_bar_workflow)
|
|
{
|
|
$bb_html .= generate_browse_bar_item("WF", $lang['browse_by_workflow_state']);
|
|
}
|
|
|
|
$bb_html .= '</div><!-- End of BrowseBarContent -->
|
|
</div><!-- End of BrowseBar -->
|
|
</div><!-- End of BrowseBarContainer -->';
|
|
echo $bb_html;
|
|
|
|
echo '<script>
|
|
b_loading = new Array();
|
|
// Expand tree to previous state based on stored cookie
|
|
jQuery(document).ready(function()
|
|
{
|
|
ReloadBrowseBar();
|
|
});
|
|
</script>';
|
|
}
|
|
|
|
|
|
/**
|
|
* Generates a root row item for the browse bar
|
|
*
|
|
* @return string $html
|
|
*/
|
|
function generate_browse_bar_item($id, $text)
|
|
{
|
|
$html = '<div class="BrowseBarItem BrowseRowOuter BrowseBarRoot" data-browse-id="' . $id . '" data-browse-parent="root" data-browse-loaded="0" data-browse-status="closed" data-browse-level="0" >';
|
|
$html .= '<div class="BrowseRowInner" >';
|
|
|
|
$html .= '<div class="BrowseBarStructure">
|
|
<a href="#" class="browse_expand browse_closed" onclick="toggleBrowseElements(\'' . $id . '\',false,true);" ></a>
|
|
</div><!-- End of BrowseBarStructure -->';
|
|
$html .= '<div onclick="toggleBrowseElements(\'' . $id . '\',false,true);" class="BrowseBarLink" >' . $text . '</div>';
|
|
|
|
$html .= '<a href="#" class="BrowseRefresh " onclick="toggleBrowseElements(\'' . $id . '\',true, true);" ><i class="fas fa-sync reloadicon"></i></a>';
|
|
|
|
$html .= "</div><!-- End of BrowseRowInner -->
|
|
</div><!-- End of BrowseRowOuter -->";
|
|
return $html;
|
|
}
|
|
|
|
/**
|
|
* Generates a help icon that opens the relevant Knowledge Base article in a modal
|
|
*
|
|
* @param string $page Knowledge Base article to display, leave blank to show the Knowledge Base homepage
|
|
* @param boolean $return_string Set to true to return the html as a single line string, False will cause the function to echo the html
|
|
*
|
|
* @return mixed if $return_string=true return is string, else void
|
|
*/
|
|
function render_help_link($page='',$return_string=false)
|
|
{
|
|
global $lang,$help_modal,$baseurl;
|
|
|
|
// Build html for link into a string
|
|
$help_link_html = '<a ';
|
|
$help_link_html .= 'href="' . $baseurl . '/pages/help.php?page=' . escape($page) . '" ';
|
|
$help_link_html .= 'title="' . escape($lang["help-tooltip"]) . '" ';
|
|
$help_link_html .= 'class="HelpLink" ';
|
|
if ($help_modal)
|
|
{ $help_link_html .= 'onClick="return ModalLoad(this, true);" ';}
|
|
else
|
|
{ $help_link_html .= 'target="_blank" ';}
|
|
$help_link_html .= '>';
|
|
$help_link_html .= '<i aria-hidden="true" class="fa fa-fw fa-question-circle"></i>';
|
|
$help_link_html .= '</a>';
|
|
|
|
if ($return_string===false) {echo $help_link_html;}
|
|
else {return $help_link_html;}
|
|
}
|
|
|
|
|
|
/**
|
|
* Render generic Question div (including clearleft)
|
|
*
|
|
* @var string $id Div ID if required. Set to empty string if not needed.
|
|
* @var callable $render_content Content renderer
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_question_div($id, callable $render_content)
|
|
{
|
|
$id = (trim($id) !== "" ? 'id="' . escape(trim($id)) . '"' : "");
|
|
?>
|
|
<div <?php echo $id; ?> class="Question">
|
|
<?php $render_content(); ?>
|
|
<div class="clearerleft"></div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* Render custom fields (NOT metadata fields)
|
|
*
|
|
* @param array $cfs Custom fields information (as returned by process_custom_fields_submission function)
|
|
*
|
|
* @return true
|
|
*/
|
|
function render_custom_fields(array $cfs)
|
|
{
|
|
return array_walk($cfs, function($field, $i)
|
|
{
|
|
render_question_div("Question_{$field["html_properties"]["id"]}", function() use ($field)
|
|
{
|
|
$field_id = $field["html_properties"]["id"];
|
|
$field_name = $field["html_properties"]["name"];
|
|
$field_value = $field["value"];
|
|
|
|
$show_help_text = isset($field['help_text']) && trim($field['help_text'] !== '');
|
|
$help_js = $show_help_text
|
|
? sprintf('onblur="HideHelp(\'%1$s\');" onfocus="ShowHelp(\'%1$s\');"', escape($field_id))
|
|
: '';
|
|
|
|
global $FIXED_LIST_FIELD_TYPES;
|
|
$selected_options_hashes = array_map(function($opt) use ($field_id)
|
|
{
|
|
return md5("{$field_id}_{$opt}");
|
|
}, (in_array($field["type"], $FIXED_LIST_FIELD_TYPES) ? $field["selected_options"] : array()));
|
|
|
|
$required_html = ($field["required"] ? "<sup>*</sup>" : "");
|
|
?>
|
|
<label for="<?php echo escape($field_id); ?>"><?php echo escape(i18n_get_translated($field["title"])) . $required_html; ?></label>
|
|
<?php
|
|
switch($field["type"])
|
|
{
|
|
case FIELD_TYPE_TEXT_BOX_MULTI_LINE:
|
|
?>
|
|
<textarea id="<?php echo escape($field_id); ?>"
|
|
class="stdwidth MultiLine"
|
|
name="<?php echo escape($field_name); ?>"
|
|
rows=6
|
|
cols=50><?php echo escape($field_value); ?></textarea>
|
|
<?php
|
|
break;
|
|
|
|
case FIELD_TYPE_DROP_DOWN_LIST:
|
|
?>
|
|
<select id="<?php echo escape($field_id); ?>" class="stdwidth" name="<?php echo escape($field_name); ?>">
|
|
<?php
|
|
foreach($field["options"] as $f_option)
|
|
{
|
|
$computed_value = md5("{$field_id}_{$f_option}");
|
|
$label = escape(i18n_get_translated($f_option));
|
|
$extra_attributes = (in_array($computed_value, $selected_options_hashes) ? " selected" : "");
|
|
|
|
echo render_dropdown_option($computed_value, $label, array(), $extra_attributes);
|
|
}
|
|
?>
|
|
</select>
|
|
<?php
|
|
break;
|
|
|
|
case FIELD_TYPE_CHECK_BOX_LIST:
|
|
?>
|
|
<div>
|
|
<?php
|
|
foreach($field["options"] as $f_option)
|
|
{
|
|
$computed_value = md5("{$field_id}_{$f_option}");
|
|
$label = escape(i18n_get_translated($f_option));
|
|
$checked = (in_array($computed_value, $selected_options_hashes) ? " checked" : "");
|
|
?>
|
|
<div class="Inline">
|
|
<input type="checkbox" name="<?php echo escape($field_name); ?>" value="<?php echo $computed_value; ?>"<?php echo $checked; ?>> <?php echo $label; ?>
|
|
</div>
|
|
<?php
|
|
}
|
|
?>
|
|
<div class="clearerleft"></div>
|
|
</div>
|
|
<?php
|
|
break;
|
|
|
|
case FIELD_TYPE_TEXT_BOX_SINGLE_LINE:
|
|
default:
|
|
// Allow plugins to render (their own) custom field types
|
|
if (hook('render_custom_fields_default_case_override', '', [$field]) !== false) {
|
|
break;
|
|
}
|
|
?>
|
|
<input type=text
|
|
id="<?php echo escape($field_id); ?>"
|
|
class="stdwidth"
|
|
name="<?php echo escape($field_name); ?>"
|
|
value="<?php echo escape($field_value); ?>"
|
|
<?php echo $help_js; ?>
|
|
>
|
|
<?php
|
|
break;
|
|
}
|
|
|
|
if ($show_help_text) {
|
|
?>
|
|
<div id="help_<?php echo escape($field_id); ?>" class="FormHelp" style="display: none;">
|
|
<div class="FormHelpInner"><?php echo escape($field['help_text']); ?></div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
if(isset($field["error"]) && trim($field["error"]) != "")
|
|
{
|
|
?>
|
|
<div class="FormError"><?php echo escape($field["error"]); ?></div>
|
|
<?php
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
/**
|
|
* Generates HTML for the "X Selected" in the search results found part pointing to the special collection COLLECTION_TYPE_SELECTION
|
|
*
|
|
* @param integer $i Counter to display
|
|
*
|
|
* @return string Returns HTML
|
|
*/
|
|
function render_selected_resources_counter($i)
|
|
{
|
|
global $baseurl, $lang, $USER_SELECTION_COLLECTION;
|
|
|
|
$url = generateURL("{$baseurl}", array("c" => $USER_SELECTION_COLLECTION));
|
|
|
|
$x_selected = '<span class="Selected">' . number_format($i) . "</span> {$lang["selected"]}";
|
|
return "<a href=\"{$url}\" class=\"SelectionCollectionLink\" onclick=\"return CentralSpaceLoad(this, true);\">{$x_selected}</a>";
|
|
}
|
|
|
|
|
|
/**
|
|
* Renders the "Edit selected" button. This is using the special 'COLLECTION_TYPE_SELECTION' collection
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_edit_selected_btn()
|
|
{
|
|
global $baseurl_short, $lang, $USER_SELECTION_COLLECTION, $restypes, $archive;
|
|
|
|
$search = "!collection{$USER_SELECTION_COLLECTION}";
|
|
# Editable_only=true (so returns editable resources only)
|
|
$editable_resources = do_search($search, $restypes, "resourceid", $archive, -1, "desc", false, 0, false, false, "", false, false, true, true);
|
|
# Editable_only=false (so returns resources whether editable or not)
|
|
$all_resources = do_search($search, $restypes, "resourceid", $archive, -1, "desc", false, 0, false, false, "", false, false, true, false);
|
|
|
|
# If there are no editable resources then don't render the edit selected button
|
|
|
|
# Setup count of editable resources
|
|
$editable_resources_count = 0;
|
|
$editable_resource_refs=array();
|
|
if(is_array($editable_resources))
|
|
{
|
|
$editable_resources_count = count($editable_resources);
|
|
$editable_resource_refs=array_column($editable_resources,"ref");
|
|
}
|
|
|
|
# Setup count of editable and non-editable resources
|
|
$all_resources_count = 0;
|
|
$all_resource_refs=array();
|
|
if(is_array($all_resources))
|
|
{
|
|
$all_resources_count = count($all_resources);
|
|
$all_resource_refs=array_column($all_resources,"ref");
|
|
}
|
|
|
|
# If both counts are zero then there cannot be any editable resources, so no edit selected button
|
|
if($editable_resources_count == 0 && $all_resources_count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
# If not all selected resources are editable then the edit selected button may be inappropriate
|
|
if($editable_resources_count != $all_resources_count)
|
|
{
|
|
# Counts differ meaning there are non-editable resources
|
|
$non_editable_resource_refs=array_diff($all_resource_refs,$editable_resource_refs);
|
|
|
|
# Is grant edit present for all non-editables?
|
|
foreach($non_editable_resource_refs as $non_editable_ref)
|
|
{
|
|
if ( !hook('customediteaccess','',array($non_editable_ref)) ) { return; }
|
|
}
|
|
|
|
# All non_editables have grant edit
|
|
# Don't return as edit button can be rendered
|
|
}
|
|
|
|
$batch_edit_url = generateURL(
|
|
"{$baseurl_short}pages/edit.php",
|
|
array(
|
|
"search" => $search,
|
|
"collection" => $USER_SELECTION_COLLECTION,
|
|
"restypes" => $restypes,
|
|
"order_by" => "resourceid",
|
|
"archive" => $archive,
|
|
"sort" => "desc",
|
|
"daylimit" => "",
|
|
"editsearchresults" => "true",
|
|
"modal" => "true",
|
|
));
|
|
|
|
$attributes = " id=\"EditSelectedResourcesBtn\"";
|
|
$attributes .= " onclick=\"ModalLoad('{$batch_edit_url}', true);\"";
|
|
|
|
render_filter_bar_button($lang["edit_selected"], $attributes, ICON_EDIT);
|
|
}
|
|
|
|
|
|
/**
|
|
* Renders the "Clear selected" button. This is using the special 'COLLECTION_TYPE_SELECTION' collection
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_clear_selected_btn()
|
|
{
|
|
global $lang, $USER_SELECTION_COLLECTION, $CSRF_token_identifier, $usersession;
|
|
|
|
$attributes = " id=\"ClearSelectedResourcesBtn\" class=\"ClearSelectedButton\"";
|
|
$attributes .= " onclick=\"ClearSelectionCollection(this);\"";
|
|
$attributes .= " data-csrf-token-identifier=\"{$CSRF_token_identifier}\"";
|
|
$attributes .= " data-csrf-token=\"" . generateCSRFToken($usersession, "clear_selected_btn_{$USER_SELECTION_COLLECTION}") . "\"";
|
|
|
|
render_filter_bar_button($lang["clear_selected"], $attributes, ICON_REMOVE);
|
|
}
|
|
|
|
|
|
/**
|
|
* Render the actions specific to when a user selected resources (using the special "COLLECTION_TYPE_SELECTION" collection)
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_selected_collection_actions()
|
|
{
|
|
global $USER_SELECTION_COLLECTION, $usercollection, $usersession, $lang, $CSRF_token_identifier, $search,
|
|
$render_actions_extra_options, $render_actions_filter, $resources_count, $result;
|
|
|
|
$orig_resources_count = $resources_count;
|
|
$orig_search = $search;
|
|
$search = "!collection{$USER_SELECTION_COLLECTION}";
|
|
|
|
$orig_result = $result;
|
|
$result = get_collection_resources_with_data($USER_SELECTION_COLLECTION);
|
|
|
|
$selected_resources = array_column($result, "ref");
|
|
$resources_count = count($selected_resources);
|
|
$usercollection_resources = get_collection_resources($usercollection);
|
|
$refs_to_remove = count(array_intersect($selected_resources, $usercollection_resources));
|
|
$collection_data = get_collection($USER_SELECTION_COLLECTION);
|
|
|
|
$valid_selection_collection_actions = array(
|
|
"relate_all",
|
|
"save_search_items_to_collection",
|
|
"remove_selected_from_collection",
|
|
"search_items_disk_usage",
|
|
"csv_export_results_metadata",
|
|
"share_collection",
|
|
"download_collection",
|
|
"license_batch",
|
|
"consent_batch",
|
|
'delete_all_in_collection',
|
|
);
|
|
|
|
if($refs_to_remove > 0)
|
|
{
|
|
$callback_csrf_token = generateCSRFToken($usersession, "collection_remove_resources");
|
|
$render_actions_extra_options = array(
|
|
array(
|
|
"value" => "remove_selected_from_collection",
|
|
"label" => $lang["remove_selected_from_collection"],
|
|
"data_attr" => array(
|
|
"callback" => "RemoveSelectedFromCollection('{$CSRF_token_identifier}', '{$callback_csrf_token}');",
|
|
),
|
|
"category" => ACTIONGROUP_COLLECTION,
|
|
),
|
|
);
|
|
}
|
|
$render_actions_filter = function($action) use ($valid_selection_collection_actions)
|
|
{
|
|
return in_array($action["value"], $valid_selection_collection_actions);
|
|
};
|
|
|
|
// override the language for actions as it's now specific to a selection of resources
|
|
$lang["relateallresources"] = $lang["relate_selected_resources"];
|
|
$lang["savesearchitemstocollection"] = $lang["add_selected_to_collection"];
|
|
$lang["searchitemsdiskusage"] = $lang["selected_items_disk_usage"];
|
|
$lang["share"] = $lang["share_selected"];
|
|
$lang['deleteallresourcesfromcollection'] = $lang['deleteselectedfromcollection'];
|
|
$lang["deleteallsure"] = $lang['deleteallselectedsure'];
|
|
|
|
render_actions($collection_data, true, false);
|
|
|
|
$search = $orig_search;
|
|
$result = $orig_result;
|
|
$resources_count = $orig_resources_count;
|
|
}
|
|
|
|
|
|
// Render a select input for a user's collections
|
|
function render_user_collection_select($name = "collection", $collections=array(), $selected=0, $classes = "", $onchangejs = "")
|
|
{
|
|
global $userref,$hidden_collections,$active_collections,$lang;
|
|
if(count($collections) == 0)
|
|
{
|
|
$collections = get_user_collections($userref);
|
|
}
|
|
|
|
echo "<select name=\"" . $name . "\" id=\"" . $name . "\" " . ($onchangejs != "" ? (" onchange=\"" . escape($onchangejs) . "\"") : "") . ($classes != "" ? (" class=\"" . escape($classes) . "\"") : "") . ">";
|
|
echo "<option value=\"0\">" . escape($lang["select"]) . "</option>";
|
|
for ($n=0;$n<count($collections);$n++)
|
|
{
|
|
if(in_array($collections[$n]['ref'],$hidden_collections))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
#show only active collections if a start date is set for $active_collections
|
|
if (strtotime($collections[$n]['created']) > ((isset($active_collections))?strtotime($active_collections):1))
|
|
{
|
|
echo "<option value=\"" . $collections[$n]["ref"] . "\" " . ($selected==$collections[$n]["ref"] ? "selected" : "") . ">" . i18n_get_collection_name($collections[$n]) . "</option>";
|
|
}
|
|
}
|
|
|
|
echo "</select>";
|
|
}
|
|
|
|
|
|
/**
|
|
* Render CSRF information as data attributes. Useful to allow JS to run state changing operations
|
|
*/
|
|
function render_csrf_data_attributes($ident)
|
|
{
|
|
global $CSRF_token_identifier, $usersession;
|
|
|
|
$token = generateCSRFToken($usersession, $ident);
|
|
return "data-csrf-token-identifier=\"{$CSRF_token_identifier}\" data-csrf-token=\"{$token}\"";
|
|
}
|
|
|
|
|
|
/**
|
|
* Check display condition for a field.
|
|
*
|
|
* @uses get_nodes()
|
|
* @uses extract_node_options()
|
|
* @uses get_resource_nodes()
|
|
* @uses get_node_by_name()
|
|
*
|
|
* @param integer $n Question sequence number on the rendered form
|
|
* @param array $field Field on which we check display conditions
|
|
* @param array $fields Resource field data and properties as returned by get_resource_field_data()
|
|
* @param boolean $render_js Set to TRUE to render the client side code for checking display conditions or FALSE otherwise
|
|
* @param integer $resource_ref Resource reference for which the display condition applies
|
|
*
|
|
* @return boolean Returns TRUE if no display condition or if field should be displayed or FALSE if field should not be displayed.
|
|
*/
|
|
function check_display_condition($n, array $field, array $fields, $render_js, int $resource_ref)
|
|
{
|
|
debug_function_call(__FUNCTION__, [$n, $field['ref'], ['ignored on purpose - too verbose'], $render_js]);
|
|
global $required_fields_exempt, $blank_edit_template, $ref, $use, $FIXED_LIST_FIELD_TYPES;
|
|
|
|
if(trim((string) $field['display_condition']) == "")
|
|
{
|
|
return true; # This field does not have a display condition, so it should be displayed
|
|
}
|
|
|
|
debug(sprintf('$use = %s', json_encode($use)));
|
|
|
|
// Assume the candidate field is to be displayed
|
|
$displaycondition = true;
|
|
// Break down into array of conditions
|
|
$conditions = explode(';', $field['display_condition']);
|
|
$condref = 0;
|
|
$scriptconditions = array();
|
|
|
|
// Need all field data to check display conditions
|
|
global $display_check_data;
|
|
if(!is_array($display_check_data))
|
|
{
|
|
$display_check_data = get_resource_field_data($use,false,false);
|
|
debug('Loaded $display_check_data');
|
|
}
|
|
|
|
// On upload, check against the posted nodes as save_resource_data() saves nodes after going through all the fields
|
|
$user_set_values = getval('nodes', [], false, 'is_array');
|
|
debug(sprintf('$user_set_values = %s', json_encode($user_set_values)));
|
|
|
|
foreach ($conditions as $condition) # Check each condition
|
|
{
|
|
debug(sprintf('field #%s - checking condition "%s"', $field['ref'], $condition));
|
|
$displayconditioncheck = false;
|
|
|
|
// Break this condition down into fieldname $s[0] and value(s) $s[1]
|
|
$s = explode('=', $condition);
|
|
|
|
// Process all fields which are referenced by display condition(s) on the candidate field
|
|
// For each referenced field, render javascript to trigger when the referenced field changes
|
|
for ($cf=0;$cf<count($display_check_data);$cf++) # Check each field to see if needs to be checked
|
|
{
|
|
// Work out nodes submitted by user, if any
|
|
$ui_selected_node_values = array();
|
|
if(
|
|
isset($user_set_values[$display_check_data[$cf]['ref']])
|
|
&& !is_array($user_set_values[$display_check_data[$cf]['ref']])
|
|
&& $user_set_values[$display_check_data[$cf]['ref']] != ''
|
|
&& is_numeric($user_set_values[$display_check_data[$cf]['ref']])
|
|
)
|
|
{
|
|
$ui_selected_node_values[] = $user_set_values[$display_check_data[$cf]['ref']];
|
|
debug(sprintf('$ui_selected_node_values = %s', json_encode($ui_selected_node_values)));
|
|
}
|
|
elseif(isset($user_set_values[$display_check_data[$cf]['ref']]) && is_array($user_set_values[$display_check_data[$cf]['ref']]))
|
|
{
|
|
$ui_selected_node_values = $user_set_values[$display_check_data[$cf]['ref']];
|
|
debug(sprintf('$ui_selected_node_values = %s', json_encode($ui_selected_node_values)));
|
|
}
|
|
|
|
// Does the fieldname on this condition match the field being processed
|
|
if($s[0] == $display_check_data[$cf]['name']) # this field needs to be checked
|
|
{
|
|
$display_check_data[$cf]['nodes'] = get_nodes($display_check_data[$cf]['ref'], null, (FIELD_TYPE_CATEGORY_TREE == $display_check_data[$cf]['type'] ? true : false));
|
|
|
|
$scriptconditions[$condref]['field'] = $display_check_data[$cf]['ref'];
|
|
$scriptconditions[$condref]['type'] = $display_check_data[$cf]['type'];
|
|
|
|
$checkvalues=$s[1];
|
|
debug("\$checkvalues = {$checkvalues}");
|
|
// Break down values delimited with pipe characters
|
|
$validvalues = explode("|",$checkvalues);
|
|
$validvalues = array_map("i18n_get_translated",$validvalues);
|
|
debug(sprintf('$validvalues = %s', json_encode($validvalues)));
|
|
$scriptconditions[$condref]['valid'] = array();
|
|
|
|
// Use submitted values if field was shown and user has edit access to it
|
|
if(getval("field_" . $fields[$n]['ref'] . "_displayed","") == "block" && metadata_field_edit_access($fields[$n]['ref']))
|
|
{
|
|
$v = $ui_selected_node_values;
|
|
}
|
|
else
|
|
{
|
|
$v = trim_array(get_resource_nodes($ref, $display_check_data[$cf]['ref']));
|
|
}
|
|
|
|
// If blank edit template is used, on upload form the dependent fields should be hidden
|
|
if($blank_edit_template && $ref < 0 && $use == $ref)
|
|
{
|
|
$v = array();
|
|
}
|
|
|
|
foreach($validvalues as $validvalue)
|
|
{
|
|
$found_validvalue = get_node_by_name($display_check_data[$cf]['nodes'], $validvalue);
|
|
|
|
if(0 != count($found_validvalue))
|
|
{
|
|
$scriptconditions[$condref]['valid'][] = (string)$found_validvalue['ref'];
|
|
|
|
if(in_array($found_validvalue['ref'], $v))
|
|
{
|
|
$displayconditioncheck = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!$displayconditioncheck)
|
|
{
|
|
$displaycondition = false;
|
|
$required_fields_exempt[]=$field["ref"];
|
|
}
|
|
|
|
// Skip rendering the JS calls to checkDisplayCondition functions
|
|
// Skip if user does not have access to the master (parent) field
|
|
if(!$render_js || !in_array($display_check_data[$cf]['ref'], array_column($fields,"ref")))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Check display conditions
|
|
// Certain fixed list types allow for multiple nodes to be passed at the same time
|
|
|
|
// Generate a javascript function specific to the field with the display condition
|
|
// This function will be invoked whenever a field referenced by the display condition changes
|
|
if(in_array($display_check_data[$cf]['type'], $FIXED_LIST_FIELD_TYPES))
|
|
{
|
|
if(FIELD_TYPE_CATEGORY_TREE == $display_check_data[$cf]['type'])
|
|
{
|
|
?>
|
|
<script>
|
|
jQuery(document).ready(function()
|
|
{
|
|
<?php
|
|
if($GLOBALS["multiple"] === false)
|
|
{
|
|
?>
|
|
checkDisplayCondition<?php echo $field['ref']; ?>();
|
|
<?php
|
|
}
|
|
?>
|
|
jQuery('#CentralSpace').on('categoryTreeChanged', function(e,node)
|
|
{
|
|
checkDisplayCondition<?php echo $field['ref']; ?>();
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
|
|
// Move on to the next field now
|
|
continue;
|
|
}
|
|
elseif(FIELD_TYPE_DYNAMIC_KEYWORDS_LIST == $display_check_data[$cf]['type'])
|
|
{
|
|
?>
|
|
<script>
|
|
jQuery(document).ready(function()
|
|
{
|
|
<?php
|
|
if($GLOBALS["multiple"] === false)
|
|
{
|
|
?>
|
|
console.debug('[document.ready] Going to call checkDisplayCondition<?php echo $field['ref']; ?>()');
|
|
checkDisplayCondition<?php echo $field['ref']; ?>();
|
|
<?php
|
|
}
|
|
?>
|
|
jQuery('#CentralSpace').on('dynamicKeywordChanged', function(e,node)
|
|
{
|
|
console.debug('#CentralSpace-on-dynamicKeywordChanged for field #<?php echo $field['ref']; ?>');
|
|
checkDisplayCondition<?php echo $field['ref']; ?>();
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
|
|
// Move on to the next field now
|
|
continue;
|
|
}
|
|
|
|
$checkname = "nodes[{$display_check_data[$cf]['ref']}][]";
|
|
|
|
if(FIELD_TYPE_RADIO_BUTTONS == $display_check_data[$cf]['type'])
|
|
{
|
|
$checkname = "nodes[{$display_check_data[$cf]['ref']}]";
|
|
}
|
|
|
|
$jquery_selector = "input[name=\"{$checkname}\"]";
|
|
|
|
if(FIELD_TYPE_DROP_DOWN_LIST == $display_check_data[$cf]['type'])
|
|
{
|
|
$checkname = "nodes[{$display_check_data[$cf]['ref']}]";
|
|
$jquery_selector = "select[name=\"{$checkname}\"]";
|
|
}
|
|
?>
|
|
<script type="text/javascript">
|
|
jQuery(document).ready(function()
|
|
{
|
|
<?php
|
|
if($GLOBALS["multiple"] === false)
|
|
{
|
|
?>
|
|
checkDisplayCondition<?php echo $field['ref']; ?>();
|
|
<?php
|
|
}
|
|
?>
|
|
jQuery('<?php echo $jquery_selector; ?>').change(function ()
|
|
{
|
|
checkDisplayCondition<?php echo $field['ref']; ?>();
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
else
|
|
{
|
|
?>
|
|
<script type="text/javascript">
|
|
jQuery(document).ready(function()
|
|
{
|
|
<?php
|
|
if($GLOBALS["multiple"] === false)
|
|
{
|
|
?>
|
|
checkDisplayCondition<?php echo $field['ref']; ?>();
|
|
<?php
|
|
}
|
|
?>
|
|
jQuery('#field_<?php echo $display_check_data[$cf]["ref"]; ?>').change(function ()
|
|
{
|
|
checkDisplayCondition<?php echo $field['ref']; ?>();
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
}
|
|
|
|
} # see if next field needs to be checked
|
|
$condref++;
|
|
|
|
} # check next condition
|
|
|
|
if($render_js)
|
|
{
|
|
$question_id = '#question_' . $n . ($GLOBALS["multiple"] === true ? '' : '_' . $resource_ref);
|
|
?>
|
|
<script type="text/javascript">
|
|
function checkDisplayCondition<?php echo $field["ref"];?>()
|
|
{
|
|
console.debug('(<?php echo str_replace(dirname(__DIR__), '', __FILE__) . ':' . __LINE__?>) checkDisplayCondition<?php echo $field["ref"]; ?>()');
|
|
|
|
if (jQuery('#field_<?php echo (int) $field["ref"]; ?>_displayed').length === 0)
|
|
{
|
|
console.debug('Skipping - field <?php echo (int) $field["ref"]; ?> not found on form');
|
|
return;
|
|
}
|
|
|
|
// Get current display state for governed field ("block" or "none")
|
|
field<?php echo $field['ref']; ?>status = jQuery('<?php echo escape($question_id); ?>').css('display');
|
|
newfield<?php echo $field['ref']; ?>status = 'none';
|
|
|
|
// Assume visible by default
|
|
field<?php echo $field['ref']; ?>visibility = true;
|
|
<?php
|
|
foreach($scriptconditions as $scriptcondition)
|
|
{
|
|
/* Example of $scriptconditions:
|
|
[{"field":"73","type":"3","display_as_dropdown":"0","valid":["267","266"]}]
|
|
*/
|
|
?>
|
|
|
|
field<?php echo $field['ref']; ?>valuefound = false;
|
|
fieldokvalues<?php echo $scriptcondition['field']; ?> = <?php echo json_encode($scriptcondition['valid']); ?>;
|
|
console.debug('[checkDisplayCondition<?php echo $field["ref"]; ?>] fieldokvalues<?php echo $scriptcondition['field']; ?> = %o', fieldokvalues<?php echo $scriptcondition['field']; ?>);
|
|
|
|
<?php
|
|
############################
|
|
### Field type specific
|
|
############################
|
|
if(in_array($scriptcondition['type'], $FIXED_LIST_FIELD_TYPES))
|
|
{
|
|
$jquery_condition_selector = "input[name=\"nodes[{$scriptcondition['field']}][]\"]";
|
|
$js_conditional_statement = "fieldokvalues{$scriptcondition['field']}.indexOf(element.value) != -1";
|
|
|
|
if(FIELD_TYPE_CHECK_BOX_LIST == $scriptcondition['type'])
|
|
{
|
|
$js_conditional_statement = "element.checked && {$js_conditional_statement}";
|
|
}
|
|
|
|
if(FIELD_TYPE_DROP_DOWN_LIST == $scriptcondition['type'])
|
|
{
|
|
$jquery_condition_selector = "select[name=\"nodes[{$scriptcondition['field']}]\"] option:selected";
|
|
}
|
|
|
|
if(FIELD_TYPE_RADIO_BUTTONS == $scriptcondition['type'])
|
|
{
|
|
$jquery_condition_selector = "input[name=\"nodes[{$scriptcondition['field']}]\"]:checked";
|
|
}
|
|
?>
|
|
jQuery('<?php echo $jquery_condition_selector; ?>').each(function(index, element)
|
|
{
|
|
if(<?php echo $js_conditional_statement; ?>)
|
|
{
|
|
field<?php echo $field['ref']; ?>valuefound = true;
|
|
}
|
|
});
|
|
|
|
<?php
|
|
}
|
|
?>
|
|
if(!field<?php echo $field['ref']; ?>valuefound)
|
|
{
|
|
field<?php echo $field['ref']; ?>visibility = false;
|
|
}
|
|
<?php
|
|
}
|
|
?>
|
|
|
|
// Is field to be displayed
|
|
if(field<?php echo $field['ref']; ?>visibility)
|
|
{
|
|
newfield<?php echo $field['ref']; ?>status = 'block';
|
|
}
|
|
|
|
// If display status changed then toggle the visibility
|
|
if(newfield<?php echo $field['ref']; ?>status != field<?php echo $field['ref']; ?>status)
|
|
{
|
|
jQuery('<?php echo escape($question_id); ?>').css("display", newfield<?php echo $field['ref']; ?>status);
|
|
// The visibility status (block/none) will be sent to the server in the following field
|
|
jQuery('#field_<?php echo $field['ref']; ?>_displayed').attr("value",newfield<?php echo $field['ref']; ?>status);
|
|
|
|
<?php
|
|
// Batch edit mode
|
|
if($GLOBALS["multiple"] === true)
|
|
{
|
|
?>
|
|
var batch_edit_editthis = jQuery("#<?php echo "editthis_{$n}"; ?>");
|
|
batch_edit_editthis.prop("checked", !batch_edit_editthis.prop("checked"));
|
|
batch_edit_toggle_edit_multi_checkbox_question(<?php echo (int) $n; ?>);
|
|
<?php
|
|
}
|
|
?>
|
|
|
|
if(jQuery('<?php echo escape($question_id); ?>').css('display') == 'block')
|
|
{
|
|
jQuery('<?php echo escape($question_id); ?>').css('border-top', '');
|
|
}
|
|
else
|
|
{
|
|
jQuery('<?php echo escape($question_id); ?>').css('border-top', 'none');
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
return $displaycondition;
|
|
}
|
|
|
|
|
|
/**
|
|
* Utility to check if browse bar should be rendered
|
|
*
|
|
* @return boolean
|
|
*/
|
|
function has_browsebar()
|
|
{
|
|
global $username, $pagename, $loginterms, $not_authenticated_pages, $k, $internal_share_access, $browse_bar;
|
|
return isset($username)
|
|
&& is_array($not_authenticated_pages) && !in_array($pagename, $not_authenticated_pages)
|
|
&& ('' == $k || $internal_share_access)
|
|
&& $browse_bar;
|
|
// && false == $loginterms ?
|
|
}
|
|
|
|
/**
|
|
* Utility to if collapsable upload options should be displayed
|
|
*
|
|
* @return boolean
|
|
*/
|
|
function display_upload_options()
|
|
{
|
|
global $metadata_read, $enable_add_collection_on_upload, $relate_on_upload, $camera_autorotation;
|
|
return $metadata_read || $enable_add_collection_on_upload || $relate_on_upload || $camera_autorotation;
|
|
}
|
|
|
|
|
|
function display_field_data(array $field,$valueonly=false,$fixedwidth=452)
|
|
{
|
|
debug_function_call(__FUNCTION__, [$field['ref'], $valueonly, $fixedwidth]);
|
|
global $ref, $show_expiry_warning, $access, $search, $extra, $lang, $FIXED_LIST_FIELD_TYPES, $force_display_template_orderby;
|
|
|
|
$value = (string) $field["value"];
|
|
$title=escape($field["title"]);
|
|
$modified_field=hook("beforeviewdisplayfielddata_processing","",array($field));
|
|
if($modified_field)
|
|
{
|
|
$field=$modified_field;
|
|
debug(sprintf('$field #%s was modified by beforeviewdisplayfielddata_processing hook', $field['ref']));
|
|
}
|
|
|
|
$warningtext="";
|
|
$dismisstext="";
|
|
$dismisslink="";
|
|
# Handle expiry date warning messages
|
|
if (!$valueonly && $field["type"] == FIELD_TYPE_EXPIRY_DATE && $value != "" && $value <= date("Y-m-d H:i") && $show_expiry_warning)
|
|
{
|
|
debug('Handle expiry date warning messages');
|
|
$title = escape($lang["warningexpired"]);
|
|
$warningtext = escape($lang["warningexpiredtext"]);
|
|
$dismisstext = LINK_CARET . escape($lang["warningexpiredok"]);
|
|
$dismisslink = "<p id=\"WarningOK\">
|
|
<a href=\"#\" onClick=\"document.getElementById('RecordDownloadTabContainer').style.display='block';document.getElementById('WarningOK').style.display='none';\">{$dismisstext}</a></p>";
|
|
$extra.="<style>#RecordDownloadTabContainer {display:none;}</style>";
|
|
|
|
# If there is no display template then prepare the full markup here
|
|
if (trim((string) $field["display_template"]) == "")
|
|
{
|
|
$extra.="<div class=\"clearerleft\"></div><div class=\"RecordStory\"><h1>{$title}</h1>
|
|
<p>{$value}</p><p>{$warningtext}</p>{$dismisslink}</div>";
|
|
}
|
|
}
|
|
|
|
# Handle general warning messages
|
|
if (!$valueonly && $field["type"] == FIELD_TYPE_WARNING_MESSAGE && trim($value) != "")
|
|
{
|
|
debug('Handle general warning messages');
|
|
$warningtext = $value;
|
|
$dismisstext = LINK_CARET . escape($lang["warningexpiredok"]);
|
|
$dismisslink = "<p id=\"WarningOK_{$field['ref']}\">
|
|
<a href=\"#\" onClick=\"document.getElementById('RecordDownloadTabContainer').style.display='block';document.getElementById('WarningOK_{$field['ref']}').style.display='none';\">{$dismisstext}</a></p>";
|
|
$extra.="<style>#RecordDownloadTabContainer {display:none;}</style>";
|
|
|
|
# If there is no display template then prepare the full markup here
|
|
if (trim((string) $field["display_template"]) == "")
|
|
{
|
|
$extra.="<div class=\"clearerleft\"></div><div class=\"RecordStory\"><h1>{$title}</h1>
|
|
<p>".nl2br(escape(i18n_get_translated($warningtext)))."</p>{$dismisslink}</div>";
|
|
}
|
|
}
|
|
|
|
if ($field['value_filter']!="")
|
|
{
|
|
debug('Calling value_filter...');
|
|
eval(eval_check_signed($field['value_filter']));
|
|
}
|
|
elseif ($field["type"] == FIELD_TYPE_DATE_AND_OPTIONAL_TIME && strpos($value,":") !== false)
|
|
{
|
|
// Show the time as well as date if entered
|
|
$value=nicedate($value,true,true);
|
|
}
|
|
elseif ($field["type"]==FIELD_TYPE_DATE_AND_OPTIONAL_TIME || $field["type"]==FIELD_TYPE_EXPIRY_DATE || $field["type"]==FIELD_TYPE_DATE)
|
|
{
|
|
$value=nicedate($value,false,true);
|
|
}
|
|
elseif ($field["type"]==FIELD_TYPE_DATE_RANGE)
|
|
{
|
|
$rangedates = explode(",",$value);
|
|
natsort($rangedates);
|
|
$value=implode(DATE_RANGE_SEPARATOR,$rangedates);
|
|
}
|
|
|
|
if($field['type'] == FIELD_TYPE_CATEGORY_TREE)
|
|
{
|
|
$parentnode = null;
|
|
$recursive = true;
|
|
$treenodes = get_nodes($field["ref"], $parentnode, $recursive);
|
|
$detailed=false; # Just get the nodes
|
|
$node_sort=false; # Do not sort the nodes
|
|
$resource_nodes=get_resource_nodes($ref, $field["ref"], $detailed, $node_sort);
|
|
$treenodenames = array();
|
|
foreach ($treenodes as $treenode)
|
|
{
|
|
if(in_array($treenode["ref"],$resource_nodes))
|
|
{
|
|
$treenodenames[] = ["ref" => $treenode["ref"], "name" => $treenode["translated_path"]];
|
|
}
|
|
}
|
|
|
|
// Render as plain text if the user is not authenticated as they will not be able to use the node searches from the pills view
|
|
if (is_authenticated()) {
|
|
$value = render_fixed_list_as_pills($treenodenames);
|
|
} else {
|
|
$value = implode(', ', array_column($treenodenames, 'name'));
|
|
}
|
|
}
|
|
|
|
if (($value!="") && ($value!=",") && ($field["display_field"]==1) && ($access==0 || ($access==1 && !$field["hide_when_restricted"])))
|
|
{
|
|
debug('Field can display...');
|
|
if (!$valueonly)
|
|
{
|
|
debug('Showing title');
|
|
$title=escape(str_replace("Keywords - ","",$field["title"]));
|
|
}
|
|
else
|
|
{
|
|
debug('Blanking title');
|
|
$title="";
|
|
}
|
|
|
|
# Value formatting
|
|
# Optimised to use the value as is if there are no "~" characters present in the value
|
|
if (is_i18n_language_string($value) && $field['type'] != FIELD_TYPE_CATEGORY_TREE) {
|
|
$field_value = $value;
|
|
debug('value formatting due to ~ character...');
|
|
# The field value may be a list of comma separated language encoded values, so process the nodes
|
|
$field_nodes_in_value = explode(",", $field["nodes"]);
|
|
if (count($field_nodes_in_value) > 1) {
|
|
# Multiple nodes in value; Get all nodes for the field and translate each one which is in the metadata
|
|
$field_nodes_all = get_nodes($field['ref']);
|
|
$names_i18n_in_value = extract_node_options($field_nodes_all, true, true);
|
|
# Convert the field nodes in value as an array keyed by the names to allow an intersect by key operation
|
|
$node_names_in_value = array_intersect_key($names_i18n_in_value, array_flip($field_nodes_in_value));
|
|
$value = implode(', ', $node_names_in_value);
|
|
$field_nodes_translated = array_map(function($node_value, $node_id)
|
|
{
|
|
return ['name' => $node_value, 'ref' => $node_id];
|
|
}
|
|
, $node_names_in_value, array_keys($node_names_in_value));
|
|
}
|
|
|
|
# Not a node list so translate the raw value or something went wrong trying to resolve the node values
|
|
# so attempt to translate the raw value to display instead
|
|
if (count($field_nodes_in_value) == 1 || trim($value) == "") {
|
|
# Translate the single value
|
|
$value=i18n_get_translated($field_value);
|
|
$field_nodes_translated = [['name' => $value, 'ref' => $field['nodes']]];
|
|
}
|
|
}
|
|
|
|
// Handle the rest of the fixed list fields, category trees have their own section
|
|
// Only render the pills view if the user is authenticated as unauthenticated users will not be able to perform the node searches
|
|
if (in_array($field['type'], $FIXED_LIST_FIELD_TYPES) && $field['type'] != FIELD_TYPE_CATEGORY_TREE && is_authenticated()) {
|
|
$nodes = $field_nodes_translated ?? array_map(function($ref, $name) {
|
|
return ['ref' => $ref, 'name' => $name];
|
|
}, array_keys($field['nodes_values']), $field['nodes_values']);
|
|
$value = render_fixed_list_as_pills($nodes);
|
|
}
|
|
|
|
# Do not convert HTML formatted fields (that are already HTML) to HTML. Added check for extracted fields set to
|
|
# TinyMCE that have not yet been edited.
|
|
if(
|
|
($field["type"] != FIELD_TYPE_TEXT_BOX_FORMATTED_AND_TINYMCE && !(in_array($field['type'], $FIXED_LIST_FIELD_TYPES) && is_authenticated()))
|
|
|| ($field["type"] == FIELD_TYPE_TEXT_BOX_FORMATTED_AND_TINYMCE && $value == strip_tags($value))
|
|
)
|
|
{
|
|
$value = nl2br(escape($value));
|
|
}
|
|
elseif($field["type"] == FIELD_TYPE_TEXT_BOX_FORMATTED_AND_TINYMCE && $value != strip_tags($value))
|
|
{
|
|
$value = strip_tags_and_attributes($value, ['a'], ['href', 'target', 'rel', 'title']);
|
|
}
|
|
|
|
$modified_value = hook('display_field_modified_value', '', array($field));
|
|
if($modified_value)
|
|
{
|
|
$value = $modified_value['value'];
|
|
debug('field value modified by display_field_modified_value hook');
|
|
}
|
|
# Final stages of rendering
|
|
|
|
# Include display template when necessary
|
|
if (!$valueonly && trim($field["display_template"] ?? "")!="")
|
|
{
|
|
debug('Include display_template');
|
|
$value_for_url=$value;
|
|
# Highlight keywords
|
|
$value=highlightkeywords($value,$search,$field["partial_index"],$field["name"],$field["keywords_index"]);
|
|
|
|
$value_mod_after_highlight=hook('value_mod_after_highlight', '', array($field,$value));
|
|
if($value_mod_after_highlight)
|
|
{
|
|
$value=$value_mod_after_highlight;
|
|
}
|
|
|
|
# Use a display template to render this field
|
|
$template = strip_tags_and_attributes($field['display_template'], array("a"), ['href', 'target', 'rel', 'title']);
|
|
$template = str_replace('[title]', $title, $template);
|
|
$template = str_replace('[value]', $value, $template);
|
|
$template = str_replace(['[url]', '%5Burl%5D'], escape($value_for_url), $template);
|
|
$template = str_replace('[warning]', escape($warningtext), $template);
|
|
$template = str_replace('[ref]', (int) $ref, $template);
|
|
$template = str_replace('[link]', strip_tags_and_attributes($dismisslink, array("a"), array("href", "onclick")), $template);
|
|
|
|
/*Language strings
|
|
Format: [lang-language-name_here]
|
|
Example: [lang-resourcetype-photo]
|
|
*/
|
|
preg_match_all('/\[lang-(.+?)\]/', $template, $template_language_matches);
|
|
$i = 0;
|
|
foreach($template_language_matches[0] as $template_language_match_placeholder)
|
|
{
|
|
$placeholder_value = $template_language_match_placeholder;
|
|
|
|
if(isset($lang[$template_language_matches[1][$i]]))
|
|
{
|
|
$placeholder_value = $lang[$template_language_matches[1][$i]];
|
|
}
|
|
|
|
$template = str_replace($template_language_match_placeholder, $placeholder_value, $template);
|
|
|
|
$i++;
|
|
}
|
|
|
|
$extra .= $template;
|
|
}
|
|
else
|
|
{
|
|
debug('No display template');
|
|
# There is a value in this field, but we also need to check again for a current-language value after the i18n_get_translated() function was called, to avoid drawing empty fields
|
|
if ($value!="")
|
|
{
|
|
debug('Draw this field normally...');
|
|
# Draw this field normally. - value has already been sanitized by htmlspecialchars
|
|
# Highlight keywords
|
|
$value=highlightkeywords($value,$search,$field["partial_index"],$field["name"],$field["keywords_index"]);
|
|
|
|
$value_mod_after_highlight=hook('value_mod_after_highlight', '', array($field,$value));
|
|
if($value_mod_after_highlight)
|
|
{
|
|
$value=$value_mod_after_highlight;
|
|
}
|
|
|
|
?><div
|
|
<?php
|
|
if (!$valueonly)
|
|
{
|
|
if ($field["full_width"])
|
|
{
|
|
echo "class=\"clearerleft item itemType".$field['type']."\"";
|
|
}
|
|
else
|
|
{
|
|
echo "class=\"itemNarrow itemType".$field['type']."\"";
|
|
}
|
|
}
|
|
elseif (isset($fixedwidth))
|
|
{
|
|
echo "style=\"width:" . $fixedwidth . "px\"";
|
|
} ?>>
|
|
<h3><?php echo $title?></h3><p><?php echo $value; ?></p></div><?php
|
|
}
|
|
}
|
|
|
|
if($force_display_template_orderby)
|
|
{
|
|
echo $extra;
|
|
$extra='';
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Helper function for display_field to generate html for fixed list fields, rendering them as a series of pills with search links
|
|
*
|
|
* @param array $node Array of nodes to display
|
|
*/
|
|
function render_fixed_list_as_pills($nodes):string
|
|
{
|
|
global $baseurl;
|
|
$display_html = "";
|
|
if (count($nodes) > 0) {
|
|
foreach ($nodes as $nodedata) {
|
|
// Add zero width spaces to break up strings on non alphanumeric characters to allow for text wrapping
|
|
$nodedata["name"] = preg_replace_callback('/[^a-zA-Z0-9]/u', function($matches) {
|
|
return $matches[0] . "\u{200B}";
|
|
}, $nodedata["name"]);
|
|
$search_url = generateURL($baseurl . '/pages/search.php', ['search' => NODE_TOKEN_PREFIX . $nodedata['ref']]);
|
|
$display_html .= "<a href=\"{$search_url}\" onclick=\"CentralSpaceLoad(this)\">";
|
|
$display_html .= "<div class=\"fixedlistnodepill\">" . escape($nodedata["name"]) . "</div>";
|
|
$display_html .= "</a>";
|
|
}
|
|
return "<div>" . $display_html . "</div>";
|
|
}
|
|
return '';
|
|
}
|
|
|
|
/*
|
|
* Render the resource lock/unlock link for resource tools
|
|
*
|
|
* @param int $ref Resource ID
|
|
* @param int $lock_user ID of the user that locked the resource
|
|
* @param boolean $editaccess Does the user have edit access to the resource?
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_resource_lock_link($ref,$lockuser,$editaccess)
|
|
{
|
|
global $userref, $lang;
|
|
|
|
$resource_locked = (int)$lockuser > 0;
|
|
|
|
$edit_lock_option = false;
|
|
if(checkperm("a")
|
|
||
|
|
$userref == $lockuser
|
|
||
|
|
(!$resource_locked && !checkperm("nolock") && $editaccess)
|
|
)
|
|
{
|
|
$edit_lock_option = true;
|
|
}
|
|
|
|
if(!$resource_locked && !$edit_lock_option)
|
|
{
|
|
// User is not permitted to lock resource
|
|
return;
|
|
}
|
|
|
|
$lock_details = get_resource_lock_message($lockuser);
|
|
|
|
echo "<li>";
|
|
if($edit_lock_option)
|
|
{
|
|
echo "<a href='#' id='lock_link_" . $ref . "' onclick='return updateResourceLock(" . $ref . ",!resource_lock_status);' ";
|
|
echo "title='" . $lock_details . "'";
|
|
echo "class='LockedResourceAction " . ($resource_locked ? "ResourceLocked" : "ResourceUnlocked" ). "'> ";
|
|
if($resource_locked)
|
|
{
|
|
$locktext = (checkperm("a") || ($lockuser == $userref)) ? $lang["action_unlock"] : $lang["status_locked"];
|
|
}
|
|
else
|
|
{
|
|
$locktext = $lang["action_lock"];
|
|
}
|
|
echo $locktext . "</a>";
|
|
}
|
|
else
|
|
{
|
|
echo "<div class='ResourceLocked' title='" . escape($lock_details) . "' >" . $lang["status_locked"] . "</div>";
|
|
}
|
|
|
|
echo "<a id='lock_details_link' href='#' " . ($resource_locked ? "" : "style='display:none;'") . " onclick='if(resource_lock_status){styledalert(\"" . escape($lang["status_locked"]) . "\",lockmessage[" . escape($ref) . "]);}'> <i class='fas fa-info-circle'></i></a> </li>";
|
|
}
|
|
|
|
/**
|
|
* EditNav - render html for next/back browsing on the resource edit page. Called by SaveAndClearButtons()
|
|
*
|
|
* @return void
|
|
*/
|
|
function EditNav()
|
|
{
|
|
global $baseurl_short,$ref,$search,$offset,$order_by,$sort,$archive,$lang,$modal,$restypes,$disablenavlinks,$upload_review_mode, $urlparams;
|
|
?>
|
|
<div class="BackToResultsContainer"><div class="backtoresults">
|
|
<?php
|
|
if(!$disablenavlinks && !$upload_review_mode)
|
|
{?>
|
|
<a class="prevLink fa fa-arrow-left" onClick="return <?php echo $modal ? "Modal" : "CentralSpace"; ?>Load(this,true);" href="<?php echo generateURL($baseurl_short . "pages/edit.php",$urlparams, array("go"=>"previous")); ?>" title="<?php echo escape($lang["previous"]); ?>"></a>
|
|
|
|
<a class="upLink" onClick="return CentralSpaceLoad(this,true);" href="<?php echo generateURL($baseurl_short . "pages/search.php",$urlparams, array("go"=>"previous")); ?>"><?php echo escape($lang["viewallresults"])?></a>
|
|
|
|
<a class="nextLink fa fa-arrow-right" onClick="return <?php echo $modal ? "Modal" : "CentralSpace"; ?>Load(this,true);" href="<?php echo generateURL($baseurl_short . "pages/edit.php",$urlparams, array("go"=>"next")); ?>" title="<?php echo escape($lang["next"]); ?>"></a>
|
|
|
|
<?php
|
|
}
|
|
if ($modal)
|
|
{ ?>
|
|
<a class="maxLink fa fa-expand" href="<?php echo generateURL($baseurl_short . "pages/edit.php",$urlparams); ?>" onClick="return CentralSpaceLoad(this);" title="<?php echo escape($lang["maximise"]); ?>"></a>
|
|
<a href="#" class="closeLink fa fa-times" onClick="ModalClose();" title="<?php echo escape($lang["close"]); ?>"></a>
|
|
<?php
|
|
} ?>
|
|
</div></div><?php
|
|
}
|
|
|
|
/**
|
|
* Render the 'QuestionSubmit' div with the 'Save', 'Clear' and 'Save all with values' locked Buttons - used by the resource edit page
|
|
*
|
|
* @param string $extraclass - Additional CSS classes to add to the Question div
|
|
* @param bool $requiredfields - to indicate the input is required
|
|
* @param bool $backtoresults - Show the next/back links using EditNav()
|
|
* @return void
|
|
*/
|
|
function SaveAndClearButtons($extraclass="",$requiredfields=false,$backtoresults=false)
|
|
{
|
|
global $lang, $multiple, $ref, $upload_review_mode, $noupload, $is_template,
|
|
$modal, $edit_selection_collection_resources, $locked_fields;
|
|
|
|
$save_btn_value = ($ref > 0 ? ($upload_review_mode ? $lang["saveandnext"] : $lang["save"]) : $lang["next"]);
|
|
if($ref < 0 && $noupload)
|
|
{
|
|
$save_btn_value = $lang['create'];
|
|
}
|
|
|
|
$confirm_text = $lang["confirmeditall"];
|
|
if($edit_selection_collection_resources)
|
|
{
|
|
$confirm_text = $lang["confirm_edit_all_selected_resources"];
|
|
}
|
|
?>
|
|
<div class="QuestionSubmit <?php echo $extraclass ?>">
|
|
<?php
|
|
if($ref < 0 || $upload_review_mode)
|
|
{
|
|
echo "<input id='edit_reset_button' name='resetform' class='resetform' type='submit' value='" . escape($lang["clearbutton"]) . "' /> ";
|
|
}
|
|
?>
|
|
<input
|
|
<?php
|
|
if ($multiple)
|
|
{ ?>onclick="return confirm('<?php echo $confirm_text; ?>');"
|
|
<?php
|
|
}
|
|
?>
|
|
name="save"
|
|
id="edit_save_button"
|
|
class="editsave"
|
|
type="submit"
|
|
value="<?php echo escape($save_btn_value); ?>" />
|
|
<?php
|
|
if($upload_review_mode)
|
|
{
|
|
?> <input id="edit_save_auto_button" name="save_auto_next" <?php if(count($locked_fields) == 0){echo "style=\"display:none;\"";} ?>class="editsave save_auto_next" type="submit" value=" <?php echo escape($lang["save_and_auto"]) ?> " />
|
|
<?php
|
|
}
|
|
|
|
if(!$is_template && $requiredfields)
|
|
{
|
|
?>
|
|
<div class="RequiredFieldLabel"><sup>*</sup> <?php echo escape($lang['requiredfield']); ?></div>
|
|
<?php
|
|
}
|
|
|
|
hook("extra_edit_buttons");
|
|
|
|
# Duplicate navigation
|
|
if (!$multiple && !$modal && $ref>0 && !hook("dontshoweditnav") && $backtoresults)
|
|
{
|
|
EditNav();
|
|
}
|
|
?>
|
|
<br />
|
|
<div class="clearerleft"> </div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* display_size_option
|
|
*
|
|
* @param mixed $sizeID
|
|
* @param mixed $sizeName
|
|
* @param mixed $fordropdown
|
|
* @return void
|
|
*/
|
|
function display_size_option($sizeID, $sizeName, $fordropdown=true, $selected=false)
|
|
{
|
|
global $available_sizes, $lang, $result;
|
|
if(!hook('replace_display_size_option','',array($sizeID, $sizeName, $fordropdown))){
|
|
if ($fordropdown)
|
|
{
|
|
?><option value="<?php echo escape($sizeID) ?>" <?php echo ($selected) ? 'selected' : ''; ?>><?php
|
|
echo $sizeName;
|
|
}
|
|
if(isset($available_sizes[$sizeID]))
|
|
{
|
|
$availableCount = count($available_sizes[$sizeID]);
|
|
}
|
|
else
|
|
{
|
|
$availableCount=0;
|
|
}
|
|
$resultCount = count($result);
|
|
if ($availableCount != $resultCount && $sizeID != "largest")
|
|
{
|
|
echo " (" . escape($availableCount . " " . $lang["of"] . " " . $resultCount) . " ";
|
|
switch ($availableCount)
|
|
{
|
|
case 0:
|
|
echo escape($lang["are_available-0"]);
|
|
break;
|
|
case 1:
|
|
echo escape($lang["are_available-1"]);
|
|
break;
|
|
default:
|
|
echo escape($lang["are_available-2"]);
|
|
break;
|
|
}
|
|
echo ")";
|
|
}
|
|
if ($fordropdown)
|
|
{
|
|
?></option><?php
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Render the featured collection category selector
|
|
*
|
|
* @param integer $parent Parent collection ref
|
|
* @param array $context Contextual data (e.g depth level to render or the current branch path)
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_featured_collection_category_selector(int $parent, array $context)
|
|
{
|
|
global $lang;
|
|
|
|
// If this information is missing, that's an unrecoverable error, the developer should really make sure this information is provided
|
|
$collection = $context["collection"]; # as returned by get_collection()
|
|
$depth = (int) $context["depth"];
|
|
$current_branch_path = $context["current_branch_path"]; # as returned by get_featured_collection_category_branch_by_leaf()
|
|
$modal = (isset($context["modal"]) && is_bool($context["modal"]) ? $context["modal"] : false);
|
|
|
|
$featured_collection_categories = get_featured_collection_categories($parent, array());
|
|
if(empty($featured_collection_categories) && $depth>0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
$html_selector_name = "selected_featured_collection_category_{$depth}";
|
|
$html_question_label_txt = $lang["themecategory"] . ($depth == 0 ? "" : " {$depth}");
|
|
?>
|
|
<div class="Question">
|
|
<label for="<?php echo $html_selector_name; ?>"><?php echo $html_question_label_txt; ?></label>
|
|
<?php
|
|
$next_level_parent = null;
|
|
?>
|
|
<select id="<?php echo $html_selector_name; ?>" class="stdwidth" name="<?php echo $html_selector_name; ?>"
|
|
onchange="featured_collection_category_select_onchange(this, document.getElementById('collectionform'));
|
|
<?php echo $modal ? "Modal" : "CentralSpace"; ?>Post(document.getElementById('collectionform'));">
|
|
<option value="0"><?php echo escape($lang["select"]); ?></option>
|
|
<?php
|
|
// Allow user to move FC category to the root. Because we don't expose the collection type to the user, this will
|
|
// give users the ability to convert between public collection and featured category at root level without access
|
|
// to the collection type.
|
|
if($depth == 0)
|
|
{
|
|
$dummy_root_lvl_selected = ($collection["type"] == COLLECTION_TYPE_FEATURED && $parent == 0 ? "selected" : "");
|
|
?>
|
|
<option value="root" <?php echo $dummy_root_lvl_selected; ?>><?php echo escape($lang["featured_collection_root_category"]); ?></option>
|
|
<?php
|
|
}
|
|
foreach($featured_collection_categories as $fc_category)
|
|
{
|
|
// Never show as an option the FC you're editing
|
|
if($fc_category["ref"] == $collection["ref"])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
$html_attr_selected = "";
|
|
if(isset($current_branch_path[$depth]) && $fc_category["ref"] == $current_branch_path[$depth]["ref"])
|
|
{
|
|
$html_attr_selected = "selected";
|
|
$next_level_parent = $fc_category["ref"];
|
|
}
|
|
?>
|
|
<option value="<?php echo $fc_category["ref"]; ?>" <?php echo $html_attr_selected; ?>><?php echo escape(i18n_get_translated($fc_category["name"])); ?></option>
|
|
<?php
|
|
}
|
|
?>
|
|
</select>
|
|
<div class="clearerleft"></div>
|
|
</div>
|
|
<?php
|
|
if(is_null($next_level_parent))
|
|
{
|
|
return;
|
|
}
|
|
|
|
$context["depth"] = ++$depth;
|
|
render_featured_collection_category_selector($next_level_parent, $context);
|
|
}
|
|
|
|
|
|
/**
|
|
* Render featured collections (as tiles on the collections_featured.php page)
|
|
*
|
|
* @param array $ctx Context data to allow caller code to decide rendering requirements
|
|
* @param array $items List of items to render (featured collection category, actual collection or smart collection)
|
|
*/
|
|
function render_featured_collections(array $ctx, array $items)
|
|
{
|
|
global $baseurl_short, $lang, $k, $themes_simple_images, $FEATURED_COLLECTION_BG_IMG_SELECTION_OPTIONS, $themes_simple_view,$show_theme_collection_stats;
|
|
|
|
$is_smart_featured_collection = (isset($ctx["smart"]) ? (bool) $ctx["smart"] : false);
|
|
$general_url_params = (isset($ctx["general_url_params"]) && is_array($ctx["general_url_params"]) ? $ctx["general_url_params"] : array());
|
|
$all_fcs = (isset($ctx["all_fcs"]) && is_array($ctx["all_fcs"]) ? $ctx["all_fcs"] : array());
|
|
|
|
foreach($items as $fc)
|
|
{
|
|
$render_ctx = $ctx;
|
|
$is_featured_collection_category = is_featured_collection_category($fc);
|
|
$is_featured_collection = (!$is_featured_collection_category && !$is_smart_featured_collection);
|
|
|
|
$tool_edit = array(
|
|
"href" => generateURL("{$baseurl_short}pages/collection_edit.php",
|
|
array(
|
|
"ref" => $fc["ref"],
|
|
"redirection_endpoint" => urlencode(
|
|
generateURL(
|
|
"{$baseurl_short}pages/collections_featured.php",
|
|
$general_url_params,
|
|
array("parent" => $fc["parent"])
|
|
)
|
|
)
|
|
)
|
|
),
|
|
"text" => $lang['action-edit'],
|
|
"modal_load" => true,
|
|
"redirect" => true
|
|
);
|
|
$tool_select = array(
|
|
"text" => $lang['action-select'],
|
|
"custom_onclick" => "return ChangeCollection({$fc['ref']}, '');"
|
|
);
|
|
|
|
// Prepare FC images
|
|
$thumbnail_selection_method = $fc["thumbnail_selection_method"];
|
|
$show_images = ($themes_simple_view && in_array($thumbnail_selection_method, $FEATURED_COLLECTION_BG_IMG_SELECTION_OPTIONS) && $thumbnail_selection_method != $FEATURED_COLLECTION_BG_IMG_SELECTION_OPTIONS["no_image"]);
|
|
unset($fc_resources);
|
|
if($themes_simple_images && $show_images)
|
|
{
|
|
$fc_resources = get_featured_collection_resources(
|
|
$fc,
|
|
array(
|
|
"smart" => $is_smart_featured_collection,
|
|
"use_thumbnail_selection_method" => !$is_smart_featured_collection,
|
|
"all_fcs" => $all_fcs,
|
|
));
|
|
$fc_images = generate_featured_collection_image_urls($fc_resources, "pre");
|
|
|
|
if(!empty($fc_images))
|
|
{
|
|
$render_ctx["images"] = $fc_images;
|
|
}
|
|
}
|
|
|
|
// Featured collection default tools
|
|
if($is_featured_collection && checkPermission_dashmanage())
|
|
{
|
|
$render_ctx["tools"][] = array(
|
|
"href" => generateURL(
|
|
"{$baseurl_short}pages/dash_tile.php",
|
|
array(
|
|
'create' => 'true',
|
|
'tltype' => 'srch',
|
|
'title' => "{$fc['name']}",
|
|
'freetext' => 'true',
|
|
'tile_audience' => 'false',
|
|
'all_users' => 1,
|
|
'promoted_resource' => (isset($render_ctx["images"]) ? 'true' : ""),
|
|
'link' => "{$baseurl_short}pages/search.php?search=!collection{$fc['ref']}",
|
|
)
|
|
),
|
|
"text" => $lang['add_to_dash']);
|
|
}
|
|
if($is_featured_collection && allow_featured_collection_share($fc))
|
|
{
|
|
$render_ctx["tools"][] = array(
|
|
"href" => generateURL("{$baseurl_short}pages/collection_share.php", array("ref" => $fc["ref"])),
|
|
"text" => $lang["share"]);
|
|
}
|
|
if($is_featured_collection && collection_readable($fc['ref']))
|
|
{
|
|
$render_ctx["tools"][] = $tool_select;
|
|
}
|
|
if($is_featured_collection && collection_writeable($fc['ref']))
|
|
{
|
|
$render_ctx["tools"][] = $tool_edit;
|
|
}
|
|
if($is_featured_collection && $show_theme_collection_stats)
|
|
{
|
|
$render_ctx['show_resources_count'] = true;
|
|
}
|
|
|
|
|
|
if($is_featured_collection_category && !$is_smart_featured_collection)
|
|
{
|
|
global $enable_theme_category_edit;
|
|
|
|
$fc_category_url = generateURL("{$baseurl_short}pages/collections_featured.php", $general_url_params, array("parent" => $fc["ref"]));
|
|
$fc_category_has_children = (isset($fc["has_children"]) ? (bool) $fc["has_children"] : false);
|
|
|
|
$render_ctx["href"] = $fc_category_url;
|
|
$render_ctx["icon"] = ICON_FOLDER;
|
|
$render_ctx["tools"] = array();
|
|
|
|
if(checkPermission_dashmanage())
|
|
{
|
|
$render_ctx["tools"][] = array(
|
|
"href" => generateURL(
|
|
"{$baseurl_short}pages/dash_tile.php",
|
|
array(
|
|
'create' => 'true',
|
|
'tltype' => 'fcthm',
|
|
'tlstyle' => 'thmbs',
|
|
'title' => "{$fc['name']}",
|
|
'freetext' => 'true',
|
|
'tile_audience' => 'false',
|
|
'promoted_resource' => (isset($render_ctx["images"]) ? 'true' : ""),
|
|
'link' => $fc_category_url
|
|
)
|
|
),
|
|
"text" => $lang["add_to_dash"]);
|
|
}
|
|
|
|
if(checkperm("h"))
|
|
{
|
|
$render_ctx["tools"][] = array(
|
|
"href" => generateURL("{$baseurl_short}pages/collection_share.php", array("ref" => $fc["ref"])),
|
|
"text" => $lang["share"]);
|
|
}
|
|
|
|
if(!$fc_category_has_children && collection_readable($fc['ref']))
|
|
{
|
|
$render_ctx["tools"][] = $tool_select;
|
|
}
|
|
|
|
if($enable_theme_category_edit && checkperm("h") || checkperm("t"))
|
|
{
|
|
$render_ctx["tools"][] = $tool_edit;
|
|
}
|
|
}
|
|
|
|
if($is_smart_featured_collection)
|
|
{
|
|
$search = NODE_TOKEN_PREFIX . $fc["ref"];
|
|
$render_ctx["href"] = generateURL("{$baseurl_short}pages/search.php", array("search" => $search, "resetrestypes" => "true"));
|
|
|
|
$node_is_parent = (isset($fc["node_is_parent"]) ? $fc["node_is_parent"] : true);
|
|
if($node_is_parent)
|
|
{
|
|
$render_ctx["href"] = generateURL(
|
|
"{$baseurl_short}pages/collections_featured.php",
|
|
array(
|
|
"smart_rtf" => $fc["resource_type_field"],
|
|
"smart_fc_parent" => $fc["parent"],
|
|
));
|
|
}
|
|
$render_ctx["icon"] = ICON_FOLDER;
|
|
$render_ctx["tools"] = array();
|
|
}
|
|
|
|
// Don't show the tools for external shares
|
|
if (trim($k) != "")
|
|
{
|
|
$render_ctx["tools"] = array();
|
|
}
|
|
|
|
render_featured_collection($render_ctx, $fc);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Render a featured collection (as tiles on the collections_featured.php page)
|
|
*
|
|
* @param array $ctx Context data to allow caller code to decide rendering requirements
|
|
* @param array $fc Featured collection data structure
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_featured_collection(array $ctx, array $fc)
|
|
{
|
|
if(empty($fc))
|
|
{
|
|
return;
|
|
}
|
|
|
|
global $baseurl_short, $lang, $k, $flag_new_themes, $flag_new_themes_age, $view_title_field;
|
|
|
|
$is_smart_featured_collection = (isset($ctx["smart"]) ? (bool) $ctx["smart"] : false);
|
|
$full_width = (isset($ctx["full_width"]) && $ctx["full_width"]);
|
|
$general_url_params = (isset($ctx["general_url_params"]) && is_array($ctx["general_url_params"]) ? $ctx["general_url_params"] : array());
|
|
$show_resources_count = (isset($ctx["show_resources_count"]) ? (bool) $ctx["show_resources_count"] : false);
|
|
$reorder = (bool) ($ctx['reorder'] ?? false);
|
|
|
|
|
|
$html_container_class = array("FeaturedSimplePanel", "HomePanel", "DashTile", "FeaturedSimpleTile");
|
|
$html_container_style = array();
|
|
$html_container_data_items = [];
|
|
|
|
// Make featured collection tile sortable
|
|
if($reorder && !$is_smart_featured_collection)
|
|
{
|
|
$html_container_class[] = 'SortableItem';
|
|
$html_container_data_items['data-fc-ref'] = $fc['ref'];
|
|
}
|
|
|
|
|
|
// Set main featured collection URL (e.g for collections it's the !collection[ID], for categories it's for collection_featured.php)
|
|
$html_fc_a_href = generateURL("{$baseurl_short}pages/search.php", $general_url_params, array("search" => "!collection{$fc["ref"]}"));
|
|
$html_fc_a_href = (isset($ctx["href"]) && trim($ctx["href"]) !== "" ? $ctx["href"] : $html_fc_a_href);
|
|
|
|
|
|
$html_contents_class = array("FeaturedSimpleTileContents");
|
|
$html_contents_icon = (isset($ctx["icon"]) && trim($ctx["icon"]) != "" ? $ctx["icon"] : ICON_CUBE);
|
|
$fc_display_name = strip_prefix_chars(i18n_get_collection_name($fc),"*");
|
|
|
|
$html_contents_h2 = $html_contents_icon . $fc_display_name;
|
|
$html_contents_h2_style = array();
|
|
if(!$is_smart_featured_collection && $flag_new_themes && (time() - strtotime((string)$fc["created"])) < (60 * 60 * 24 * $flag_new_themes_age))
|
|
{
|
|
$html_contents_h2 .= sprintf(' <div class="NewFlag">%s</div>', escape($lang['newflag']));
|
|
}
|
|
if($full_width)
|
|
{
|
|
$html_container_class[] = "FullWidth";
|
|
$html_contents_h2_style[] = "max-width: unset;";
|
|
|
|
$action_selection_id = "themes_action_selection{$fc["ref"]}_bottom_{$fc["ref"]}";
|
|
|
|
if($show_resources_count && !$is_smart_featured_collection)
|
|
{
|
|
$html_contents_h2 .= sprintf(
|
|
' <span data-tag="resources_count" data-fc-ref="%s">%s</span>',
|
|
escape($fc['ref']),
|
|
escape($lang['counting_resources']));
|
|
}
|
|
}
|
|
|
|
|
|
$theme_images = (isset($ctx["images"]) ? $ctx["images"] : array());
|
|
$theme_images = array_map(
|
|
function($theme_image) use ($view_title_field, $lang){
|
|
if (!isset($theme_image['ref'])) {return $theme_image;} // Invalid data [t35944]
|
|
$ref = $theme_image['ref'];
|
|
$resource_data = get_resource_data($ref);
|
|
if ($resource_data===false) {return $theme_image;} // Resource not found
|
|
$theme_image['alt_text'] = $resource_data['field' . $view_title_field] ?? $lang['resource-1'] . ' ' . $ref;
|
|
return $theme_image;
|
|
}
|
|
, $theme_images);
|
|
if(!empty($theme_images))
|
|
{
|
|
$html_container_class[] = "FeaturedSimpleTileImage";
|
|
|
|
if(count($theme_images) == 1)
|
|
{
|
|
$alt_string = $theme_images[0]['alt_text'] ?? "";
|
|
$theme_image_path = $theme_images[0]["path"] ?? "";
|
|
$html_container_style[] = "background: url({$theme_image_path});";
|
|
$html_container_style[] = "background-size: cover;";
|
|
$theme_images = array();
|
|
}
|
|
}
|
|
|
|
|
|
$html_container_data = '';
|
|
foreach($html_container_data_items as $name => $value)
|
|
{
|
|
$html_container_data .= sprintf(' %s="%s"', $name, escape($value));
|
|
}
|
|
|
|
$tools = (isset($ctx["tools"]) && is_array($ctx["tools"]) && !$full_width ? $ctx["tools"] : array());
|
|
$html_actions_style = ['display: none;'];
|
|
|
|
// DEVELOPER NOTE: anything past this point should be set. All logic is handled above
|
|
?>
|
|
<div id="FeaturedSimpleTile_<?php echo md5($fc['ref']); ?>"
|
|
class="<?php echo implode(" ", $html_container_class); ?>"
|
|
alt="<?php echo escape($alt_string ?? '') ?>"
|
|
style="<?php echo implode(" ", $html_container_style); ?>" <?php echo $html_container_data; ?> >
|
|
<a href="<?php echo $html_fc_a_href; ?>" onclick="return CentralSpaceLoad(this, true);" id="featured_tile_<?php echo $fc["ref"]; ?>" class="FeaturedSimpleLink">
|
|
<div id="FeaturedSimpleTileContents_<?php echo $fc["ref"]; ?>" class="<?php echo implode(" ", $html_contents_class); ?>">
|
|
<?php
|
|
foreach($theme_images as $i => $theme_image)
|
|
{
|
|
$gap = 200 / count($theme_images);
|
|
$space = $i * $gap;
|
|
$style = array(
|
|
"left: {$space}px;",
|
|
"transform: rotate(" . (20 - ($i * 12)) . "deg);"
|
|
);
|
|
?>
|
|
<img src="<?php echo $theme_image['path']; ?>"
|
|
alt="<?php echo escape($theme_image['alt_text'] ?? ""); ?>"
|
|
class="TileGroupImageBase"
|
|
style="<?php echo implode(" ", $style); ?>" >
|
|
<?php
|
|
}
|
|
?>
|
|
<h2 style="<?php echo implode(" ", $html_contents_h2_style); ?>"><?php echo $html_contents_h2; ?></h2>
|
|
</div>
|
|
</a>
|
|
<?php
|
|
if(!empty($tools))
|
|
{
|
|
?>
|
|
<div id="FeaturedSimpleTileActions_<?php echo md5($fc['ref']); ?>" class="FeaturedSimpleTileActions" style="<?php echo implode(" ", $html_actions_style); ?>">
|
|
<?php
|
|
foreach($tools as $tool)
|
|
{
|
|
if(empty($tool))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
$href = (isset($tool["href"]) && trim($tool["href"]) != "" ? $tool["href"] : "#");
|
|
$text = $tool["text"]; // if this is missing, code is wrong somewhere else
|
|
|
|
$tool_onclick = (isset($tool["modal_load"]) && $tool["modal_load"] ? 'return ModalLoad(this, true);' : 'return CentralSpaceLoad(this, true);');
|
|
if(isset($tool["custom_onclick"]) && trim($tool["custom_onclick"]) != "")
|
|
{
|
|
$tool_onclick = $tool["custom_onclick"];
|
|
}
|
|
?>
|
|
<div class="tool">
|
|
<a href="<?php echo $href; ?>" onclick="<?php echo $tool_onclick; ?>">
|
|
<span><?php echo LINK_CARET; ?><?php echo escape($text); ?></span>
|
|
</a>
|
|
</div>
|
|
<?php
|
|
}
|
|
?>
|
|
</div><!-- End of FeaturedSimpleTileActions_<?php echo md5($fc['ref']); ?> -->
|
|
<?php
|
|
}
|
|
elseif($full_width && !$is_smart_featured_collection)
|
|
{
|
|
?>
|
|
<div class="ListTools">
|
|
<div class="ActionsContainer">
|
|
<select class="fcollectionactions" id="<?php echo $action_selection_id ?>" data-actions-loaded="0" data-actions-populating="0" data-col-id="<?php echo $fc["ref"];?>" onchange="action_onchange_<?php echo $action_selection_id ?>(this.value);">
|
|
<option><?php echo escape($lang["actions-select"]); ?></option>
|
|
</select>
|
|
</div>
|
|
</div><!-- End of ListTools -->
|
|
<?php
|
|
}
|
|
?>
|
|
</div><!-- End of FeaturedSimpleTile_<?php echo $fc["ref"]; ?>-->
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* Renders an option in the Permission Manager (admin_group_permissions.php page)
|
|
*
|
|
* @param string $permission Permission identifier
|
|
* @param string $description User friendly description of the permission
|
|
* @param boolean $reverse Reverse the permission
|
|
* @param boolean $reload deprecated - Autosave changes done on this permission
|
|
* @param boolean $disabled Disable this permission as another supersedes it (greys it out and checks it)
|
|
*/
|
|
function DrawOption(string $permission, string $description, bool $reverse = false, bool $reload = false, bool $disabled = false): void
|
|
{
|
|
global $permissions,$permissions_done;
|
|
|
|
$description_escaped = strip_paragraph_tags(strip_tags_and_attributes($description));
|
|
|
|
$checked = in_array($permission, $permissions);
|
|
if ($reverse)
|
|
{
|
|
$checked = !$checked;
|
|
}
|
|
|
|
$input_value = $reverse ? "reverse" : "normal";
|
|
$base64_perm = base64_encode($permission);
|
|
|
|
// Other attributes - note: a disabled input also gets checked automatically (some plugins do it)
|
|
$disabled_attr = '';
|
|
$onchange_attr = " onchange=SavePermissions(['$base64_perm']);";
|
|
if ($disabled)
|
|
{
|
|
$checked = true;
|
|
$disabled_attr = ' disabled';
|
|
$onchange_attr = '';
|
|
}
|
|
$checked_attr = $checked ? ' checked' : '';
|
|
?>
|
|
<input type="hidden" name="permission_<?php echo $base64_perm; ?>" value="<?php echo $input_value; ?>">
|
|
<tr class="<?php echo count($permissions_done) % 2 == 0 ? 'tableRowEven' : 'tableRowOdd'; ?>">
|
|
<td><?php if ($reverse) {?><i><?php } ?><?php echo escape($permission) ?><?php if ($reverse) {?></i><?php } ?></td>
|
|
<td><?php echo $description_escaped; ?></td>
|
|
<td>
|
|
<input
|
|
type="checkbox"
|
|
name="checked_<?php echo $base64_perm; ?>"
|
|
data-reverse="<?php echo (int) $reverse; ?>"
|
|
<?php echo $disabled_attr . $checked_attr . $onchange_attr; ?>>
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
$permissions_done[] = $permission;
|
|
}
|
|
|
|
|
|
/**
|
|
* Render featured collections options in the Permission Manager (admin_group_permissions.php page)
|
|
*
|
|
* This function will generate and render the following permissions that target featured collection categories
|
|
* # j[numeric ID of new collection] - valid for FC categories at root level. These are normal permissions.
|
|
* # -j[numeric ID of new collection] - valid for the rest of FC sub-categories. These permissions are reversed, {@see DrawOption()}!
|
|
*
|
|
* @param array $ctx Context data to allow caller code to start from different tree levels. Supports the following
|
|
* properties: parent and depth
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_featured_collections_category_permissions(array $ctx)
|
|
{
|
|
global $lang;
|
|
|
|
$permissions = (isset($ctx["permissions"]) && is_array($ctx["permissions"]) ? $ctx["permissions"] : array());
|
|
$parent = (isset($ctx["parent"]) ? validate_collection_parent(array("parent" => $ctx["parent"])) : 0);
|
|
$path_depth = (isset($ctx["depth"]) ? $ctx["depth"] : 0);
|
|
$branch_path = (isset($ctx["branch_path"]) && is_array($ctx["branch_path"]) ? $ctx["branch_path"] : array());
|
|
|
|
$current_depth = $path_depth;
|
|
$current_branch_path = $branch_path;
|
|
$reverse_permission = ($parent > 0);
|
|
|
|
foreach(get_featured_collection_categories($parent, array("access_control" => false)) as $fc)
|
|
{
|
|
$branch_path = $current_branch_path;
|
|
$branch_path[] = array(
|
|
"ref" => $fc["ref"],
|
|
"name" => $fc["name"],
|
|
"parent" => validate_collection_parent($fc),
|
|
);
|
|
|
|
$fc_perm_id = (!$reverse_permission ? "" : "-") . "j{$fc["ref"]}";
|
|
$description = sprintf("%s%s '%s'",
|
|
($path_depth == 0 ? "" : str_pad("", $path_depth * 7, "—") . " "),
|
|
(!$reverse_permission ? $lang["can_see_theme_category"] : $lang["can_see_theme_sub_category"]),
|
|
i18n_get_translated($fc["name"])
|
|
);
|
|
DrawOption($fc_perm_id, $description, $reverse_permission, true);
|
|
|
|
// Root categories (ie that don't have a parent) get rendered as normal permissions. Sub-categories, get rendered
|
|
// as reverse permissions
|
|
debug(sprintf("render_featured_collections_category_permissions: Check if allowed to render sub-categories for FC category '%s'", $fc['ref']));
|
|
$render_subcategories = array_reduce($branch_path, function($carry, $item) use ($permissions)
|
|
{
|
|
$root_node = is_null($item["parent"]);
|
|
$perm_id = ($root_node ? "" : "-") . "j{$item["ref"]}";
|
|
$allow_render = ($root_node ? in_array($perm_id, $permissions) : !in_array($perm_id, $permissions));
|
|
debug(sprintf("render_featured_collections_category_permissions: For perm ID '%s': carry = %s; root_node = %s; allow_render = %s", $perm_id, json_encode($carry), json_encode($root_node), json_encode($allow_render)));
|
|
|
|
// FALSE if at least one featured collection category parent is forbidden
|
|
return !is_bool($carry) ? $allow_render : $carry && $allow_render;
|
|
}, null);
|
|
debug("render_featured_collections_category_permissions: render_subcategories = " . json_encode($render_subcategories));
|
|
debug("render_featured_collections_category_permissions: ");
|
|
|
|
if($render_subcategories)
|
|
{
|
|
render_featured_collections_category_permissions(
|
|
array(
|
|
"permissions" => $permissions,
|
|
"parent" => $fc["ref"],
|
|
"depth" => ++$path_depth,
|
|
"branch_path" => $branch_path,
|
|
));
|
|
|
|
// Step back to initial depth level
|
|
$path_depth = $current_depth;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* show_upgrade_in_progress message
|
|
*
|
|
* @param bool $dbstructonly - Indicates whether this is a full upgrade with migration scripts or just a check_db_structs()
|
|
* @return void
|
|
*/
|
|
function show_upgrade_in_progress($dbstructonly=false)
|
|
{
|
|
global $lang;
|
|
$title = (isset($lang["upgrade_in_progress"])?$lang["upgrade_in_progress"]:"Upgrade in progress");
|
|
$message="This system is currently being upgraded by another process. Delete filestore/tmp/process_locks/* if this process has stalled." . PHP_EOL;
|
|
if(!$dbstructonly)
|
|
{
|
|
$upgrade_progress_overall=get_sysvar(SYSVAR_UPGRADE_PROGRESS_OVERALL);
|
|
$upgrade_progress_script=get_sysvar(SYSVAR_UPGRADE_PROGRESS_SCRIPT);
|
|
$message.=($upgrade_progress_overall===false ? '' : $upgrade_progress_overall . PHP_EOL);
|
|
$message.=($upgrade_progress_script===false ? '' : 'Script status: ' . $upgrade_progress_script . PHP_EOL);
|
|
}
|
|
if(PHP_SAPI == 'cli')
|
|
{
|
|
echo $message;
|
|
}
|
|
else
|
|
{
|
|
echo "<h1>{$title}</h1>";
|
|
echo nl2br($message);
|
|
?>
|
|
<script>
|
|
setTimeout(function()
|
|
{
|
|
window.location.reload(true);
|
|
}, 5000);
|
|
</script>
|
|
<?php
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* add link to mp3 preview file if resource is a wav file
|
|
*
|
|
* @param array $resource - resource data
|
|
* @param int $ref - resource ref
|
|
* @param string $k - url param key
|
|
* @param array $ffmpeg_audio_extensions - config var containing a list of extensions which will be ported to mp3 format for preview
|
|
* @param string $baseurl - config base url
|
|
* @param array $lang - array containing language strings
|
|
*
|
|
*/
|
|
function render_audio_download_link($resource, $ref, $k, $ffmpeg_audio_extensions, $baseurl, $lang)
|
|
{
|
|
|
|
// if resource is a .wav file and user has permissions to download then allow user also to download the mp3 preview file if available
|
|
// resources with extension in $ffmpeg_audio_extensions will always create an mp3 preview file
|
|
|
|
$path = get_resource_path($resource['ref'],true,"",false,"mp3");
|
|
$resource_download_allowed = resource_download_allowed($ref,'',$resource["resource_type"]);
|
|
$size_info = array('id' => '', 'extension' => 'mp3');
|
|
|
|
if (in_array($resource['file_extension'], $ffmpeg_audio_extensions) && file_exists($path) && $resource_download_allowed)
|
|
{
|
|
?>
|
|
<tr class="DownloadDBlend">
|
|
<td class="DownloadFileName">
|
|
<h2><?php echo escape($lang['mp3_preview_file']); ?></h2>
|
|
<p><?php echo formatfilesize(filesize_unlimited($path)); ?></p>
|
|
</td>
|
|
<?php add_download_column($ref,$size_info, true); ?>
|
|
</tr>
|
|
<?php
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Render a table based on ResourceSpace data to include sorting by various columns
|
|
*
|
|
* @param array $tabledata - This must be constructed as detailed below
|
|
*
|
|
* Required elements:-
|
|
*
|
|
* "class" Optional class to add to table div
|
|
* "headers" - Column headings using the identifier as the index,
|
|
* - name - Title to display
|
|
* - Sortable - can column be sorted?
|
|
* - width - Optional column width
|
|
*
|
|
* "orderbyname" - name of variable used on page to determine orderby (used to differentiate from standard search values)
|
|
* "orderby" - Current order by value
|
|
* "sortbyname" - name of variable used on page to determine sort
|
|
* "sort" - Current sort
|
|
* "defaulturl" - Default URL to construct links
|
|
* "modal" - Open links in modal? (false by default)
|
|
* "params" - Current parameters to use in URL
|
|
* "pager" - Pager settings
|
|
* - current page
|
|
* - total pages
|
|
* "data" - Array of data to display in table, using header identifers as indexes
|
|
* - If "rowid" is specified this will be used as the id attribute for the <tr> element
|
|
* - The "alerticon" can be used to specify a CSS class to use for a row status icon
|
|
* - An additional 'tools' element can be included to add custom action icons
|
|
* - "icon" - FontAwesome class to use for icon
|
|
* - "text" - title attribute
|
|
* - "url" - URl to link to
|
|
* - "url:class" - The styling classes for the URL. Type: string. This tool property is optional.
|
|
* - "modal" - (boolean) Open link in modal?
|
|
* - "onclick" - OnClick action to add to icon
|
|
*
|
|
* e.g.
|
|
*
|
|
* array(
|
|
* "icon"=>"fa fa-trash",
|
|
* "text"=>$lang["action-delete"],
|
|
* "url"=>"",
|
|
* "modal"=>false,
|
|
* "onclick"=>"delete_job(" . $jobs[$n]["ref"] . ");return false;"
|
|
* );
|
|
*
|
|
* array(
|
|
* "icon"=>"fa fa-info",
|
|
* "text"=>$lang["job_details"],
|
|
* "url"=>generateURL($baseurl . "/pages/job_details.php",array("job" => $jobs[$n]["ref"])),
|
|
* "modal"=>true,
|
|
* );
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_table($tabledata)
|
|
{
|
|
global $list_display_array, $lang, $default_perpage_list;
|
|
$modal = isset($tabledata["modal"]) && $tabledata["modal"];
|
|
$alertcolumn = count(array_column($tabledata["data"],'alerticon')) > 0;
|
|
if(isset($tabledata["pager"]))
|
|
{
|
|
$pageroptions = array(
|
|
"curpage" => $tabledata["pager"]["current"],
|
|
"totalpages" => $tabledata["pager"]["total"],
|
|
"per_page" => isset($tabledata["pager"]["per_page"]) ? $tabledata["pager"]["per_page"] : $default_perpage_list,
|
|
"break" => isset($tabledata["pager"]["break"]) ? $tabledata["pager"]["break"] : true,
|
|
"scrolltotop" => isset($tabledata["pager"]["scrolltotop"]) ? $tabledata["pager"]["scrolltotop"] : true,
|
|
"url" => $tabledata["defaulturl"],
|
|
"url_params" => $tabledata["params"],
|
|
);
|
|
echo '<div class="TopInpageNav TableNav">';
|
|
echo '<div class="InpageNavLeftBlock">' . escape($lang["resultsdisplay"]) . ': ';
|
|
// Show per page options
|
|
$list_display_array["all"] = 99999;
|
|
$pplinks = array();
|
|
foreach($list_display_array as $ldopt => $ldnum)
|
|
{
|
|
$lpp_name = isset($lang[$ldopt]) ? $lang[$ldopt] : $ldnum;
|
|
if ($pageroptions["per_page"] == $ldnum)
|
|
{
|
|
$pplinks[] = "<span class='Selected'>" . escape($lpp_name) . "</span>";
|
|
}
|
|
else
|
|
{
|
|
if(isset($tabledata["params"]["search_go"]))
|
|
{
|
|
$tabledata["params"]["search_go"] = "";
|
|
}
|
|
$perpageurl = generateURL($pageroptions["url"],$tabledata["params"], array("per_page"=>$ldnum));
|
|
$pplinks[] = "<a onclick='return " . ($modal ? "Modal" : "CentralSpace") . "Load(this, true);' href='" .
|
|
$perpageurl . "'>" . $lpp_name . "</a>";
|
|
}
|
|
}
|
|
echo implode(" | ", $pplinks);
|
|
echo "</div> <!-- End of InpageNavLeftBlock per page div -->";
|
|
echo "<div class='TablePagerHolder'>";
|
|
pager(false, true,$pageroptions);
|
|
echo "</div>";
|
|
}
|
|
echo '</div>';
|
|
echo "<div class='Listview " . (isset($tabledata["class"]) ? escape($tabledata["class"]) : "") . "'>\n";
|
|
echo "<table border='0' cellspacing='0' cellpadding='0' class='ListviewStyle'>\n";
|
|
echo "<tbody><tr class='ListviewTitleStyle'>\n";
|
|
if($alertcolumn)
|
|
{
|
|
echo "<th id='RowAlertStatus' style='width: 10px;'></th>";
|
|
}
|
|
foreach($tabledata["headers"] as $header=>$headerdetails)
|
|
{
|
|
echo "<th " . ($headerdetails["name"]==$lang["tools"] ? "class='ListTools'" : "") . (isset($headerdetails["width"]) ? ("style='width:" . escape($headerdetails["width"]) . "'") : "") . ">";
|
|
if($headerdetails["sortable"])
|
|
{
|
|
$revsort = ($tabledata["sort"]=="ASC") ? "DESC" : "ASC";
|
|
echo "<a href='" . generateURL($tabledata["defaulturl"],$tabledata["params"],array($tabledata["orderbyname"]=>$header,$tabledata["sortname"]=>($tabledata["orderby"] == $header ? $revsort : $tabledata["sort"]))) . "' onclick='return " . ($modal ? "Modal" : "CentralSpace") . "Load(this, true);'>" . escape($headerdetails["name"]);
|
|
if($tabledata["orderby"] == $header)
|
|
{
|
|
// Currently sorted by this column
|
|
echo "<span class='" . $revsort . "'></span>";
|
|
}
|
|
echo "</a>";
|
|
}
|
|
else
|
|
{
|
|
echo escape($headerdetails["name"]);
|
|
}
|
|
|
|
|
|
echo "</th>";
|
|
}
|
|
echo "</tr>\n"; // End of table header row
|
|
|
|
if(count($tabledata["data"]) == 0)
|
|
{
|
|
echo "<tr><td colspan='" . (strval(count($tabledata["headers"]))) . "'>" . escape($lang["no_results_found"]) . "</td></tr>\n";
|
|
}
|
|
else
|
|
{
|
|
foreach($tabledata["data"] as $rowdata)
|
|
{
|
|
$rowid = isset($rowdata["rowid"]) ? " id='" . escape($rowdata["rowid"]) . "'" : "";
|
|
if(isset($rowdata["rowlink"]))
|
|
{
|
|
$rowid .= " class='row_clickable' data-link='" . escape($rowdata["rowlink"]) . "'";
|
|
}
|
|
echo "<tr" . $rowid . ">";
|
|
|
|
if(isset($rowdata['alerticon']))
|
|
{
|
|
echo "<td><i class='" . escape($rowdata['alerticon']) . "' title = '" . escape($rowdata['alerticontitle'] ?? "") . "'></i></td>";
|
|
}
|
|
elseif($alertcolumn)
|
|
{
|
|
echo "<td></td>";
|
|
}
|
|
foreach($tabledata["headers"] as $header=>$headerdetails)
|
|
{
|
|
if(isset($rowdata[$header]))
|
|
{
|
|
echo "<td>";
|
|
// Data is present
|
|
if($header == "tools")
|
|
{
|
|
echo "<div class='ListTools'>";
|
|
foreach($rowdata["tools"] as $toolitem)
|
|
{
|
|
echo "<a aria-hidden='true' href='" . escape($toolitem["url"]) . "' class=\"" . escape($toolitem['url:class'] ?? '') . "\" onclick='";
|
|
if(isset($toolitem["onclick"]))
|
|
{
|
|
echo escape($toolitem["onclick"]);
|
|
}
|
|
else
|
|
{
|
|
echo "return " . ($toolitem["modal"] ? "Modal" : "return CentralSpace") . "Load(this,true);";
|
|
}
|
|
echo "' title='" . escape($toolitem["text"]) . "'><i class='" . escape($toolitem["icon"]) . "'></i> " . escape($toolitem["text"]) . "</a>";
|
|
}
|
|
echo "</div>";
|
|
}
|
|
else
|
|
{
|
|
echo (isset($headerdetails["html"]) && (bool)$headerdetails["html"])
|
|
? strip_tags_and_attributes($rowdata[$header], array("a","input"), array("href", "target", "type", "class", "onclick", 'name', 'value', 'title'))
|
|
: escape($rowdata[$header]);
|
|
}
|
|
echo "</td>";
|
|
}
|
|
else
|
|
{
|
|
echo "<td></td>\n";
|
|
}
|
|
}
|
|
echo "</tr>\n";
|
|
}
|
|
}
|
|
echo '</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<script>
|
|
jQuery(document).ready(function()
|
|
{
|
|
jQuery(".row_clickable").click(function (e, row, $element)
|
|
{
|
|
return ModalLoad(jQuery(this).data(\'link\'), true);
|
|
});
|
|
});
|
|
</script>';
|
|
}
|
|
|
|
/**
|
|
* Render multimensional array or object to display within table cells
|
|
*
|
|
* @param array $array
|
|
* @return void
|
|
*/
|
|
function render_array_in_table_cells($array)
|
|
{
|
|
foreach($array as $name => $value)
|
|
{
|
|
echo '<table class="TableArray">';
|
|
echo "<tr><td width='50%'>";
|
|
echo escape($name);
|
|
echo "</td><td width='50%'>";
|
|
|
|
if(is_array($value))
|
|
{
|
|
render_array_in_table_cells($value);
|
|
}
|
|
elseif(is_bool($value))
|
|
{
|
|
echo $value ? "TRUE" : "FALSE";
|
|
}
|
|
else
|
|
{
|
|
echo escape((string)$value);
|
|
}
|
|
|
|
echo "</td></tr>";
|
|
echo "</table>";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render the top page error style version
|
|
*
|
|
* @param string $err_msg Error message
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_top_page_error_style(string $err_msg)
|
|
{
|
|
if(trim($err_msg) === '')
|
|
{
|
|
return;
|
|
}
|
|
|
|
?><div class="PageInformal"><?php echo escape($err_msg); ?></div><?php
|
|
}
|
|
|
|
|
|
/**
|
|
* Render a FormHelper. These are used in forms, to provide extra information to the user to a question.
|
|
*
|
|
* @param string $txt Help text
|
|
* @param string $id Div ID
|
|
* @param array $ctx Contextual data
|
|
*/
|
|
function render_question_form_helper(string $txt, string $id, array $ctx)
|
|
{
|
|
$txt = trim($txt);
|
|
$id = trim($id);
|
|
|
|
if($txt === '' || $id === '')
|
|
{
|
|
return;
|
|
}
|
|
|
|
$ctx_class = (isset($ctx['class']) && is_array($ctx['class']) ? $ctx['class'] : array());
|
|
$ctx_style = (isset($ctx['style']) && is_string($ctx['style']) ? $ctx['style'] : ''); # Use a class if possible!
|
|
|
|
|
|
$class = escape(join(' ', array_merge(array('FormHelp'), $ctx_class)));
|
|
$style = (trim($ctx_style) !== '' ? sprintf(' style="%s"', escape($ctx_style)) : '');
|
|
?>
|
|
<div id="help_<?php echo escape($id); ?>" class="<?php echo $class; ?>"<?php echo $style; ?>>
|
|
<div class="FormHelpInner"><?php echo escape($txt); ?></div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* Render an HTML hidden input
|
|
*
|
|
* @param string $name Input name
|
|
* @param string $value Input value
|
|
*/
|
|
function render_hidden_input(string $name, string $value)
|
|
{
|
|
?>
|
|
<input type="hidden" name="<?php echo escape($name); ?>" value="<?php echo escape($value); ?>">
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Renders a dropdown for selecting the workflow state of a resource.
|
|
*
|
|
* This function generates a dropdown menu with various workflow states,
|
|
* allowing the user to select the current state of the resource.
|
|
* The available options are based on permission checks and additional states defined globally.
|
|
*
|
|
* @param int|null $current The currently selected state, if any.
|
|
* @param bool $checkaccess Indicates whether to check user permissions for each state.
|
|
*/
|
|
function render_workflow_state_question($current=null, $checkaccess=true)
|
|
{
|
|
global $additional_archive_states, $lang;
|
|
$statusoptions = array();
|
|
for ($n=-2;$n<=3;$n++)
|
|
{
|
|
if (!$checkaccess || checkperm("e" . $n) || $n==$current)
|
|
{
|
|
$statusoptions[$n] = isset($lang["status" . $n]) ? $lang["status" . $n] : $n;
|
|
}
|
|
}
|
|
foreach ($additional_archive_states as $additional_archive_state)
|
|
{
|
|
if (!$checkaccess || checkperm("e" . $additional_archive_state) || $additional_archive_state==$current)
|
|
{
|
|
$statusoptions[$additional_archive_state] = isset($lang["status" . $additional_archive_state]) ? $lang["status" . $additional_archive_state] : $additional_archive_state;
|
|
}
|
|
}
|
|
|
|
render_dropdown_question($lang["status"], "share_status", $statusoptions, $current, " class=\"stdWidth\"");
|
|
}
|
|
|
|
/**
|
|
* Renders a question field for setting a share password.
|
|
*
|
|
* This function generates an HTML input field where users can set or change
|
|
* the password for shared access to a resource. It includes functionality to
|
|
* toggle password visibility and indicates if the password is required.
|
|
*
|
|
* @param bool $blank Indicates if the password field should be left blank (default is true).
|
|
*/
|
|
function render_share_password_question($blank=true)
|
|
{
|
|
global $lang, $share_password_required;
|
|
?>
|
|
<div class="Question">
|
|
<label for="sharepassword"><?php echo strip_tags_and_attributes($lang["share-set-password"]); echo $share_password_required ? '<sup>*</sup>' : ''; ?></label>
|
|
<input type="password" <?php echo $share_password_required ? 'required' : ''; ?> id="sharepassword" name="sharepassword" autocomplete="new-password" maxlength="40" class="stdwidth" value="<?php echo $blank ? "" : escape($lang["password_unchanged"]); ?>">
|
|
<span class="fa fa-fw fa-eye-slash infield-icon" id="share-password-icon" onclick="togglePassword('sharepassword');"></span>
|
|
<script>
|
|
|
|
function togglePassword(pwdelement)
|
|
{
|
|
input = jQuery('#' + pwdelement);
|
|
if (input.attr("type") == "password")
|
|
{
|
|
input.attr("type", "text");
|
|
jQuery('#share-password-icon').removeClass('fa-eye-slash').addClass('fa-eye');
|
|
}
|
|
else
|
|
{
|
|
input.attr("type", "password");
|
|
jQuery('#share-password-icon').removeClass('fa-eye').addClass('fa-eye-slash');
|
|
}
|
|
}
|
|
var passInput="";
|
|
var passState="(unchanged)";
|
|
var passHistory="";
|
|
function pclick(id)
|
|
{
|
|
// Set to password mode
|
|
document.getElementById(id).type="password";
|
|
document.getElementById(id).value=passState;
|
|
document.getElementById(id).select();
|
|
}
|
|
function pblur(id)
|
|
{
|
|
// Copy keyed input other than bracketed placeholders to hidden password
|
|
passInput = document.getElementById(id).value;
|
|
if(passInput!="(unchanged)" && passInput!="(changed)")
|
|
{
|
|
document.getElementById("sharepassword").value=passInput;
|
|
passState="(changed)";
|
|
}
|
|
// Return to text mode showing the appropriate bracketed placeholder
|
|
document.getElementById(id).value=passState;
|
|
document.getElementById(id).type="text";
|
|
}
|
|
</script>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* Get required rows and columns for use when displaying radio buttons in a table
|
|
*
|
|
* @param array $options Array of text options
|
|
* @return array (Number of rows, number of columns)
|
|
*/
|
|
function radio_get_layout($options)
|
|
{
|
|
$l = average_length($options);
|
|
|
|
$cols = 10;
|
|
if($l > 5)
|
|
{
|
|
$cols = 6;
|
|
}
|
|
|
|
if($l > 10)
|
|
{
|
|
$cols = 4;
|
|
}
|
|
|
|
if($l > 15)
|
|
{
|
|
$cols = 3;
|
|
}
|
|
|
|
if($l > 25)
|
|
{
|
|
$cols = 2;
|
|
}
|
|
|
|
$rows = ceil(count($options) / $cols);
|
|
return array($rows, $cols);
|
|
}
|
|
|
|
|
|
/**
|
|
* render_radio_buttons_question - Used to display a question with radio buttons
|
|
*
|
|
* @param string $label Label of question
|
|
* @param string $inputname Name of input field
|
|
* @param array $options Array of options (value and text pairs) (eg. array('pixelwidthmin'=>'From','pixelwidthmin'=>'To')
|
|
* @param string $current The current selected value
|
|
* @param string $extra Extra attributes used on the selector element
|
|
* @param bool $listview Show as vertical list? (false for table view)
|
|
* @param array $ctx Rendering context. Should be used to inject different elements (e.g set the div class, add onclick for select)
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_radio_buttons_question($label, $inputname, $options = array(), $current="", $extra="", $listview=false, array $ctx = array())
|
|
{
|
|
$div_class = array("Question");
|
|
if(isset($ctx["div_class"]) && is_array($ctx["div_class"]) && !empty($ctx["div_class"]))
|
|
{
|
|
$div_class = array_merge($div_class, $ctx["div_class"]);
|
|
}
|
|
|
|
$onchange = (isset($ctx["onchange"]) && trim($ctx["onchange"]) != "" ? trim($ctx["onchange"]) : "");
|
|
$onchange = ($onchange != "" ? sprintf("onchange=\"%s\"", $onchange) : "");
|
|
|
|
$extra .= " {$onchange}";
|
|
|
|
list($rows,$cols) = radio_get_layout(array_values($options));
|
|
if($listview)
|
|
{
|
|
$cols=1;
|
|
}
|
|
?>
|
|
<div class="<?php echo implode(" ", $div_class); ?>">
|
|
<label><?php echo $label; ?></label>
|
|
|
|
<table id="<?php echo $inputname . "_radio_table"; ?>" class="radioOptionTable" cellpadding="3" cellspacing="3">
|
|
<tbody>
|
|
<tr>
|
|
<?php
|
|
$row = 1;
|
|
$col = 1;
|
|
|
|
foreach($options as $optionvalue=>$optiontext)
|
|
{
|
|
if($col > $cols)
|
|
{
|
|
$col = 1;
|
|
$row++; ?>
|
|
</tr>
|
|
<tr>
|
|
<?php
|
|
}
|
|
$col++;
|
|
?>
|
|
<td width="10" valign="middle">
|
|
<input type="radio"
|
|
id="radio_<?php echo escape($optionvalue); ?>"
|
|
name="<?php echo $inputname; ?>"
|
|
value="<?php echo escape($optionvalue); ?>"
|
|
<?php
|
|
if($current == $optionvalue)
|
|
{
|
|
?>
|
|
checked
|
|
<?php
|
|
}?>>
|
|
</td>
|
|
<td align="left" valign="middle">
|
|
<label class="customFieldLabel"
|
|
for="radio_<?php echo escape($optionvalue); ?>"
|
|
><?php echo escape($optiontext); ?></label>
|
|
</td>
|
|
<?php
|
|
}
|
|
?>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="clearerleft"></div>
|
|
</div>
|
|
<?php
|
|
}
|
|
/**
|
|
* Render a user message for use in conversation view
|
|
*
|
|
* @param array $message Message data from message_get_conversation()
|
|
* @return void
|
|
*/
|
|
function render_message($message="")
|
|
{
|
|
global $userref;
|
|
$msgdata = array();
|
|
if($message == "")
|
|
{
|
|
// Template
|
|
$msgdata[] = "%%CLASSES%%"; // %%CLASSES%%
|
|
$msgdata[] = ""; // EXTRA
|
|
$msgdata[] = "%%PROFILEIMAGE%%"; // %%PROFILEIMAGE%%
|
|
$msgdata[] = "%%MESSAGE%%"; // %%MESSAGE%%
|
|
}
|
|
else
|
|
{
|
|
$udata = get_user($message["owner"]);
|
|
if($udata["ref"] == $userref)
|
|
{
|
|
$msgdata[] = "user_message own_message"; // %%CLASSES%%
|
|
}
|
|
else
|
|
{
|
|
$msgdata[] = "user_message"; // %%CLASSES%%
|
|
}
|
|
$sendername = isset($udata["fullname"]) && trim($udata["fullname"]) != "" ? $udata["fullname"] : $udata["username"];
|
|
|
|
$msgdata[] = ""; // EXTRA
|
|
|
|
$pimage = get_profile_image($message["owner"]);
|
|
if($pimage == "")
|
|
{
|
|
$msgdata[] = "<i title='" . escape($sendername) . "' aria-hidden='true' class='fa fa-user fa-fw fa-lg ProfileImage'></i>"; // %%PROFILEIMAGE%%
|
|
}
|
|
else
|
|
{
|
|
$msgdata[] = "<img title='" . escape($sendername) . "' alt='" . escape($sendername) . "' class='ProfileImage' src='" . $pimage . "'>"; // %%PROFILEIMAGE%%
|
|
}
|
|
$msgdata[] = escape($message["message"]); // %%MESSAGE%%
|
|
}
|
|
|
|
$messagehtml = "<div class='%%CLASSES%%' %%EXTRA%%>
|
|
<div class='message_content'>
|
|
<div class='profileimage'>
|
|
%%PROFILEIMAGE%%
|
|
</div>
|
|
<div class='user_message_text'>%%MESSAGE%%</div>
|
|
</div>
|
|
<div class='clearerleft'></div>
|
|
</div>";
|
|
|
|
|
|
echo str_replace(array("%%CLASSES%%","%%EXTRA%%","%%PROFILEIMAGE%%","%%MESSAGE%%"),$msgdata,$messagehtml);
|
|
}
|
|
|
|
|
|
/**
|
|
* Render the antispam Question form section
|
|
*/
|
|
function render_antispam_question()
|
|
{
|
|
global $scramble_key, $lang;
|
|
|
|
$rndword = array_merge(range('0', '9'), range('A', 'Z'));
|
|
shuffle($rndword);
|
|
$timestamp=time();
|
|
$rndwordarray= array_slice ($rndword , 0,6);
|
|
$rndcode= hash("SHA256",implode("",$rndwordarray) . $scramble_key . $timestamp);
|
|
$height = 50; //CAPTCHA image height
|
|
$width = 160; //CAPTCHA image width
|
|
$font_size = 25; //CAPTCHA Font size
|
|
$font=__DIR__. "/../gfx/fonts/vera.ttf";
|
|
|
|
$capimage = imagecreate($width, $height);
|
|
imagecolorallocate($capimage, 245, 245, 245);
|
|
$textcolor = imagecolorallocate($capimage, 34, 34, 34);
|
|
$green = ImageColorAllocate($capimage, 121, 188, 65);
|
|
|
|
ImageRectangle($capimage,0,0,$width-1,$height-1,$green);
|
|
imageline($capimage, 0, $height/2, $width, $height/2, $green);
|
|
imageline($capimage, $width*4/5, 2, $width*4/5, $height, $green);
|
|
imageline($capimage, $width*3/5, 2, $width*3/5, $height, $green);
|
|
imageline($capimage, $width*2/5, 2, $width*2/5, $height, $green);
|
|
imageline($capimage, $width/5, 2, $width/5, $height, $green);
|
|
|
|
$n=0;
|
|
foreach($rndwordarray as $rndletter)
|
|
{
|
|
imagefttext($capimage, $font_size,rand(-20, 20), 10 + (24*$n), rand(25, 45), $textcolor, $font, $rndletter);
|
|
$n++;
|
|
}
|
|
|
|
ob_start();
|
|
imagegif($capimage);
|
|
$imagedata = ob_get_contents();
|
|
ob_end_clean();
|
|
?>
|
|
<div class="Question">
|
|
<input type="hidden" name="antispamcode" value="<?php echo $rndcode; ?>">
|
|
<input type="hidden" name="antispamtime" value="<?php echo $timestamp; ?>">
|
|
<label for="antispam"><?php echo escape($lang["enterantispamcode"]); ?> <sup>*</sup><br>
|
|
<div id="AntiSpamImage" style="
|
|
margin: 5px 0;
|
|
background: url(data:image/gif;base64,<?php echo base64_encode($imagedata); ?>) top left no-repeat;
|
|
height: <?php echo $height; ?>px;
|
|
width: <?php echo $width; ?>px;
|
|
border-radius: 6px;
|
|
display: inline-block;
|
|
">
|
|
</div>
|
|
</label>
|
|
<input type="text" name="antispam_user_code" class="stdwidth" value="">
|
|
<input type=text name="antispam" id="antispam" class="stdwidth" value="">
|
|
<div class="clearerleft"></div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Renders a 'fixed' text question - not an input but to display information or values that cannot be changed
|
|
*
|
|
* @param string $label Question label
|
|
* @param string $text Fixed text
|
|
* @param string $helptext Optional help text
|
|
* @param string $helptext Optional div identifier
|
|
*
|
|
*/
|
|
function render_fixed_text_question(string $label, string $text, string $helptext = "", string $divid = ""): void
|
|
{
|
|
$fixed_html = '
|
|
<div class="Question" %identifier>
|
|
<label>%label</label>
|
|
<div class="Fixed">%text</div>
|
|
<div class="clearerleft"></div>
|
|
%helptextdiv
|
|
</div>';
|
|
|
|
$help_html = '
|
|
<div class="FormHelp" style="padding:0; clear:left;" >
|
|
<div class="FormHelpInner">%helptext</div>
|
|
</div>';
|
|
|
|
$replace = [
|
|
"%identifier" => (trim($divid) != '' ? ' id="' . escape($divid) . '"' : ''),
|
|
"%label" => escape($label),
|
|
"%text" => escape($text),
|
|
"%helptextdiv" => (trim($helptext) != "" ? str_replace("%helptext", escape($helptext), $help_html) : ""),
|
|
];
|
|
|
|
echo str_replace(array_keys($replace),$replace,$fixed_html);
|
|
}
|
|
|
|
|
|
/**
|
|
* Output encoding for HTML context when unsafe input is rendered inside it
|
|
*
|
|
* @return string
|
|
*/
|
|
function escape(string $unsafe): string
|
|
{
|
|
return htmlspecialchars($unsafe, ENT_QUOTES | ENT_SUBSTITUTE);
|
|
}
|
|
|
|
|
|
/**
|
|
* HTML aware function to break up long words onto multiple lines for
|
|
* PDF generation where CSS text wrapping can't be used
|
|
*
|
|
* @param string $html HTML/text to be processed
|
|
* @param int $length Maximum word length
|
|
* @return string
|
|
*
|
|
*/
|
|
function html_break_long_words(string $html, int $length): string {
|
|
|
|
// Regex to match tags and text separately
|
|
preg_match_all('/<[^>]+>|[^<]+/', $html, $matches);
|
|
|
|
$output = '';
|
|
|
|
foreach ($matches[0] as $part) {
|
|
if ($part[0] === '<') {
|
|
// If it's an HTML tag, add it to the output as-is
|
|
$output .= $part;
|
|
} else {
|
|
// If it's plain text, process it for long words
|
|
$words = preg_split('/(\s+)/', $part, -1, PREG_SPLIT_DELIM_CAPTURE);
|
|
|
|
foreach ($words as $word) {
|
|
if (strlen($word) > $length) {
|
|
// Insert <br> tags between chunks only
|
|
$word = wordwrap($word, $length, '<br>', true);
|
|
}
|
|
$output .= $word;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
|
|
/**
|
|
* Renders a fontawesome icon selector question
|
|
* Requires lib/fontawesome/resourcespace/icon_classes.php to be included in the page using the function
|
|
*
|
|
* @param string $label
|
|
* @param string $name Input name
|
|
* @param string $current Current value
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_fa_icon_selector(string $label="",string $name="icon",string $current="")
|
|
{
|
|
global $lang, $font_awesome_icons;
|
|
|
|
if(trim($label) == "")
|
|
{
|
|
$label = $lang["property-icon"];
|
|
}
|
|
?>
|
|
<div class="Question">
|
|
<label><?php echo escape($label) ?></label>
|
|
<?php $blank_icon = ($current == "" || !in_array($current, $font_awesome_icons)); ?>
|
|
<div id="iconpicker-question">
|
|
<input name="<?php echo escape($name) ?>" type="text" id="iconpicker-input" value="<?php echo escape($current)?>" /><span id="iconpicker-button"><i class="fa-fw <?php echo $blank_icon ? 'fas fa-chevron-down' : escape($current)?>" id="iconpicker-button-fa"></i></span>
|
|
</div>
|
|
<div id="iconpicker-container">
|
|
<div class="iconpicker-title">
|
|
<input type="text" id="iconpicker-filter" placeholder="<?php echo escape($lang['icon_picker_placeholder']) ?>" onkeyup="filterIcons()">
|
|
</div>
|
|
<div class="iconpicker-content">
|
|
<?php foreach ($font_awesome_icons as $icon_name)
|
|
{
|
|
?>
|
|
<div class="iconpicker-content-icon" data-icon="<?php echo escape(trim($icon_name)) ?>" title="<?php echo escape(trim($icon_name)) ?>">
|
|
<i class="fa-fw <?php echo escape(trim($icon_name)) ?>"></i>
|
|
</div>
|
|
<?php
|
|
} ?>
|
|
</div>
|
|
</div>
|
|
<div class="clearerleft"> </div>
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
|
|
jQuery("#iconpicker-button").click(function()
|
|
{
|
|
jQuery("#iconpicker-container").toggle();
|
|
});
|
|
|
|
jQuery("#iconpicker-input").focus(function()
|
|
{
|
|
jQuery("#iconpicker-container").show();
|
|
});
|
|
|
|
jQuery(".iconpicker-content-icon").click(function()
|
|
{
|
|
var icon_name = jQuery(this).data("icon");
|
|
jQuery("#iconpicker-input").val(icon_name);
|
|
jQuery("#iconpicker-button i").attr("class","fa-fw " + icon_name);
|
|
});
|
|
|
|
jQuery(document).mouseup(function(e)
|
|
{
|
|
var container = jQuery("#iconpicker-container");
|
|
var question = jQuery("#iconpicker-question");
|
|
|
|
if (!container.is(e.target) && container.has(e.target).length === 0
|
|
&& !question.is(e.target) && question.has(e.target).length === 0)
|
|
{
|
|
container.hide();
|
|
}
|
|
});
|
|
|
|
function filterIcons()
|
|
{
|
|
filter_text = document.getElementById("iconpicker-filter");
|
|
var filter_upper = filter_text.value.toLowerCase();
|
|
|
|
container = document.getElementById("iconpicker-container");
|
|
icon_divs = container.getElementsByClassName("iconpicker-content-icon");
|
|
|
|
for (i = 0; i < icon_divs.length; i++)
|
|
{
|
|
icon_short_name = icon_divs[i].getAttribute("data-icon");
|
|
if (icon_short_name.toLowerCase().indexOf(filter_upper) > -1)
|
|
{
|
|
icon_divs[i].style.display = "inline-block";
|
|
}
|
|
else
|
|
{
|
|
icon_divs[i].style.display = "none";
|
|
}
|
|
}
|
|
}
|
|
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* Render all related resources on view page
|
|
*
|
|
* @param array $context Array with all required info from the view page
|
|
*
|
|
* @return void
|
|
*
|
|
*/
|
|
function display_related_resources($context)
|
|
{
|
|
$ref = $context["ref"] ?? 0;
|
|
$k = $context["k"] ?? "";
|
|
$userref = $context["userref"] ?? 0;
|
|
$arr_related = $context["relatedresources"] ?? [];
|
|
$internal_share_access = $context["internal_share_access"] ?? false;
|
|
$related_restypes = $context["related_restypes"] ?? [];
|
|
$relatedtypes_shown = $context["relatedtypes_shown"] ?? [];
|
|
$edit_access = $context["edit_access"] ?? false;
|
|
$urlparams = $context["urlparams"] ?? ["ref" => $ref];
|
|
|
|
global $baseurl, $baseurl_short, $lang, $view_title_field, $sort_relations_by_filetype, $related_resources_title_trim, $sort_relations_by_restype, $metadata_template_title_field, $metadata_template_resource_type;
|
|
|
|
$allrestypes = get_resource_types();
|
|
$allrestypes_names = array_column($allrestypes, 'name', 'ref');
|
|
|
|
if ($ref == 0 || count(array_diff(array_column($allrestypes, "ref"), $relatedtypes_shown)) == 0) {
|
|
return;
|
|
}
|
|
|
|
$use_watermark = check_use_watermark();
|
|
?>
|
|
<!--Display panel for related resources-->
|
|
<div class="RecordBox">
|
|
<div class="RecordPanel">
|
|
<div id="RelatedResources">
|
|
<div class="RecordResource">
|
|
<div class="Title"><?php echo escape($lang["relatedresources"]); ?></div>
|
|
<?php
|
|
if (
|
|
checkperm("s")
|
|
&& ($k == "" || $internal_share_access)
|
|
) {
|
|
if (count(array_diff(array_column($arr_related, "resource_type"), $relatedtypes_shown)) > 0) {
|
|
?>
|
|
<a href="<?php echo generateURL($baseurl . '/pages/search.php', ['search' => "!related$ref", 'restypes' => '']); ?>"
|
|
onClick="return CentralSpaceLoad(this,true);">
|
|
<?php echo LINK_CARET . escape($lang["clicktoviewasresultset"]); ?>
|
|
</a>
|
|
<div class="clearerleft"></div>
|
|
<?php
|
|
}
|
|
if ($sort_relations_by_filetype) {
|
|
// Sort by file extension
|
|
$related_file_extensions = array_unique(array_column($arr_related, "file_extension"));
|
|
foreach ($related_file_extensions as $rext) {
|
|
?>
|
|
<h4><?php echo escape((string) $rext); ?></h4>
|
|
<?php
|
|
// loop and display the results by file extension
|
|
for ($n = 0; $n < count($arr_related); $n++) {
|
|
if (in_array($arr_related[$n]["resource_type"], $relatedtypes_shown)) {
|
|
// Don't show this type again.
|
|
continue;
|
|
}
|
|
if ($arr_related[$n]["file_extension"] == $rext) {
|
|
$rref = $arr_related[$n]["ref"];
|
|
$title = $arr_related[$n]["field" . $view_title_field];
|
|
$access = get_resource_access($rref);
|
|
$safeviewlink = generateURL(
|
|
$baseurl . "/pages/view.php",
|
|
["ref" => (int) $rref, "search" => "!related" . $ref]
|
|
);
|
|
// Swap title fields if necessary
|
|
if (
|
|
isset($metadata_template_title_field)
|
|
&& isset($metadata_template_resource_type)
|
|
&& $arr_related[$n]['resource_type'] == $metadata_template_resource_type
|
|
) {
|
|
$title = $arr_related[$n]["field" . $metadata_template_title_field];
|
|
}
|
|
?>
|
|
<div class="CollectionPanelShell">
|
|
<table border="0" class="CollectionResourceAlign">
|
|
<tr>
|
|
<td>
|
|
<a href="<?php echo $safeviewlink; ?>"
|
|
onClick="return CentralSpaceLoad(this,true);">
|
|
<?php
|
|
$thumbnail = get_resource_preview($arr_related[$n], ["col"], $access, $use_watermark);
|
|
if ($thumbnail !== false) {
|
|
render_resource_image($arr_related[$n], $thumbnail["url"], "collection");
|
|
} else {
|
|
echo get_nopreview_html((string) $arr_related[$n]["file_extension"], $arr_related[$n]['resource_type']);
|
|
} ?>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<div class="CollectionPanelInfo">
|
|
<a href="<?php echo $safeviewlink; ?>"
|
|
onClick="return CentralSpaceLoad(this,true);">
|
|
<?php echo escape(tidy_trim(i18n_get_translated($title), $related_resources_title_trim)); ?>
|
|
</a>
|
|
</div>
|
|
<?php hook("relatedresourceaddlink"); ?>
|
|
</div>
|
|
<?php
|
|
}
|
|
}
|
|
?>
|
|
<div class="clearerleft"> </div>
|
|
<?php
|
|
} // End of display loop by resource extension
|
|
// End of IF sorted relations by extension
|
|
} elseif ($sort_relations_by_restype) {
|
|
foreach ($related_restypes as $rtype) {
|
|
if (in_array($rtype, $relatedtypes_shown)) {
|
|
// Don't show this type again.
|
|
continue;
|
|
}
|
|
?>
|
|
<h4><?php echo escape($allrestypes_names[$rtype]); ?></h4>
|
|
<?php
|
|
// Loop and display the results by file extension
|
|
for ($n = 0; $n < count($arr_related); $n++) {
|
|
if ($arr_related[$n]["resource_type"] == $rtype) {
|
|
$rref = $arr_related[$n]["ref"];
|
|
$title = $arr_related[$n]["field" . $view_title_field];
|
|
$access = get_resource_access($rref);
|
|
$safeviewlink = generateURL(
|
|
$baseurl . "/pages/view.php",
|
|
["ref" => (int) $rref, "search" => "!related" . $ref]
|
|
);
|
|
// Swap title fields if necessary
|
|
if (
|
|
isset($metadata_template_title_field)
|
|
&& isset($metadata_template_resource_type)
|
|
&& $arr_related[$n]['resource_type'] == $metadata_template_resource_type
|
|
) {
|
|
$title = $arr_related[$n]["field" . $metadata_template_title_field];
|
|
}
|
|
?>
|
|
<!--Resource Panel-->
|
|
<div class="CollectionPanelShell">
|
|
<table border="0" class="CollectionResourceAlign">
|
|
<tr>
|
|
<td>
|
|
<a href="<?php echo $safeviewlink; ?>"
|
|
onClick="return CentralSpaceLoad(this,true);">
|
|
<?php
|
|
$thumbnail = get_resource_preview($arr_related[$n], ["col"], $access, $use_watermark);
|
|
if ($thumbnail !== false) {
|
|
render_resource_image($arr_related[$n], $thumbnail["url"], "collection");
|
|
} else {
|
|
echo get_nopreview_html((string) $arr_related[$n]["file_extension"], $arr_related[$n]['resource_type']);
|
|
} ?>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<div class="CollectionPanelInfo">
|
|
<a href="<?php echo $safeviewlink; ?>" onClick="return CentralSpaceLoad(this,true);">
|
|
<?php echo escape(tidy_trim(i18n_get_translated($title), $related_resources_title_trim)); ?>
|
|
</a>
|
|
</div>
|
|
<?php hook("relatedresourceaddlink"); ?>
|
|
</div>
|
|
<?php
|
|
} // End of this resource type
|
|
} // End of $arr_related
|
|
?>
|
|
<div class="clearerleft"> </div>
|
|
<?php
|
|
} // End of display loop by resource extension
|
|
// End of IF sorted relations
|
|
} else {
|
|
// Related resources (default view)
|
|
for ($n = 0; $n < count($arr_related); $n++) {
|
|
if (in_array($arr_related[$n]["resource_type"], $relatedtypes_shown)) {
|
|
// Don't show this type again.
|
|
continue;
|
|
}
|
|
$rref = $arr_related[$n]["ref"];
|
|
$title = $arr_related[$n]["field" . $view_title_field];
|
|
$access = get_resource_access($rref);
|
|
$safeviewlink = generateURL(
|
|
$baseurl . "/pages/view.php",
|
|
["ref" => (int) $rref, "search" => "!related" . $ref]
|
|
);
|
|
// Swap title fields if necessary
|
|
if (
|
|
isset($metadata_template_title_field)
|
|
&& isset($metadata_template_resource_type)
|
|
&& $arr_related[$n]["resource_type"] == $metadata_template_resource_type
|
|
) {
|
|
$title = $arr_related[$n]["field" . $metadata_template_title_field];
|
|
}
|
|
?>
|
|
<div class="CollectionPanelShell">
|
|
<table border="0" class="CollectionResourceAlign">
|
|
<tr>
|
|
<td>
|
|
<a href="<?php echo $safeviewlink; ?>"
|
|
onClick="return CentralSpaceLoad(this,true);">
|
|
<?php
|
|
$thumbnail = get_resource_preview($arr_related[$n], ["col"], $access, $use_watermark);
|
|
if ($thumbnail !== false) {
|
|
render_resource_image($arr_related[$n], $thumbnail["url"], "collection");
|
|
} else {
|
|
echo get_nopreview_html((string) $arr_related[$n]["file_extension"], $arr_related[$n]['resource_type']);
|
|
}
|
|
?>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<div class="CollectionPanelInfo">
|
|
<a href="<?php echo $safeviewlink; ?>" onClick="return CentralSpaceLoad(this,true);">
|
|
<?php echo escape(tidy_trim(i18n_get_translated($title), $related_resources_title_trim)); ?>
|
|
</a>
|
|
</div>
|
|
<?php hook("relatedresourceaddlink"); ?>
|
|
</div>
|
|
<?php
|
|
} // End of $arr_related
|
|
} // End related resources default display
|
|
} // End of if any related resources exist
|
|
?>
|
|
</div><!-- End of RecordResource -->
|
|
<?php if ($edit_access) {
|
|
// Add link to create new related resource and view as result set
|
|
$add_related_params = [
|
|
"ref" => -$userref,
|
|
"relateto" => $ref,
|
|
"noupload" => "true",
|
|
"recordonly" => "true",
|
|
"collection_add" => "false",
|
|
"redirecturl" => generateURL($baseurl . "/pages/view.php", $urlparams),
|
|
];
|
|
$addrelated_url = generateURL($baseurl_short . "pages/edit.php", $add_related_params);
|
|
?>
|
|
<div class="clearerleft"></div>
|
|
<a href="<?php echo $addrelated_url; ?>"
|
|
onclick="return CentralSpaceLoad(this, true);">
|
|
<?php echo LINK_PLUS . escape($lang['related_resource_create']); ?>
|
|
</a>
|
|
<?php
|
|
}?>
|
|
</div><!-- End of RelatedResources -->
|
|
</div><!-- End of RecordPanel -->
|
|
</div><!-- End of RecordBox -->
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Display appropriate field constraint for use on admin_resource_type_field_edit.php e.g. single select/Number
|
|
*
|
|
* @param int Metadata field ID
|
|
* @param int Current field type
|
|
*
|
|
* @return void
|
|
*
|
|
*/
|
|
function admin_resource_type_field_constraint(int $ref, int $currentvalue): void
|
|
{
|
|
global $lang;
|
|
$constraint=ps_value("SELECT field_constraint value FROM resource_type_field WHERE ref=?",array("i",$ref),0, "schema");
|
|
?>
|
|
<div class="clearerleft"></div>
|
|
</div> <!-- end question -->
|
|
<div class="Question">
|
|
<label><?php echo escape($lang["property-field_constraint"]) ?></label>
|
|
<select id="field_constraint" name="field_constraint" class="stdwidth" onchange="CentralSpacePost(this.form);">
|
|
|
|
<option value="0" <?php if ($constraint==0) { echo " selected"; } ?>><?php echo escape($lang["property-field_constraint-none"]) ?></option>
|
|
<option value="1" <?php if ($constraint==1) { echo " selected"; } ?>><?php echo escape(($currentvalue==FIELD_TYPE_TEXT_BOX_SINGLE_LINE ? $lang["property-field_constraint-number"] : $lang["property-field_constraint-singlekeyword"]))?></option>
|
|
</select>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Render metadata field option input on admin_resource_type_field_edit.php
|
|
*
|
|
* @param string $propertyname Field property/column name
|
|
* @param string $propertytitle Title
|
|
* @param string $helptext Help text
|
|
* @param mixed $type Input type (0=text,1=boolean,2=text area)
|
|
* @param mixed $currentvalue Current field setting
|
|
* @param int $fieldtype Field type. See definitions.php
|
|
* @param bool $system_date_field Is this field set as the system $date_field?
|
|
*
|
|
* @return void
|
|
*
|
|
*/
|
|
function admin_resource_type_field_option(string $propertyname,string $propertytitle, string $helptext, $type,$currentvalue,int $fieldtype, bool $system_date_field) : void
|
|
{
|
|
debug_function_call("admin_resource_type_field_option",func_get_args());
|
|
|
|
global $ref,$lang, $baseurl_short,$FIXED_LIST_FIELD_TYPES, $daterange_edtf_support, $allfields, $newfield,
|
|
$resource_type_array, $existingrestypes, $regexp_slash_replace, $resource_type_array;
|
|
if($propertyname=="linked_data_field")
|
|
{
|
|
if($fieldtype==FIELD_TYPE_DATE_RANGE && $daterange_edtf_support)
|
|
{
|
|
// The linked_data_field column is is only used for date range fields at present
|
|
$propertytitle = $lang["property-field_raw_edtf"];
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
$resource_types=get_resource_types("",true,false,true);
|
|
foreach($resource_types as $resource_type)
|
|
{
|
|
$resource_type_array[$resource_type["ref"]]=$resource_type["name"];
|
|
}
|
|
|
|
if($propertyname == 'regexp_filter')
|
|
{
|
|
$currentvalue = str_replace($regexp_slash_replace, '\\', (string) $currentvalue);
|
|
}
|
|
|
|
$alt_helptext=hook('rtfieldedithelptext', 'admin_resource_type_field_edit', array($propertyname));
|
|
if($alt_helptext!==false){
|
|
$helptext=$alt_helptext;
|
|
}
|
|
|
|
?>
|
|
<div class="Question" >
|
|
<label><?php echo ($propertytitle!="") ? escape((string) $propertytitle) : escape((string) $propertyname); ?></label>
|
|
<?php
|
|
if($propertyname=="global")
|
|
{
|
|
// Special case - new global/resource type selector
|
|
?>
|
|
<table>
|
|
<tr>
|
|
<td>
|
|
<input type="checkbox"
|
|
name="global"
|
|
id="globalfield"
|
|
value="1"
|
|
<?php if($currentvalue == 1) { ?> checked="checked"<?php } ?>s
|
|
onchange="showHideResTypeSelector();">
|
|
<?php echo escape($lang["resourcetype-global_field"]) ?>
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
foreach($resource_type_array as $resource_type=>$restypename)
|
|
{
|
|
?>
|
|
<tr>
|
|
<td>
|
|
<input type="checkbox"
|
|
name="field_restype_select_<?php echo escape($resource_type); ?>"
|
|
id="field_restype_select_<?php echo escape($resource_type); ?>"
|
|
class="field_restype_select"
|
|
value="1"
|
|
<?php if($currentvalue == 1) { ?> disabled="true"<?php } ?>
|
|
<?php if(in_array($resource_type,$existingrestypes)) { ?> checked="checked"<?php } ?>>
|
|
<?php echo escape($restypename) ?>
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
}
|
|
?>
|
|
</table>
|
|
<script>
|
|
function showHideResTypeSelector() {
|
|
if(jQuery("#globalfield").prop("checked")){
|
|
jQuery(".field_restype_select").display = 'none';
|
|
jQuery(".field_restype_select").prop('checked',false);
|
|
jQuery(".field_restype_select").prop('disabled',true);
|
|
}
|
|
else {
|
|
jQuery(".field_restype_select").display = 'block';
|
|
jQuery(".field_restype_select").prop('disabled',false);
|
|
}
|
|
}
|
|
</script>
|
|
<?php
|
|
}
|
|
elseif($propertyname=="type")
|
|
{
|
|
global $field_types;
|
|
|
|
// Sort so that the display order makes some sense
|
|
//natsort($field_types);
|
|
?>
|
|
<select id="field_edit_<?php echo escape((string) $propertyname); ?>"
|
|
name="<?php echo escape((string) $propertyname); ?>"
|
|
class="stdwidth"
|
|
onchange="
|
|
<?php if(!$newfield)
|
|
{?>
|
|
newval=parseInt(this.value);
|
|
if((jQuery.inArray(newval,fixed_list_fields) > -1) && (jQuery.inArray(current_type,text_fields) > -1))
|
|
{
|
|
jQuery('input[name=\'keywords_index\']')[0].checked = true;
|
|
|
|
if(confirm('<?php echo escape($lang["admin_resource_type_field_migrate_data_prompt"]) ?>'))
|
|
{
|
|
jQuery('#migrate_data').val('yes');
|
|
}
|
|
else
|
|
{
|
|
jQuery('#migrate_data').val('');
|
|
}
|
|
|
|
this.form.submit();
|
|
}
|
|
|
|
else if ((jQuery.inArray(newval,text_fields) > -1) && (jQuery.inArray(current_type,fixed_list_fields) > -1))
|
|
{
|
|
if(confirm('<?php echo escape($lang["admin_resource_type_field_cannot_migrate_data_prompt"]) ?>'))
|
|
{
|
|
this.form.submit();
|
|
} else {
|
|
jQuery('#field_edit_type').val(current_type);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.form.submit();
|
|
}
|
|
<?php
|
|
}
|
|
else
|
|
{
|
|
?>
|
|
this.form.submit();
|
|
<?php
|
|
}
|
|
?>
|
|
">
|
|
<?php
|
|
foreach($field_types as $field_type=>$field_type_description)
|
|
{
|
|
?>
|
|
<option value="<?php echo $field_type ?>"<?php if ($currentvalue == $field_type) { echo " selected"; } ?>><?php echo escape($lang[$field_type_description]) ; ?></option>
|
|
<?php
|
|
}
|
|
?>
|
|
</select>
|
|
<?php
|
|
if (in_array($currentvalue, $FIXED_LIST_FIELD_TYPES))
|
|
{
|
|
?>
|
|
<div class="clearerleft"></div>
|
|
</div> <!-- end question -->
|
|
|
|
<div class="Question">
|
|
<label><?php echo escape($lang['options']) ; ?></label>
|
|
<span><a href="<?php echo $baseurl_short ?>pages/admin/admin_manage_field_options.php?field=<?php echo $ref ?>" onClick="return CentralSpaceLoad(this,true);"><?php echo escape($lang['property-options_edit_link']) ; ?></a></span>
|
|
<div class="clearerleft"></div>
|
|
|
|
<?php
|
|
if(FIELD_TYPE_CATEGORY_TREE != $currentvalue)
|
|
{
|
|
?>
|
|
</div>
|
|
<?php
|
|
$field_index = array_search($ref, array_column($allfields, 'ref'));
|
|
$automatic_nodes_ordering = (false !== $field_index ? $allfields[$field_index]['automatic_nodes_ordering'] : 0);
|
|
?>
|
|
<div class="Question">
|
|
<label><?php echo escape($lang['property-automatic_nodes_ordering_label']) ; ?></label>
|
|
<input type="checkbox" name="automatic_nodes_ordering" value="1"<?php if(1 == $automatic_nodes_ordering) { ?> checked="checked"<?php } ?>>
|
|
<?php
|
|
// create constraints selector
|
|
admin_resource_type_field_constraint($ref, (int)$currentvalue);
|
|
}
|
|
}
|
|
elseif (in_array($currentvalue, array(FIELD_TYPE_TEXT_BOX_SINGLE_LINE)))
|
|
{
|
|
// create constraints selector
|
|
admin_resource_type_field_constraint($ref, (int)$currentvalue);
|
|
}
|
|
}
|
|
elseif($propertyname=="linked_data_field")
|
|
{
|
|
if ($fieldtype==FIELD_TYPE_DATE_RANGE && $daterange_edtf_support)
|
|
{
|
|
// The linked_data_field column is is only used for date range fields at present
|
|
// Used to store the raw EDTF string submitted
|
|
?>
|
|
<input id="linked_data_field" name="linked_data_field" type="text" class="stdwidth" value="<?php echo escape((string) $currentvalue)?>">
|
|
<?php
|
|
}
|
|
}
|
|
elseif($propertyname === 'tab')
|
|
{
|
|
?>
|
|
<select class="stdwidth" name="<?php echo escape($propertyname); ?>">
|
|
<?php
|
|
foreach(get_tab_name_options() as $tab_ref => $tab_name)
|
|
{
|
|
$selected = $tab_ref === (int) $currentvalue ? 'selected' : '';
|
|
?>
|
|
<option value="<?php echo (int) $tab_ref; ?>" <?php echo $selected; ?>><?php echo escape((string) $tab_name); ?></option>
|
|
<?php
|
|
}
|
|
?>
|
|
</select>
|
|
<?php
|
|
}
|
|
elseif($propertyname == 'partial_index')
|
|
{
|
|
?>
|
|
<input
|
|
id="field_edit_<?php echo escape((string) $propertyname); ?>"
|
|
name="<?php echo escape((string) $propertyname); ?>"
|
|
type="checkbox"
|
|
value="1"
|
|
<?php if ($currentvalue==1) { ?> checked="checked"<?php } ?>
|
|
onchange='handleIndexOptions(this, "field_edit_complete_index")'
|
|
>
|
|
<?php
|
|
}
|
|
elseif ($propertyname == 'complete_index')
|
|
{
|
|
?>
|
|
<input
|
|
id="field_edit_<?php echo escape((string) $propertyname); ?>"
|
|
name="<?php echo escape((string) $propertyname); ?>"
|
|
type="checkbox"
|
|
value="1"
|
|
<?php if ($currentvalue==1) { ?> checked="checked"<?php } ?>
|
|
onchange="handleIndexOptions(this, 'field_edit_partial_index')"
|
|
>
|
|
<?php
|
|
} elseif ($propertyname == 'sort_method') {
|
|
?>
|
|
<select class="stdwidth" name="<?php echo escape($propertyname); ?>">
|
|
<?php
|
|
foreach(FIELD_SORT_METHODS as $method => $value) {
|
|
$selected = $value === $currentvalue ? 'selected' : '';
|
|
?>
|
|
<option
|
|
value="<?php echo (int) $value; ?>" <?php echo $selected; ?>
|
|
><?php echo escape($lang["sort-method_$method"]); ?>
|
|
</option>
|
|
<?php }
|
|
?>
|
|
</select>
|
|
<?php
|
|
}
|
|
elseif($type==1)
|
|
{
|
|
if ($propertyname=="advanced_search" && $system_date_field)
|
|
{
|
|
?><input id="field_edit_<?php echo escape((string) $propertyname); ?>" name="<?php echo escape((string) $propertyname); ?>" type="checkbox" value="1" checked="checked" onclick="return false;"><?php
|
|
$helptext=$lang["property-system_date_help_text"];
|
|
}
|
|
else
|
|
{
|
|
?><input id="field_edit_<?php echo escape((string) $propertyname); ?>" name="<?php echo escape((string) $propertyname); ?>" type="checkbox" value="1" <?php if ($currentvalue==1) { ?> checked="checked"<?php } ?>><?php
|
|
}
|
|
}
|
|
elseif($type==2)
|
|
{
|
|
?>
|
|
<textarea class="stdwidth" rows="5" id="field_edit_<?php echo escape((string) $propertyname); ?>" name="<?php echo escape((string) $propertyname); ?>"><?php echo escape((string) $currentvalue)?></textarea>
|
|
<?php
|
|
}
|
|
else
|
|
{
|
|
?>
|
|
<input id="field_edit_<?php echo escape((string) $propertyname); ?>" name="<?php echo escape((string) $propertyname); ?>" type="text" class="stdwidth" value="<?php echo escape((string) $currentvalue)?>">
|
|
<?php
|
|
}
|
|
|
|
if($helptext!="")
|
|
{
|
|
?>
|
|
<div class="FormHelp" style="padding:0;clear:left;" >
|
|
<div class="FormHelpInner"><?php echo strip_tags_and_attributes(str_replace("%ref",$ref,$helptext), ["a"], ["href", "target"]) ?>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
if($propertyname == "name")
|
|
{
|
|
?>
|
|
<div id="shortname_err_msg" class="FormHelp DisplayNone" style="padding:0;clear:left;" >
|
|
<div class="FormHelpInner PageInformal"><?php echo escape($lang["warning_duplicate_shortname_fields"]) ; ?></div>
|
|
</div>
|
|
<script>
|
|
var validate_shortname_in_progress = false;
|
|
jQuery("input[name='name']").keyup(function(event)
|
|
{
|
|
if(validate_shortname_in_progress)
|
|
{
|
|
return;
|
|
}
|
|
|
|
validate_shortname_in_progress = true;
|
|
|
|
jQuery.get(
|
|
baseurl + "/pages/admin/ajax/validate_rtf_shortname.php",
|
|
{
|
|
ref: "<?php echo escape($ref); ?>",
|
|
new_shortname: event.target.value
|
|
},
|
|
function (response)
|
|
{
|
|
var err_msg_el = jQuery("#shortname_err_msg");
|
|
if(err_msg_el.hasClass("DisplayNone") === false)
|
|
{
|
|
err_msg_el.addClass("DisplayNone");
|
|
}
|
|
|
|
if(typeof response.data !== "undefined" && !response.data.valid)
|
|
{
|
|
err_msg_el.removeClass("DisplayNone");
|
|
}
|
|
|
|
validate_shortname_in_progress = false;
|
|
},
|
|
"json");
|
|
|
|
return;
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
?>
|
|
<div class="clearerleft"></div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* Renders a resource type selection dropdown
|
|
*
|
|
* @param string $label label for the field
|
|
* @param string $name name of form select
|
|
* @param string $class array CSS class to apply
|
|
* @param boolean $hidden optionally hide the question usng CSS display:none
|
|
* @param int $current Current selected value
|
|
*
|
|
* @return void
|
|
*/
|
|
function render_resource_type_selector_question(string $label, string $name, string $class = "stdwidth", bool $hidden = false, $current = 0) : void
|
|
{
|
|
global $lang;
|
|
$resource_types = get_resource_types('',true,false,true);
|
|
|
|
echo "<div class='Question' id='" . escape($name) . "'" . ($hidden ? " style='display:none;border-top:none;'" : "") . ">";
|
|
echo "<label for='" . escape($name) . "' >" . escape($label) . "</label>";
|
|
echo "<select name='" . escape($name) . "' id='" . escape($name) . "' class='" . $class . "'>";
|
|
echo "<option value='' selected >" . escape($lang["select"]) . "</option>";
|
|
foreach($resource_types as $resource_type)
|
|
{
|
|
$selected = ($resource_type["ref"] == $current ? "selected" : "");
|
|
echo "<option value='{$resource_type['ref']}' {$selected}>" . escape(lang_or_i18n_get_translated($resource_type['name'],'fieldtitle-')) . "</option>";
|
|
}
|
|
echo "</select>";
|
|
echo "<div class='clearerleft'></div>";
|
|
echo "</div>";
|
|
}
|
|
|
|
/**
|
|
* Render the Download info for the resource tool (on view page)
|
|
*
|
|
* @param int $ref Resource ref
|
|
* @param array $size_info Preview size information
|
|
* @param bool $downloadthissize Should the size be downloadable or requested?
|
|
* @param bool $view_in_browser Allow the size to be viewed directly in the browser
|
|
*/
|
|
function add_download_column($ref, $size_info, $downloadthissize, $view_in_browser=false)
|
|
{
|
|
global $save_as, $terms_download, $order_by, $lang, $baseurl, $k, $search, $request_adds_to_collection, $offset, $archive, $sort, $internal_share_access, $urlparams, $resource, $iOS_save,$download_usage;
|
|
$view_in_browser_msg = $view_in_browser ? $lang["view_in_browser"] : $lang["action-download"];
|
|
if ($downloadthissize)
|
|
{
|
|
?>
|
|
<td class="DownloadButton">
|
|
<?php
|
|
global $size_info_array;
|
|
$size_info_array = $size_info;
|
|
if(!hook("downloadbuttonreplace"))
|
|
{
|
|
if($terms_download || $save_as)
|
|
{
|
|
?>
|
|
<a id="downloadlink"
|
|
<?php
|
|
if (!hook("downloadlink","",array("ref=" . $ref . "&k=" . $k . "&size=" . $size_info["id"] . "&ext=" . $size_info["extension"], $view_in_browser)))
|
|
{
|
|
if ($view_in_browser)
|
|
{
|
|
echo "href=\"" . generateURL($baseurl . "/pages/terms.php",$urlparams,array("url"=> generateURL($baseurl . "/pages/download.php",$urlparams,array("size"=>$size_info["id"],"ext"=> $size_info["extension"],"direct"=>1,"noattach"=>true)))) . "\"";
|
|
}
|
|
else
|
|
{
|
|
echo "href=\"" . generateURL($baseurl . "/pages/terms.php",$urlparams,array("url"=> generateURL($baseurl . "/pages/download_progress.php",$urlparams,array("size"=>$size_info["id"],"ext"=> $size_info["extension"])))) . "\"";
|
|
}
|
|
}
|
|
|
|
if($iOS_save || $view_in_browser)
|
|
{
|
|
echo " target=\"_blank\"";
|
|
}
|
|
else
|
|
{
|
|
echo " onClick=\"return CentralSpaceLoad(this,true);\"";
|
|
}
|
|
?>>
|
|
<?php echo escape($view_in_browser_msg); ?>
|
|
</a>
|
|
<?php
|
|
}
|
|
elseif ($download_usage)
|
|
// download usage form displayed - load into main window
|
|
{
|
|
?>
|
|
<a id="downloadlink"
|
|
<?php
|
|
if (!hook("downloadlink","",array("ref=" . $ref . "&k=" . $k . "&size=" . $size_info["id"]. "&ext=" . $size_info["extension"])))
|
|
{
|
|
if ($view_in_browser)
|
|
{
|
|
echo "href=\"" . generateURL($baseurl . "/pages/download_usage.php",$urlparams,array("url"=> generateURL($baseurl . "/pages/download.php",$urlparams,array("size"=>$size_info["id"],"ext"=> $size_info["extension"],"direct"=>1,"noattach"=>true)))) . "\"";
|
|
}
|
|
else
|
|
{
|
|
echo "href=\"" . generateURL($baseurl . "/pages/download_usage.php",$urlparams,array("url"=> generateURL($baseurl . "/pages/download_progress.php",$urlparams,array("size"=>$size_info["id"],"ext"=> $size_info["extension"])))) . "\"";
|
|
}
|
|
}
|
|
|
|
if($iOS_save || $view_in_browser)
|
|
{
|
|
echo " target=\"_blank\"";
|
|
}
|
|
else
|
|
{
|
|
echo " onClick=\"return CentralSpaceLoad(this,true);\"";
|
|
}
|
|
?>>
|
|
<?php echo escape($view_in_browser_msg); ?>
|
|
</a>
|
|
<?php
|
|
}
|
|
else
|
|
{
|
|
?>
|
|
<a id="downloadlink"
|
|
<?php
|
|
if (!hook("downloadlink","",array("ref=" . $ref . "&k=" . $k . "&size=" . $size_info["id"]. "&ext=" . $size_info["extension"], $view_in_browser)))
|
|
{
|
|
if ($view_in_browser)
|
|
{
|
|
echo 'href="' . $baseurl . "/pages/download.php?direct=1&noattach=true&ref=" . urlencode($ref) . "&ext=" . $size_info['extension'] . "&k=" . urlencode($k) . '" target="_blank"';
|
|
}
|
|
else
|
|
{
|
|
echo 'href="#" onclick="directDownload(' . '\'' . $baseurl . '/pages/download_progress.php?ref=' . urlencode($ref) . '&size=' . $size_info['id'] . '&ext=' . $size_info['extension'] . '&k=' . urlencode($k) . '\'' . ', this)"';
|
|
}
|
|
}
|
|
?>>
|
|
<?php echo escape($view_in_browser_msg); ?>
|
|
</a>
|
|
<?php
|
|
}
|
|
|
|
unset($size_info_array);
|
|
}
|
|
?>
|
|
</td>
|
|
<?php
|
|
}
|
|
elseif (checkperm("q"))
|
|
{
|
|
if (!hook("resourcerequest"))
|
|
{
|
|
?>
|
|
<td class="DownloadButton">
|
|
<?php
|
|
if ($request_adds_to_collection && ($k=="" || $internal_share_access) && !checkperm('b')) // We can't add to a collection if we are accessing an external share, unless we are a logged in user
|
|
{
|
|
if (isset($size_info["id"]))
|
|
{
|
|
echo add_to_collection_link($ref,"alert('" . escape($lang["requestaddedtocollection"]) . "');",$size_info["id"]);
|
|
}
|
|
else
|
|
{
|
|
echo add_to_collection_link($ref);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
?><a href="<?php echo generateURL($baseurl . "/pages/resource_request.php",$urlparams) ?>" onClick="return CentralSpaceLoad(this,true);"><?php
|
|
}
|
|
echo escape($lang["action-request"]) ?>
|
|
</a>
|
|
</td>
|
|
<?php
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# No access to this size, and the request functionality has been disabled. Show just 'restricted'.
|
|
?><td class="DownloadButton DownloadDisabled"><?php echo escape($lang["access1"])?></td><?php
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render image on view.php
|
|
*
|
|
* @param array $resource Resource data
|
|
* @param array $context Array with following named elements
|
|
* "access" - Resource access
|
|
* "edit_access" - Resource edit access
|
|
*
|
|
* @return void
|
|
*
|
|
*/
|
|
function render_resource_view_image(array $resource, array $context)
|
|
{
|
|
global $lang;
|
|
$imageurl="";
|
|
|
|
$use_watermark = check_use_watermark();
|
|
$access = $context["access"] ?? 1; // Default to restricted
|
|
$edit_access = $context["edit_access"] ?? 0;
|
|
|
|
// Set the preview sizes to look for. Access will be checked by get_resource_preview()
|
|
// Retina mode uses 'scr' size
|
|
$viewsizes = (($GLOBALS["retina_mode"] || !$GLOBALS["resource_view_use_pre"]) && $access === 0) ? ["scr"]: [];
|
|
$viewsizes[] = "pre";
|
|
$viewsizes[] = "thm";
|
|
|
|
$imagepre = get_resource_preview($resource,$viewsizes, $access, $use_watermark);
|
|
if($imagepre)
|
|
{
|
|
$imageurl = $imagepre["url"];
|
|
$imagepath = $imagepre["path"];
|
|
$image_width = $imagepre["width"];
|
|
$image_height = $imagepre["height"];
|
|
$validimage = true;
|
|
}
|
|
else
|
|
{
|
|
?>
|
|
<div id="previewimagewrapper">
|
|
<?php echo get_nopreview_html((string) $resource["file_extension"], $resource["resource_type"]); ?>
|
|
</div>
|
|
<?php
|
|
return true;
|
|
}
|
|
|
|
$previewimagelink = generateURL("{$GLOBALS["baseurl"]}/pages/preview.php", $GLOBALS["urlparams"], array("ext" => $resource["preview_extension"])) . "&" . hook("previewextraurl");
|
|
$previewimagelink_onclick = 'return CentralSpaceLoad(this);';
|
|
|
|
if (!hook("replacepreviewlink"))
|
|
{
|
|
?>
|
|
<div id="previewimagewrapper">
|
|
<a id="previewimagelink"
|
|
class="enterLink"
|
|
href="<?php echo $previewimagelink; ?>"
|
|
title="<?php echo escape($lang["fullscreenpreview"]); ?>"
|
|
style="position:relative;"
|
|
onclick="<?php echo $previewimagelink_onclick; ?>">
|
|
<?php
|
|
}
|
|
?>
|
|
<img id="previewimage"
|
|
class="Picture"
|
|
src="<?php echo $imageurl; ?>"
|
|
alt="<?php echo escape($lang['fullscreenpreview']); ?>"
|
|
onload="jQuery('.DownloadDBlend').css('pointer-events','auto')"
|
|
GALLERYIMG="no"
|
|
<?php
|
|
if($GLOBALS["annotate_enabled"])
|
|
{
|
|
?>
|
|
data-original="<?php echo "{$GLOBALS["baseurl"]}/annotation/resource/" . (int) $resource["ref"]; ?>"
|
|
<?php
|
|
}
|
|
|
|
if($GLOBALS["retina_mode"])
|
|
{
|
|
?>
|
|
onload="this.width/=1.8;this.onload=null;"
|
|
<?php
|
|
}
|
|
?>/>
|
|
</a>
|
|
|
|
<?php
|
|
hook('aftersearchimg', '', array($resource["ref"]));
|
|
hook('previewextras'); ?>
|
|
|
|
<?php
|
|
if($validimage)
|
|
{
|
|
if ($GLOBALS["image_preview_zoom"])
|
|
{
|
|
$GLOBALS["image_preview_zoom"] = false;
|
|
$tile_region_support = false;
|
|
$not_jpg = strtolower((string)$resource['file_extension']) != "jpg";
|
|
$fulljpgsize = $not_jpg ? "hpr" : "";
|
|
$fulljpgext = $not_jpg ? 'jpg' : $resource['file_extension'];
|
|
$zoom_image_path = get_resource_path($resource["ref"], true, $fulljpgsize, false, $fulljpgext, true, 1, $use_watermark);
|
|
|
|
if($GLOBALS["preview_tiles"] && file_exists($zoom_image_path) && resource_download_allowed($resource["ref"], '', $resource['resource_type']))
|
|
{
|
|
$image_size = get_original_imagesize($resource["ref"], $zoom_image_path);
|
|
$image_width = (int) $image_size[1];
|
|
$image_height = (int) $image_size[2];
|
|
|
|
$tiles = compute_tiles_at_scale_factor(1, $image_width, $image_height);
|
|
$first_tile = (isset($tiles[0]['id']) ? $tiles[0]['id'] : '');
|
|
$last_tile = (isset($tiles[count($tiles) - 1]['id']) ? $tiles[count($tiles) - 1]['id'] : '');
|
|
if(
|
|
$first_tile !== '' && $last_tile !== ''
|
|
&& file_exists(get_resource_path($resource["ref"], true, $first_tile, false))
|
|
&& file_exists(get_resource_path($resource["ref"], true, $last_tile, false))
|
|
)
|
|
{
|
|
$tile_region_support = true;
|
|
}
|
|
}
|
|
|
|
if ($tile_region_support)
|
|
{
|
|
// Force $hide_real_filepath temporarily to get the download URL
|
|
$orig_hrfp = $GLOBALS["hide_real_filepath"];
|
|
$GLOBALS["hide_real_filepath"] = true;
|
|
$tile_url = get_resource_path($resource["ref"], false, '', false, $resource['file_extension'], true, 1, $use_watermark);
|
|
$GLOBALS["hide_real_filepath"] = $orig_hrfp;
|
|
|
|
// Generate the custom tile source object for OpenSeadragon
|
|
?>
|
|
<script>
|
|
var openseadragon_custom_tile_source = {
|
|
height: <?php echo $image_height; ?>,
|
|
width: <?php echo $image_width; ?>,
|
|
tileSize: <?php echo (int) $GLOBALS["preview_tile_size"]; ?>,
|
|
minLevel: 11,
|
|
getTileUrl: function(level, x, y)
|
|
{
|
|
var scale_factor = Math.pow(2, this.maxLevel - level);
|
|
var tile_url = '<?php echo $tile_url; ?>';
|
|
tile_url += '&tile_region=1';
|
|
tile_url += '&tile_scale=' + scale_factor;
|
|
tile_url += '&tile_row=' + y;
|
|
tile_url += '&tile_col=' + x;
|
|
|
|
console.info('[OpenSeadragon] level = %o, x (column) = %o, y (row) = %o, scale_factor = %o', level, x, y, scale_factor);
|
|
console.debug('[OpenSeadragon] tile_url = %o', tile_url);
|
|
return tile_url;
|
|
}
|
|
};
|
|
</script>
|
|
<?php
|
|
$GLOBALS["image_preview_zoom"] = true;
|
|
}
|
|
else
|
|
{
|
|
// Use static image of a higher resolution (lpr/scr) preview
|
|
foreach(['lpr', 'scr'] as $hrs)
|
|
{
|
|
$zoom_image_path = get_resource_path($resource["ref"], true, $hrs, false, $resource['preview_extension'], true, 1, $use_watermark);
|
|
$allowed_static_image_size = resource_download_allowed($resource["ref"], $hrs, $resource['resource_type']);
|
|
if(file_exists($zoom_image_path) && !resource_has_access_denied_by_RT_size($resource['resource_type'], $hrs) && $allowed_static_image_size)
|
|
{
|
|
$preview_url = get_resource_path($resource["ref"], false, $hrs, false, $resource['preview_extension'], true, 1, $use_watermark);
|
|
|
|
// Generate the custom tile source object for OpenSeadragon
|
|
$GLOBALS["image_preview_zoom_lib_required"] = true;
|
|
?>
|
|
<script>
|
|
var openseadragon_custom_tile_source = { type: 'image', url: '<?php echo $preview_url; ?>' };
|
|
</script>
|
|
<?php
|
|
$GLOBALS["image_preview_zoom"] = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (canSeePreviewTools())
|
|
{
|
|
if ($GLOBALS["annotate_enabled"])
|
|
{
|
|
include_once '../include/annotation_functions.php';
|
|
}
|
|
?>
|
|
|
|
<!-- Available tools to manipulate previews -->
|
|
<div id="PreviewTools" >
|
|
<script>
|
|
function is_another_tool_option_enabled(element)
|
|
{
|
|
var current_selected_tool = jQuery(element);
|
|
var tool_options_enabled = jQuery('#PreviewToolsOptionsWrapper')
|
|
.find('.ToolsOptionLink.Enabled')
|
|
.not(current_selected_tool);
|
|
|
|
if(tool_options_enabled.length === 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
styledalert('<?php echo escape($lang['not_allowed']); ?>', '<?php echo escape($lang['error_multiple_preview_tools']); ?>');
|
|
return true;
|
|
}
|
|
|
|
function toggleMode(element)
|
|
{
|
|
jQuery(element).toggleClass('Enabled');
|
|
}
|
|
</script>
|
|
|
|
<div id="PreviewToolsOptionsWrapper">
|
|
<?php
|
|
if($GLOBALS["annotate_enabled"] && file_exists($imagepath) && canSeeAnnotationsFields())
|
|
{
|
|
?>
|
|
<a class="ToolsOptionLink AnnotationsOption" href="#" onclick="toggleAnnotationsOption(this); return false;">
|
|
<i class='fa fa-pencil-square-o' aria-hidden="true"></i>
|
|
</a>
|
|
|
|
<script>
|
|
var rs_tagging_plugin_added = false;
|
|
|
|
function toggleAnnotationsOption(element)
|
|
{
|
|
var option = jQuery(element);
|
|
var preview_image = jQuery('#previewimage');
|
|
var preview_image_link = jQuery('#previewimagelink');
|
|
var img_copy_id = 'previewimagecopy';
|
|
var img_src = preview_image.attr('src');
|
|
|
|
// Setup Annotorious (has to be done only once)
|
|
if(!rs_tagging_plugin_added)
|
|
{
|
|
anno.addPlugin('RSTagging',
|
|
{
|
|
select : '<?php echo escape($lang['annotate_select'])?>',
|
|
annotations_endpoint: '<?php echo $GLOBALS["baseurl"]; ?>/pages/ajax/annotations.php',
|
|
nodes_endpoint : '<?php echo $GLOBALS["baseurl"]; ?>/pages/ajax/get_nodes.php',
|
|
resource : <?php echo (int) $resource["ref"]; ?>,
|
|
read_only : <?php echo $edit_access ? 'false' : 'true'; ?>,
|
|
// We pass CSRF token identifier separately in order to know what to get in the Annotorious plugin file
|
|
csrf_identifier: '<?php echo $GLOBALS["CSRF_token_identifier"]; ?>',
|
|
<?php echo generateAjaxToken('RSTagging'); ?>
|
|
});
|
|
|
|
<?php if ($GLOBALS["facial_recognition"]) { ?>
|
|
anno.addPlugin('RSFaceRecognition',
|
|
{
|
|
annotations_endpoint: '<?php echo $GLOBALS["baseurl"]; ?>/pages/ajax/annotations.php',
|
|
facial_recognition_endpoint: '<?php echo $GLOBALS["baseurl"]; ?>/pages/ajax/facial_recognition.php',
|
|
resource: <?php echo (int) $resource["ref"]; ?>,
|
|
facial_recognition_tag_field: <?php echo (int) $GLOBALS["facial_recognition_tag_field"]; ?>,
|
|
// We pass CSRF token identifier separately in order to know what to get in the Annotorious plugin file
|
|
fr_csrf_identifier: '<?php echo $GLOBALS["CSRF_token_identifier"]; ?>',
|
|
<?php echo generateAjaxToken('RSFaceRecognition'); ?>
|
|
});
|
|
<?php } ?>
|
|
|
|
rs_tagging_plugin_added = true;
|
|
|
|
// We have to wait for initialisation process to finish as this does ajax calls
|
|
// in order to set itself up
|
|
setTimeout(function ()
|
|
{
|
|
toggleAnnotationsOption(element);
|
|
},
|
|
1000);
|
|
|
|
return false;
|
|
}
|
|
|
|
// Feature enabled? Then disable it.
|
|
if(option.hasClass('Enabled'))
|
|
{
|
|
anno.destroy(preview_image.data('original'));
|
|
|
|
// Remove the copy and show the linked image again
|
|
jQuery('#' + img_copy_id).remove();
|
|
preview_image_link.show();
|
|
|
|
toggleMode(element);
|
|
|
|
return false;
|
|
}
|
|
|
|
// Always check no other conflicting preview tool option is enabled
|
|
if(is_another_tool_option_enabled(element))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Enable feature
|
|
// Hide the linked image for now and use a copy of it to annotate
|
|
var preview_image_copy = preview_image.clone(true);
|
|
preview_image_copy.prop('id', img_copy_id);
|
|
preview_image_copy.prop('src', img_src);
|
|
|
|
// Set the width and height of the image otherwise if the source of the file
|
|
// is fetched from download.php, Annotorious will not be able to determine its
|
|
// size
|
|
var preview_image_width=preview_image.width();
|
|
var preview_image_height=preview_image.height();
|
|
preview_image_copy.width( preview_image_width );
|
|
preview_image_copy.height( preview_image_height );
|
|
|
|
preview_image_copy.insertAfter(preview_image_link);
|
|
preview_image_link.hide();
|
|
|
|
anno.makeAnnotatable(document.getElementById(img_copy_id));
|
|
|
|
toggleMode(element);
|
|
|
|
return false;
|
|
}
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
if($GLOBALS["image_preview_zoom"])
|
|
{
|
|
# Process rotation from preview tweaks and use it to display the openseadragon preview in the correct orientation.
|
|
if (isset($resource['preview_tweaks']))
|
|
{
|
|
$preview_tweak_parts = explode('|', $resource['preview_tweaks']);
|
|
$osd_preview_rotation = 0;
|
|
if ($preview_tweak_parts[0] > 0 && is_numeric($preview_tweak_parts[0]))
|
|
{
|
|
$osd_preview_rotation = 360 - $preview_tweak_parts[0];
|
|
}
|
|
} ?>
|
|
|
|
<a class="ToolsOptionLink ImagePreviewZoomOption" href="#" onclick="return toggleImagePreviewZoomOption(this);">
|
|
<i class='fa fa-search-plus' aria-hidden="true"></i>
|
|
</a>
|
|
|
|
<script>
|
|
var openseadragon_viewer = null;
|
|
function toggleImagePreviewZoomOption(element)
|
|
{
|
|
var zoom_option_enabled = jQuery(element).hasClass('Enabled');
|
|
|
|
if(!zoom_option_enabled && is_another_tool_option_enabled(element))
|
|
{
|
|
// Don't enable the tool while a conflicting preview tool is enabled
|
|
return false;
|
|
}
|
|
else if(!zoom_option_enabled)
|
|
{
|
|
console.debug('Enabling image zoom with OpenSeadragon');
|
|
|
|
jQuery('#previewimagewrapper').prepend('<div id="openseadragon_viewer"></div>');
|
|
|
|
// Hide the usual preview image of the resource
|
|
jQuery('#previewimagelink').toggleClass('DisplayNone');
|
|
|
|
openseadragon_viewer = OpenSeadragon({
|
|
id: "openseadragon_viewer",
|
|
prefixUrl: "<?php echo $GLOBALS["baseurl"] . LIB_OPENSEADRAGON; ?>/images/",
|
|
degrees: <?php echo (int) $osd_preview_rotation; ?>,
|
|
// debugMode: true,
|
|
// debugGridColor: ['red'],
|
|
|
|
tileSources: openseadragon_custom_tile_source
|
|
});
|
|
}
|
|
else if(zoom_option_enabled)
|
|
{
|
|
console.debug('Disabling image zoom with OpenSeadragon');
|
|
openseadragon_viewer.destroy();
|
|
openseadragon_viewer = null;
|
|
jQuery('#openseadragon_viewer').remove();
|
|
|
|
// Show the usual preview image of the resource
|
|
jQuery('#previewimagelink').toggleClass('DisplayNone');
|
|
}
|
|
else
|
|
{
|
|
console.error('Something went wrong with toggleImagePreviewZoomOption');
|
|
}
|
|
|
|
toggleMode(element);
|
|
|
|
return false;
|
|
}
|
|
</script>
|
|
<?php
|
|
}
|
|
?>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
} /* end of canSeePreviewTools() */
|
|
}
|
|
?>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Render the resource tools for preview sizes
|
|
* @param array $resource Resource data - {@see get_resource_data()}
|
|
* @param array{'download_multisize': bool, "sizes"?: array, 'urlparams': array} $ctx Contextual information.
|
|
*/
|
|
function render_resource_tools_size_download_options(array $resource, array $ctx): void
|
|
{
|
|
$ref = $resource['ref'];
|
|
$download_multisize = $ctx['download_multisize'];
|
|
$sizes = $ctx['sizes'] ?? get_image_sizes($resource['ref'], false, $resource['file_extension'], false);
|
|
$urlparams = $ctx['urlparams'];
|
|
|
|
/** @var string Client side namespace to prevent clashes */
|
|
$ns = "Resource{$ref}{$ctx['context']}";
|
|
|
|
if (!(($resource['has_image'] !== RESOURCE_PREVIEWS_NONE) && $download_multisize)) {
|
|
return;
|
|
}
|
|
|
|
$allowed_sizes = [];
|
|
foreach ($sizes as $size) {
|
|
if ($size['id'] === '') {
|
|
continue;
|
|
}
|
|
|
|
$downloadthissize = resource_download_allowed($ref, $size['id'], $resource['resource_type']);
|
|
if (!$downloadthissize && !checkperm('q')) {
|
|
continue;
|
|
}
|
|
|
|
// Fake $size key entry used in JS land
|
|
$size['html'] = [
|
|
// to display the preview size info to the user when selecting a size
|
|
'size_info' => get_size_info($size),
|
|
// to update the download button when selecting a size
|
|
'download_column' => cast_echo_to_string('add_download_column', [$ref, $size, $downloadthissize]),
|
|
];
|
|
|
|
if (
|
|
$downloadthissize
|
|
&& $size['allow_preview'] == 1
|
|
&& !hook('previewlinkbar')
|
|
&& file_exists($size['path'])
|
|
) {
|
|
$GLOBALS['data_viewsize'] = $size['id']; # relied upon by some plugins (e.g lightbox)
|
|
|
|
// Fake $size key entry used in JS land to update the View button before showing it to the user
|
|
$size['html']['view_btn'] = [
|
|
'viewsizeurl' => (string) hook('getpreviewurlforsize'),
|
|
'href' => generateURL(
|
|
"{$GLOBALS['baseurl']}/pages/preview.php",
|
|
$urlparams,
|
|
['ext' => $resource['file_extension']]
|
|
)
|
|
. '&' . hook('previewextraurl'),
|
|
];
|
|
}
|
|
|
|
$allowed_sizes[$size['id']] = $size;
|
|
}
|
|
|
|
if ($allowed_sizes === []) {
|
|
return;
|
|
}
|
|
$modified_sizes = hook('modifyallowed_sizes', 'view', [$resource, $allowed_sizes]);
|
|
if ($modified_sizes !== false) {
|
|
$allowed_sizes = $modified_sizes;
|
|
}
|
|
|
|
$use_selector = count($allowed_sizes) > 1;
|
|
$render = function(bool $show_selector) use ($ns, $allowed_sizes, $resource): void {
|
|
if ($show_selector) {
|
|
?>
|
|
<select id="<?php echo escape($ns); ?>size">
|
|
<?php
|
|
foreach ($allowed_sizes as $allowed_size) {
|
|
echo render_dropdown_option($allowed_size['id'], $allowed_size['name']);
|
|
}
|
|
?>
|
|
</select>
|
|
<?php hook('append_to_download_filename_td', '', [$resource, $ns]); ?>
|
|
<div id="<?php echo escape($ns); ?>sizeInfo"><?php
|
|
echo $allowed_sizes[array_key_first($allowed_sizes)]['html']['size_info'];
|
|
?></div>
|
|
<?php
|
|
return;
|
|
}
|
|
|
|
// If only one size is available, render in the same way as the original file (ie not as a drop down selector).
|
|
$allowed_size = $allowed_sizes[array_key_first($allowed_sizes)];
|
|
?>
|
|
<h2><?php echo escape($allowed_size['name']); ?></h2>
|
|
<?php hook('append_to_download_filename_td', '', [$resource, $ns]); ?>
|
|
<div id="<?php echo escape($ns); ?>sizeInfo"><?php echo $allowed_size['html']['size_info']; ?></div>
|
|
<?php
|
|
};
|
|
$render_js_picker = function(bool $show_selector) use ($ns, $allowed_sizes) {
|
|
if ($show_selector) {
|
|
?>
|
|
const picker = jQuery('select#<?php echo escape($ns); ?>size');
|
|
const selected_size = picker.val();
|
|
updateSizeInfo('<?php echo escape($ns); ?>', selected_size);
|
|
updatePreviewLink('<?php echo escape($ns); ?>', selected_size, picker);
|
|
updateDownloadLink('<?php echo escape($ns); ?>', selected_size, picker);
|
|
<?php
|
|
return;
|
|
}
|
|
|
|
// If only one size is available, there's no "size" to select from so ensure functions get called correctly to
|
|
// the context.
|
|
$allowed_size = $allowed_sizes[array_key_first($allowed_sizes)];
|
|
?>
|
|
const picker = jQuery('.Picker #<?php echo escape($ns); ?>sizeInfo');
|
|
updatePreviewLink('<?php echo escape($ns); ?>', '<?php echo escape($allowed_size['id']); ?>', picker);
|
|
updateDownloadLink('<?php echo escape($ns); ?>', '<?php echo escape($allowed_size['id']); ?>', picker);
|
|
<?php
|
|
};
|
|
?>
|
|
<tr class="DownloadDBlend">
|
|
<td class="DownloadFileName Picker"><?php $render($use_selector); ?></td>
|
|
<td class="DownloadButton">
|
|
<a id="<?php echo escape($ns); ?>downloadlink" onclick="return CentralSpaceLoad(this, true);"><?php
|
|
echo escape($GLOBALS['lang']['action-download']);
|
|
?></a>
|
|
<a
|
|
id="<?php echo escape($ns); ?>previewlink"
|
|
class="enterLink previewsizelink DisplayNone"
|
|
href="#"
|
|
data-viewsize=""
|
|
data-viewsizeurl=""
|
|
><?php echo escape($GLOBALS['lang']["action-view"]); ?></a>
|
|
</td>
|
|
</tr>
|
|
<script>
|
|
function <?php echo escape($ns); ?>_get_preview_size_info()
|
|
{
|
|
return <?php
|
|
echo json_encode(
|
|
array_map(
|
|
get_sub_array_with(
|
|
[
|
|
'allow_preview',
|
|
'html',
|
|
]
|
|
),
|
|
$allowed_sizes
|
|
),
|
|
JSON_NUMERIC_CHECK
|
|
);
|
|
?>;
|
|
}
|
|
|
|
jQuery(document).ready(function() {
|
|
<?php $render_js_picker($use_selector); ?>
|
|
});
|
|
|
|
jQuery('select#<?php echo escape($ns); ?>size').change(function() {
|
|
const picker = jQuery(this);
|
|
const selected_size = picker.val();
|
|
updateSizeInfo('<?php echo escape($ns); ?>', selected_size);
|
|
updatePreviewLink('<?php echo escape($ns); ?>', selected_size, picker);
|
|
updateDownloadLink('<?php echo escape($ns); ?>', selected_size, picker);
|
|
});
|
|
<?php hook('append_to_resource_tools_size_download_options_script', '', [$ns, $allowed_sizes, $resource]); ?>
|
|
</script>
|
|
<?php
|
|
}
|