/** * Generate a catalogue entry URL moniker. * * @param array The URL parts to generate the moniker from. * @return string The generated moniker. */ function generate_catalogue_entry_moniker($url_parts) { require_code('catalogues'); $fields = get_catalogue_entry_field_values(NULL, intval($url_parts['id']), array(0), NULL); $field = array_shift($fields); $value = array_key_exists('effective_value_pure', $field) ? $field['effective_value_pure'] : $field['effective_value']; return strip_comcode($value); }
/** * Get a list of maps containing all the catalogue entries, and path information, under the specified category - and those beneath it, recursively. * * @param ID_TEXT The catalogue name * @param ?AUTO_LINK Only show entries submitted by this member (NULL: no filter) * @param ?AUTO_LINK The category being at the root of our recursion (NULL: true root) * @param ?string The tree up to this point in the recursion (NULL: blank, as we are starting the recursion) * @param ?ID_TEXT The name of the $category_id we are currently going through (NULL: look it up). This is here for efficiency reasons, as finding children IDs to recurse to also reveals the childs title * @param ?integer The number of recursive levels to search (NULL: all) * @param boolean Whether to only show for what may be edited by the current member * @return array A list of maps for all categories. Each map entry containins the fields 'id' (category ID) and 'tree' (tree path to the category, including the categories own title), and more. */ function get_catalogue_entries_tree($catalogue_name, $submitter = NULL, $category_id = NULL, $tree = NULL, $title = NULL, $levels = NULL, $editable_filter = false) { if (is_null($category_id)) { $is_tree = $GLOBALS['SITE_DB']->query_value_null_ok('catalogues', 'c_is_tree', array('c_name' => $catalogue_name)); } if (is_null($category_id) && is_null($levels)) { if ($GLOBALS['SITE_DB']->query_value('catalogue_categories', 'COUNT(*)', array('c_name' => $catalogue_name)) > 1000) { return array(); } // Too many! } if (is_null($category_id)) { if (is_null($is_tree)) { return array(); } if ($is_tree == 0) { $temp_rows = $GLOBALS['SITE_DB']->query_select('catalogue_categories', array('id', 'cc_title'), array('c_name' => $catalogue_name, 'cc_parent_id' => NULL), 'ORDER BY id DESC', 300); if (get_page_name() == 'cms_catalogues') { if (count($temp_rows) == 300) { attach_message(do_lang_tempcode('TOO_MUCH_CHOOSE__RECENT_ONLY', escape_html(integer_format(300))), 'warn'); } } $children = array(); foreach ($temp_rows as $row) { $children = array_merge(get_catalogue_entries_tree($catalogue_name, $submitter, $row['id'], NULL, get_translated_text($row['cc_title']), 1, $editable_filter), $children); } return $children; } $temp_rows = $GLOBALS['SITE_DB']->query_select('catalogue_categories', array('id', 'cc_title'), array('c_name' => $catalogue_name, 'cc_parent_id' => NULL), 'ORDER BY id', 1); if (!array_key_exists(0, $temp_rows)) { return array(); } $category_id = $temp_rows[0]['id']; $title = get_translated_text($temp_rows[0]['cc_title']); } if (is_null($tree)) { $tree = ''; } if (!has_category_access(get_member(), 'catalogues_catalogue', $catalogue_name)) { return array(); } if (get_value('disable_cat_cat_perms') !== '1' && !has_category_access(get_member(), 'catalogues_category', strval($category_id))) { return array(); } // Put our title onto our tree if (is_null($title)) { $title = get_translated_text($GLOBALS['SITE_DB']->query_value('catalogue_categories', 'cc_title', array('id' => $category_id))); } $tree .= $title; // We'll be putting all children in this entire tree into a single list $children = array(); $children[0] = array(); $children[0]['id'] = $category_id; $children[0]['title'] = $title; $children[0]['tree'] = $tree; // Children of this category $rows = $GLOBALS['SITE_DB']->query_select('catalogue_categories', array('id', 'cc_title'), array('cc_parent_id' => $category_id), '', 300); if (get_page_name() == 'cms_catalogues') { if (count($rows) == 300) { attach_message(do_lang_tempcode('TOO_MUCH_CHOOSE__RECENT_ONLY', escape_html(integer_format(300))), 'warn'); } } $where = array('cc_id' => $category_id); if (!is_null($submitter)) { $where['ce_submitter'] = $submitter; } $erows = $GLOBALS['SITE_DB']->query_select('catalogue_entries', array('id', 'ce_submitter'), $where, 'ORDER BY ce_add_date DESC', 300); if (get_page_name() == 'cms_catalogues') { if (count($erows) == 300) { attach_message(do_lang_tempcode('TOO_MUCH_CHOOSE__RECENT_ONLY', escape_html(integer_format(300))), 'warn'); } } $children[0]['entries'] = array(); foreach ($erows as $row) { if ($editable_filter && !has_edit_permission('mid', get_member(), $row['ce_submitter'], 'cms_catalogues', array('catalogues_catalogue', $catalogue_name, 'catalogues_category', $category_id))) { continue; } $entry_fields = get_catalogue_entry_field_values($catalogue_name, $row['id'], array(0)); $name = $entry_fields[0]['effective_value']; // 'Name' is value of first field $children[0]['entries'][$row['id']] = $name; } $children[0]['child_entry_count'] = count($children[0]['entries']); if ($levels === 0) { $children[0]['entries'] = array(); } $children[0]['child_count'] = count($rows); $tree .= ' > '; if ($levels !== 0) { foreach ($rows as $i => $child) { $rows[$i]['_cc_title'] = get_translated_text($child['cc_title']); } global $M_SORT_KEY; $M_SORT_KEY = '_cc_title'; usort($rows, 'multi_sort'); foreach ($rows as $child) { $child_id = $child['id']; $child_title = $child['_cc_title']; $child_tree = $tree; $child_children = get_catalogue_entries_tree($catalogue_name, $submitter, $child_id, $child_tree, $child_title, is_null($levels) ? NULL : $levels - 1, $editable_filter); $children = array_merge($children, $child_children); } } return $children; }
/** * Standard modular run function for CRON hooks. Searches for tasks to perform. */ function run() { if (!addon_installed('catalogues')) { return; } $time = time(); $done_reports = array('daily' => false, 'weekly' => false, 'monthly' => false, 'quarterly' => false); $catalogues = $GLOBALS['SITE_DB']->query('SELECT c_title,c_name,c_send_view_reports FROM ' . get_table_prefix() . 'catalogues WHERE ' . db_string_not_equal_to('c_send_view_reports', '') . ' AND ' . db_string_not_equal_to('c_send_view_reports', 'never')); $doing = array(); foreach ($catalogues as $catalogue) { switch ($catalogue['c_send_view_reports']) { case 'daily': $amount = 60 * 60 * 24; break; case 'weekly': $amount = 60 * 60 * 24 * 7; break; case 'monthly': $amount = 60 * 60 * 24 * 31; break; case 'quarterly': $amount = 60 * 60 * 24 * 93; break; default: $amount = NULL; } if (!is_null($amount)) { $last_time = intval(get_value('last_catalogue_reports_' . $catalogue['c_send_view_reports'])); if ($last_time <= $time - $amount) { // Mark done if (!$done_reports[$catalogue['c_send_view_reports']]) { set_value('last_catalogue_reports_' . $catalogue['c_send_view_reports'], strval($time)); $done_reports[$catalogue['c_send_view_reports']] = true; } $doing[] = $catalogue; // Mark as doing, rather than do immediately - so to avoid race conditions } } } if (count($doing) != 0) { require_code('notifications'); require_code('catalogues'); require_lang('catalogues'); } if (function_exists('set_time_limit')) { @set_time_limit(0); } // Now for the intensive part foreach ($doing as $catalogue) { $start = 0; do { // So, we find all the entries in their catalogue, and group them by submitters $entries = $GLOBALS['SITE_DB']->query_select('catalogue_entries', array('id', 'ce_submitter', 'ce_views', 'ce_views_prior'), array('c_name' => $catalogue['c_name']), 'ORDER BY ce_submitter', 2000, $start); $members = array(); foreach ($entries as $entry) { if (!array_key_exists($entry['ce_submitter'], $members)) { $members[$entry['ce_submitter']] = array(); } $members[$entry['ce_submitter']][] = $entry; } $catalogue_title = get_translated_text($catalogue['c_title']); $regularity = do_lang('VR_' . strtoupper($catalogue['c_send_view_reports'])); $fields = $GLOBALS['SITE_DB']->query_select('catalogue_fields', array('*'), array('c_name' => $catalogue['c_name']), 'ORDER BY id', 1); // And now we send out mails, and get ready for the next report foreach ($members as $member_id => $member) { // Work out the contents of the mail $buildup = ''; foreach ($member as $entry) { $field_values = get_catalogue_entry_field_values($catalogue['c_name'], $entry, array(0), $fields); $entry_title = $field_values[0]['effective_value']; $views = $entry['ce_views'] - $entry['ce_views_prior']; $GLOBALS['SITE_DB']->query_update('catalogue_entries', array('ce_views_prior' => $entry['ce_views']), array('id' => $entry['id']), '', 1); $temp = do_lang($catalogue['c_name'] . '__CATALOGUE_VIEW_REPORT_LINE', comcode_escape(is_object($entry_title) ? $entry_title->evaluate() : $entry_title), integer_format($views), NULL, NULL, false); if (is_null($temp)) { $temp = do_lang('DEFAULT__CATALOGUE_VIEW_REPORT_LINE', comcode_escape(is_object($entry_title) ? $entry_title->evaluate() : $entry_title), integer_format($views)); } $buildup .= $temp; } $mail = do_lang($catalogue['c_name'] . '__CATALOGUE_VIEW_REPORT', $buildup, comcode_escape($catalogue_title), $regularity, get_lang($member_id), false); if (is_null($mail)) { $mail = do_lang('DEFAULT__CATALOGUE_VIEW_REPORT', $buildup, comcode_escape($catalogue_title), array($regularity, get_site_name()), get_lang($member_id)); } $subject_tag = do_lang($catalogue['c_name'] . '__CATALOGUE_VIEW_REPORT_SUBJECT', $catalogue_title, get_site_name(), NULL, get_lang($member_id), false); if (is_null($subject_tag)) { $subject_tag = do_lang('DEFAULT__CATALOGUE_VIEW_REPORT_SUBJECT', comcode_escape($catalogue_title), comcode_escape(get_site_name()), NULL, get_lang($member_id)); } // Send actual notification dispatch_notification('catalogue_view_reports__' . $catalogue['c_name'], NULL, $subject_tag, $mail, array($member_id), A_FROM_SYSTEM_PRIVILEGED); } $start += 2000; } while (count($entries) == 2000); } }
/** * Get tempcode for a catalogue entry adding/editing form. * * @param ?ID_TEXT The catalogue for the entry (NULL: detect) * @param ?AUTO_LINK The category for the entry (NULL: first) * @param BINARY Whether the entry is validated * @param LONG_TEXT Staff notes * @param ?BINARY Whether rating is allowed (NULL: decide statistically, based on existing choices) * @param ?SHORT_INTEGER Whether comments are allowed (0=no, 1=yes, 2=review style) (NULL: decide statistically, based on existing choices) * @param ?BINARY Whether trackbacks are allowed (NULL: decide statistically, based on existing choices) * @param ?AUTO_LINK The ID of the entry (NULL: not yet added) * @return array A pair: the tempcode for the visible fields, and the tempcode for the hidden fields */ function get_form_fields($catalogue_name = NULL, $category_id = NULL, $validated = 1, $notes = '', $allow_rating = NULL, $allow_comments = NULL, $allow_trackbacks = NULL, $id = NULL) { list($allow_rating, $allow_comments, $allow_trackbacks) = $this->choose_feedback_fields_statistically($allow_rating, $allow_comments, $allow_trackbacks); if (is_null($catalogue_name)) { $catalogue_name = get_param('catalogue_name'); } require_code('feedback'); require_code('form_templates'); $fields = new ocp_tempcode(); $hidden = form_input_hidden('catalogue_name', $catalogue_name); global $NON_CANONICAL_PARAMS; $NON_CANONICAL_PARAMS[] = 'validated'; if (is_null($id) && is_null($category_id)) { $category_id = get_param_integer('category_id', NULL); $NON_CANONICAL_PARAMS[] = 'category_id'; $NON_CANONICAL_PARAMS[] = 'category_id_suggest'; } $this->add_text = do_lang('CATALOGUE_' . $catalogue_name . '_ADD_TEXT', escape_html(get_base_url()), NULL, NULL, NULL, false); $this->edit_text = do_lang('CATALOGUE_' . $catalogue_name . '_EDIT_TEXT', escape_html(get_base_url()), NULL, NULL, NULL, false); // Standard fields // =============== // Category if (is_null($id) && is_null($category_id) && get_value('no_confirm_url_spec_cats') !== '1') { $category_id = $GLOBALS['SITE_DB']->query_value_null_ok('catalogue_categories', 'MIN(id)', array('c_name' => $catalogue_name)); } if (!is_null($category_id) && (is_null($id) && get_value('no_confirm_url_spec_cats') === '1' || get_value('no_spec_cat__' . $catalogue_name) === '1')) { $hidden->attach(form_input_hidden('category_id', strval($category_id))); } else { if (is_null($id) && is_null($category_id)) { $category_id = get_param_integer('category_id_suggest', NULL); // Less forceful than 'category_id', as may be changed even with 'no_confirm_url_spec_cats' on } $fields->attach(form_input_tree_list(do_lang_tempcode('CATEGORY'), do_lang_tempcode('DESCRIPTION_CATEGORY_TREE'), 'category_id', NULL, 'choose_catalogue_category', array('catalogue_name' => $catalogue_name, 'addable_filter' => true), true, is_null($category_id) ? '' : strval($category_id))); } // Special fields // ============== if (!is_null($id)) { $special_fields = get_catalogue_entry_field_values($catalogue_name, $id); } else { $special_fields = $GLOBALS['SITE_DB']->query_select('catalogue_fields', array('*'), array('c_name' => $catalogue_name), 'ORDER BY cf_order'); } $field_groups = array(); require_code('fields'); foreach ($special_fields as $field_num => $field) { $NON_CANONICAL_PARAMS[] = 'field_' . strval($field['id']); $ob = get_fields_hook($field['cf_type']); $default = get_param('field_' . strval($field['id']), $field['cf_default']); if (array_key_exists('effective_value_pure', $field)) { $default = $field['effective_value_pure']; } elseif (array_key_exists('effective_value', $field)) { $default = $field['effective_value']; } $_cf_name = get_translated_text($field['cf_name']); $field_cat = ''; if (strpos($_cf_name, ': ') !== false) { $field_cat = substr($_cf_name, 0, strpos($_cf_name, ': ')); if ($field_cat . ': ' == $_cf_name) { $_cf_name = $field_cat; // Just been pulled out as heading, nothing after ": " } else { $_cf_name = substr($_cf_name, strpos($_cf_name, ': ') + 2); } } if (!array_key_exists($field_cat, $field_groups)) { $field_groups[$field_cat] = new ocp_tempcode(); } $_cf_description = escape_html(get_translated_text($field['cf_description'])); $GLOBALS['NO_DEBUG_MODE_FULLSTOP_CHECK'] = true; $result = $ob->get_field_inputter($_cf_name, $_cf_description, $field, $default, is_null($id), !array_key_exists($field_num + 1, $special_fields)); $GLOBALS['NO_DEBUG_MODE_FULLSTOP_CHECK'] = false; if (is_null($result)) { continue; } if (is_array($result)) { $field_groups[$field_cat]->attach($result[0]); $hidden->attach($result[1]); } else { $field_groups[$field_cat]->attach($result); } if (strpos($field['cf_type'], '_trans') !== false) { $this->do_preview = true; } unset($result); unset($ob); } if (array_key_exists('', $field_groups)) { $field_groups_blank = $field_groups['']; unset($field_groups['']); $field_groups = array_merge(array($field_groups_blank), $field_groups); } foreach ($field_groups as $field_group_title => $extra_fields) { if (is_integer($field_group_title)) { $field_group_title = $field_group_title == 0 ? '' : strval($field_group_title); } if ($field_group_title != '') { $fields->attach(do_template('FORM_SCREEN_FIELD_SPACER', array('TITLE' => $field_group_title))); } $fields->attach($extra_fields); } if ($validated == 0) { $validated = get_param_integer('validated', 0); if ($validated == 1) { attach_message(do_lang_tempcode('WILL_BE_VALIDATED_WHEN_SAVING')); } } if (has_some_cat_specific_permission(get_member(), 'bypass_validation_' . $this->permissions_require . 'range_content', NULL, $this->permissions_cat_require_b) || has_some_cat_specific_permission(get_member(), 'bypass_validation_' . $this->permissions_require . 'range_content', NULL, $this->permissions_cat_require)) { if (addon_installed('unvalidated')) { if (count($field_groups) != 1) { $fields->attach(do_template('FORM_SCREEN_FIELD_SPACER', array('TITLE' => do_lang_tempcode('SETTINGS')))); } $fields->attach(form_input_tick(do_lang_tempcode('VALIDATED'), do_lang_tempcode('DESCRIPTION_VALIDATED'), 'validated', $validated == 1)); } } require_code('feedback2'); $fields->attach(feedback_fields($allow_rating == 1, $allow_comments == 1, $allow_trackbacks == 1, false, $notes, $allow_comments == 2)); return array($fields, $hidden); }
/** * Calculate product price * * @param AUTO_LINK Catalogue entry id * @param integer Quantity to deduct */ function update_stock($entry_id, $quantity) { require_code('catalogues'); $stock_level_warn_threshold = 0; $current_stock = 0; $stock_maintained = false; $res = $GLOBALS['SITE_DB']->query_select('catalogue_entries', array('c_name', 'cc_id'), array('id' => $entry_id), '', 1); if (!array_key_exists(0, $res)) { return; } $row = $res[0]; $catalogue_name = $row['c_name']; $fields = get_catalogue_entry_field_values($catalogue_name, $entry_id, NULL, NULL, true); if (array_key_exists(3, $fields)) { if (is_object($fields[3]['effective_value'])) { $fields[3]['effective_value'] = $fields[3]['effective_value']->evaluate(); } if ($fields[3]['effective_value'] == '') { return; } $stock_field = $fields[3]['id']; $current_stock = intval($fields[3]['effective_value']); } if (array_key_exists(4, $fields)) { if (is_object($fields[4]['effective_value'])) { $fields[4]['effective_value'] = $fields[4]['effective_value']->evaluate(); } if (is_null($fields[4]['effective_value'])) { return; } $stock_maintained = intval($fields[4]['effective_value']) == 1; } if (array_key_exists(5, $fields)) { if (is_object($fields[5]['effective_value'])) { $fields[5]['effective_value'] = $fields[5]['effective_value']->evaluate(); } if (is_null($fields[5]['effective_value'])) { return; } $stock_level_warn_threshold = intval($fields[5]['effective_value']); } $product_name = get_translated_text($row['cc_id']); if ($current_stock < $quantity && $stock_maintained) { require_code('site'); attach_message(do_lang_tempcode('LOW_STOCK_DISPATCH_FAILED', $product_name)); } $stock_after_dispatch = $current_stock - $quantity; if ($stock_after_dispatch < $stock_level_warn_threshold) { stock_maintain_warn_mail($product_name, $entry_id); } $GLOBALS['SITE_DB']->query_update('catalogue_efv_integer', array('cv_value' => intval($stock_after_dispatch)), array('cf_id' => $stock_field, 'ce_id' => $entry_id)); }
/** * Append fields to content add/edit form for gathering custom fields. * * @param ID_TEXT Award hook codename * @param ?ID_TEXT Content entry ID (NULL: new entry) * @param tempcode Fields (passed by reference) * @param tempcode Hidden Fields (passed by reference) */ function append_form_custom_fields($content_type, $id, &$fields, &$hidden) { require_code('catalogues'); $catalogue_entry_id = get_bound_content_entry($content_type, $id); if (!is_null($catalogue_entry_id)) { $special_fields = get_catalogue_entry_field_values('_' . $content_type, $catalogue_entry_id); } else { $special_fields = $GLOBALS['SITE_DB']->query_select('catalogue_fields', array('*'), array('c_name' => '_' . $content_type), 'ORDER BY cf_order'); } $field_groups = array(); require_code('fields'); foreach ($special_fields as $field_num => $field) { $ob = get_fields_hook($field['cf_type']); $default = get_param('field_' . strval($field['id']), $field['cf_default']); if (array_key_exists('effective_value_pure', $field)) { $default = $field['effective_value_pure']; } elseif (array_key_exists('effective_value', $field)) { $default = $field['effective_value']; } $_cf_name = get_translated_text($field['cf_name']); $field_cat = ''; $matches = array(); if (strpos($_cf_name, ': ') !== false) { $field_cat = substr($_cf_name, 0, strpos($_cf_name, ': ')); if ($field_cat . ': ' == $_cf_name) { $_cf_name = $field_cat; // Just been pulled out as heading, nothing after ": " } else { $_cf_name = substr($_cf_name, strpos($_cf_name, ': ') + 2); } } if (!array_key_exists($field_cat, $field_groups)) { $field_groups[$field_cat] = new ocp_tempcode(); } $_cf_description = escape_html(get_translated_text($field['cf_description'])); $GLOBALS['NO_DEBUG_MODE_FULLSTOP_CHECK'] = true; $result = $ob->get_field_inputter($_cf_name, $_cf_description, $field, $default, true, !array_key_exists($field_num + 1, $special_fields)); $GLOBALS['NO_DEBUG_MODE_FULLSTOP_CHECK'] = false; if (is_null($result)) { continue; } if (is_array($result)) { $field_groups[$field_cat]->attach($result[0]); $hidden->attach($result[1]); } else { $field_groups[$field_cat]->attach($result); } $hidden->attach(form_input_hidden('label_for__field_' . strval($field['id']), $_cf_name)); unset($result); unset($ob); } if (array_key_exists('', $field_groups)) { $field_groups_blank = $field_groups['']; unset($field_groups['']); $field_groups = array_merge(array($field_groups_blank), $field_groups); } foreach ($field_groups as $field_group_title => $extra_fields) { if (is_integer($field_group_title)) { $field_group_title = $field_group_title == 0 ? '' : strval($field_group_title); } if ($field_group_title != '') { $fields->attach(do_template('FORM_SCREEN_FIELD_SPACER', array('TITLE' => $field_group_title))); } $fields->attach($extra_fields); } }