AAAAPKj>\6 index.htmlnuW+APKj>\6maps/index.htmlnuW+APKj>\)maps/.htaccessnuW+A Order allow,deny Deny from all PKj>\8maps/default.phpnuW+Aescape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $lang = JFactory::getLanguage(); JText::script('COM_FINDER_MAPS_CONFIRM_DELETE_PROMPT'); ?>
items) == 0): ?> state->get('filter.branch') != 1) : ?> authorise('core.manage', 'com_finder'); ?> items as $i => $item) :?>
id); ?> title); $title = $lang->hasKey($key) ? JText::_($key) : $item->title; ?> state->get('filter.branch') == 1 && $item->num_children) : ?> escape($title); ?> escape($title); ?> num_children > 0) : ?> (num_children; ?>) num_nodes > 0) : ?> (num_nodes; ?>) state, $i, 'maps.', $canChange, 'cb'); ?>
pagination->getListFooter(); ?>
PKj>\) .htaccessnuW+A Order allow,deny Deny from all PKj>\6statistics/index.htmlnuW+APKj>\)statistics/.htaccessnuW+A Order allow,deny Deny from all PKj>\)index/.htaccessnuW+A Order allow,deny Deny from all PKj>\6index/index.htmlnuW+APKj>\6ǚ--index/default.phpnuW+Aescape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $lang = JFactory::getLanguage(); JText::script('COM_FINDER_INDEX_CONFIRM_PURGE_PROMPT'); JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); ?>
items) == 0): ?> authorise('core.manage', 'com_finder'); ?> items as $i => $item) : ?>
total == 0) { echo JText::_('COM_FINDER_INDEX_NO_DATA') . ' ' . JText::_('COM_FINDER_INDEX_TIP'); } else { echo JText::_('COM_FINDER_INDEX_NO_CONTENT'); } ?>
link_id); ?> publish_start_date) or intval($item->publish_end_date) or intval($item->start_date) or intval($item->end_date)) : ?> escape($item->title); ?> published, $i, 'index.', $canChange, 'cb'); ?> t_title); echo $lang->hasKey($key) ? JText::_($key) : $item->t_title; ?> url) > 80) { echo substr($item->url, 0, 70) . '...'; } else { echo $item->url; } ?> indexdate, JText::_('DATE_FORMAT_LC4')); ?>
pagination->getListFooter(); ?>
PKj>\)filters/.htaccessnuW+A Order allow,deny Deny from all PKj>\6filters/index.htmlnuW+APKj>\DWWfilters/default.phpnuW+Aget('id'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); ?>
items) == 0): ?> items as $i => $item) : $canCreate = $user->authorise('core.create', 'com_finder'); $canEdit = $user->authorise('core.edit', 'com_finder'); $canCheckin = $user->authorise('core.manage', 'com_checkin') || $filter->checked_out == $user->get('id') || $filter->checked_out == 0; $canChange = $user->authorise('core.edit.state', 'com_finder') && $canCheckin; ?>
total == 0): echo JText::_('COM_FINDER_NO_FILTERS'); ?>
filter_id); ?> checked_out) { echo JHtml::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'filters.', $canCheckin); } ?> escape($item->title); ?> escape($item->title); } ?> state, $i, 'filters.', $canChange); ?> created_by_alias ? $item->created_by_alias : $item->user_name; ?> created, JText::_('DATE_FORMAT_LC4')); ?> map_count; ?> filter_id; ?>
pagination->getListFooter(); ?>
PKj>\)filter/.htaccessnuW+A Order allow,deny Deny from all PKj>\6filter/index.htmlnuW+APKx>\s js/highlighter.jsnuW+Avar Highlighter = new Class({ options: { autoUnhighlight: true, caseSensitive: false, startElement: false, endElement: false, elements: new Array(), className: 'highlight', onlyWords: true, tag: 'span' }, initialize: function (options) { this.setOptions(options); this.getElements(this.options.startElement, this.options.endElement); this.words = []; }, highlight: function (words) { if (words.constructor === String) { words = [words]; } if (this.options.autoUnhighlight) { this.unhighlight(words); } var pattern = this.options.onlyWords ? '\b' + pattern + '\b' : '(' + words.join('\\b|\\b') + ')'; var regex = new RegExp(pattern, this.options.caseSensitive ? '' : 'i'); this.options.elements.each(function (el) { this.recurse(el, regex, this.options.className); }, this); return this; }, unhighlight: function (words) { if (words.constructor === String) { words = [words]; } words.each(function (word) { word = (this.options.caseSensitive ? word : word.toUpperCase()); if (this.words[word]) { var elements = $$(this.words[word]); elements.setProperty('class', ''); elements.each(function (el) { var tn = document.createTextNode(el.getText()); el.getParent().replaceChild(tn, el); }); } }, this); return this; }, recurse: function (node, regex, klass) { if (node.nodeType === 3) { var match = node.data.match(regex); if (match) { var highlight = new Element(this.options.tag); highlight.addClass(klass); var wordNode = node.splitText(match.index); wordNode.splitText(match[0].length); var wordClone = wordNode.cloneNode(true); highlight.appendChild(wordClone); wordNode.parentNode.replaceChild(highlight, wordNode); highlight.setProperty('rel', highlight.get('text')); var comparer = highlight.get('text'); if (!this.options.caseSensitive) { comparer = highlight.get('text').toUpperCase(); } if (!this.words[comparer]) { this.words[comparer] = []; } this.words[comparer].push(highlight); return 1; } } else if ((node.nodeType === 1 && node.childNodes) && !/(script|style|textarea|iframe)/i.test(node.tagName) && !(node.tagName === this.options.tag.toUpperCase() && node.className === klass)) { for (var i = 0; i < node.childNodes.length; i++) { i += this.recurse(node.childNodes[i], regex, klass); } } return 0; }, getElements: function (start, end) { var next = start.getNext(); if (next.id != end.id) { this.options.elements.include(next); this.getElements(next, end); } } }); Highlighter.implement(new Options); window.addEvent('domready', function () { var start = document.id('highlighter-start'); var end = document.id('highlighter-end'); if (!start || !end || !window.highlight) { return true; } highlighter = new Highlighter({ startElement: start, endElement: end, autoUnhighlight: true, onlyWords: false }).highlight(window.highlight); start.dispose(); end.dispose(); });PKx>\ȇ**js/sliderfilter.jsnuW+AFinderFilter = new Class({ Extends: Fx.Elements, options: { onActive: Class.empty, onBackground: Class.empty, height: false, width: true, opacity: true, fixedHeight: false, fixedWidth: 220, wait: true }, initialize: function (togglers, elements, container, frame) { this.togglers = togglers || []; this.elements = elements || []; this.container = document.id(container); this.frame = document.id(frame); this.effects = {}; if (this.options.opacity) this.effects.opacity = 'fullOpacity'; if (this.options.width) this.effects.width = this.options.fixedWidth ? 'fullWidth' : 'offsetWidth'; this.container.setStyle('width', '230px'); this.addEvent('onActive', function (toggler, element) { element.set('styles', { 'border-top': '1px solid #ccc', 'border-right': '1px solid #ccc', 'border-bottom': '1px solid #ccc', 'overflow': 'auto' }); this.container.set('styles', { width: this.container.getStyle('width').toInt() + element.fullWidth }); coord = element.getCoordinates([this.frame]); scroller = new Fx.Scroll(frame); scroller.start(coord.top, coord.left); }); this.addEvent('onBackground', function () { el = this.elements[this.active]; el.getElements('input').each(function (n) { n.removeProperty('checked'); }); }); this.addEvent('onComplete', function () { el = this.elements[this.active]; if (!el.getStyle('width').toInt()) { this.container.set('styles', { 'width': this.container.getStyle('width').toInt() - el.fullWidth }); } this.active = null; }); for (var i = 0, l = this.togglers.length; i < l; i++) this.addSection(this.togglers[i], this.elements[i]); this.elements.each(function (el, i) { var cbs = el.getElements('input.selector').length; var cba = 0; el.getElements('input.selector').each(function (n) { if (n.getProperty('checked')) { this.togglers[i].setProperty('checked', 'checked'); cba += 1; } }, this); if (cbs > 0 && cbs === cba && el.getElement('input.branch-selector') != null) { el.getElement('input.branch-selector').setProperty('checked', 'checked'); } if (cba) { this.fireEvent('onActive', [this.togglers[i], el]); } else { for (var fx in this.effects) el.setStyle(fx, 0); } el.getElement('dt').getElement('input').addEvent('change', function (e) { if (e.target.getProperty('checked')) { el.getElements('dd').each(function (dd) { dd.getElement('input').setProperty('checked', 'checked'); }); } else { el.getElements('dd').each(function (dd) { dd.getElement('input').removeProperty('checked'); }); } }); }, this); }, addSection: function (toggler, element, pos) { toggler = document.id(toggler); element = document.id(element); var test = this.togglers.contains(toggler); var len = this.togglers.length; this.togglers.include(toggler); this.elements.include(element); if (len && (!test || pos)) { pos = Array.pick(pos, len - 1); toggler.inject(this.togglers[pos], 'before'); element.inject(toggler, 'after'); } else if (this.container && !test) { toggler.inject(this.container); element.inject(this.container); } var idx = this.togglers.indexOf(toggler); toggler.addEvent('click', this.toggle.bind(this, idx)); if (this.options.width) element.set('styles', { 'padding-left': 0, 'border-left': 'none', 'padding-right': 0, 'border-right': 'none' }); element.fullOpacity = 1; if (this.options.fixedWidth) element.fullWidth = this.options.fixedWidth; if (this.options.fixedHeight) element.fullHeight = this.options.fixedHeight; element.set('styles', {'overflow': 'hidden'}); return this; }, toggle: function (index) { index = (typeOf(index) == 'element') ? this.elements.indexOf(index) : index; if (this.timer && this.options.wait) return this; this.active = index; var obj = {}; obj[index] = {}; var el = this.elements[index]; if (this.togglers[index].getProperty('checked')) { for (var fx in this.effects) obj[index][fx] = el[this.effects[fx]]; this.start(obj); this.fireEvent('onActive', [this.togglers[index], el]); } else { for (var fx in this.effects) obj[index][fx] = 0; this.start(obj); this.fireEvent('onBackground', [this.togglers[index], el]); } return this; } }); window.addEvent('domready', function () { Filter = new FinderFilter(document.getElements('input.toggler'), document.getElements('dl.checklist'), document.id('finder-filter-container'), document.id('finder-filter-window')); document.id('tax-select-all').addEvent('change', function () { if (document.id('tax-select-all').getProperty('checked')) { document.id('finder-filter-window').getElements('input').each(function (input) { if (input.getProperty('id') != 'tax-select-all') { input.removeProperty('checked'); } }); } }); });PKx>\I4o??js/autocompleter.jsnuW+Avar Observer = new Class({ Implements: [Options, Events], options: { periodical: false, delay: 1000 }, initialize: function (el, onFired, options) { this.element = document.id(el) || $document.id(el); this.addEvent('onFired', onFired); this.setOptions(options); this.bound = this.changed.bind(this); this.resume(); }, changed: function () { var value = this.element.get('value'); if ($equals(this.value, value)) return; this.clear(); this.value = value; this.timeout = this.onFired.delay(this.options.delay, this); }, setValue: function (value) { this.value = value; this.element.set('value', value); return this.clear(); }, onFired: function () { this.fireEvent('onFired', [this.value, this.element]); }, clear: function () { clearTimeout(this.timeout || null); return this; }, pause: function () { if (this.timer) clearTimeout(this.timer); else this.element.removeEvent('keyup', this.bound); return this.clear(); }, resume: function () { this.value = this.element.get('value'); if (this.options.periodical) this.timer = this.changed.periodical(this.options.periodical, this); else this.element.addEvent('keyup', this.bound); return this; } }); var $equals = function (obj1, obj2) { return (obj1 == obj2 || JSON.encode(obj1) == JSON.encode(obj2)); }; var Autocompleter = new Class({ Implements: [Options, Events], options: { minLength: 1, markQuery: true, width: 'inherit', maxChoices: 10, injectChoice: null, customChoices: null, emptyChoices: null, visibleChoices: true, className: 'autocompleter-choices', zIndex: 1000, delay: 400, observerOptions: {}, fxOptions: {}, autoSubmit: false, overflow: false, overflowMargin: 25, selectFirst: false, filter: null, filterCase: false, filterSubset: false, forceSelect: false, selectMode: true, choicesMatch: null, multiple: false, separator: ', ', separatorSplit: /\s*[,;]\s*/, autoTrim: false, allowDupes: false, cache: true, relative: false }, initialize: function (element, options) { this.element = document.id(element); this.setOptions(options); this.build(); this.observer = new Observer(this.element, this.prefetch.bind(this), Object.merge({}, { 'delay': this.options.delay }, this.options.observerOptions)); this.queryValue = null; if (this.options.filter) this.filter = this.options.filter.bind(this); var mode = this.options.selectMode; this.typeAhead = (mode == 'type-ahead'); this.selectMode = (mode === true) ? 'selection' : mode; this.cached = []; }, build: function () { if (document.id(this.options.customChoices)) { this.choices = this.options.customChoices; } else { this.choices = new Element('ul', { 'class': this.options.className, 'styles': { 'zIndex': this.options.zIndex } }).inject(document.body); this.relative = false; if (this.options.relative) { this.choices.inject(this.element, 'after'); this.relative = this.element.getOffsetParent(); } this.fix = new OverlayFix(this.choices); } if (!this.options.separator.test(this.options.separatorSplit)) { this.options.separatorSplit = this.options.separator; } this.fx = (!this.options.fxOptions) ? null : new Fx.Tween(this.choices, Object.merge({}, { 'property': 'opacity', 'link': 'cancel', 'duration': 200 }, this.options.fxOptions)).addEvent('onStart', Chain.prototype.clearChain).set(0); this.element.setProperty('autocomplete', 'off').addEvent((Browser.ie || Browser.safari || Browser.chrome) ? 'keydown' : 'keypress', this.onCommand.bind(this)).addEvent('click', this.onCommand.bind(this, [false])).addEvent('focus', this.toggleFocus.create({ bind: this, arguments: true, delay: 100 })).addEvent('blur', this.toggleFocus.create({ bind: this, arguments: false, delay: 100 })); }, destroy: function () { if (this.fix) this.fix.destroy(); this.choices = this.selected = this.choices.destroy(); }, toggleFocus: function (state) { this.focussed = state; if (!state) this.hideChoices(true); this.fireEvent((state) ? 'onFocus' : 'onBlur', [this.element]); }, onCommand: function (e) { if (!e && this.focussed) return this.prefetch(); if (e && e.key && !e.shift) { switch (e.key) { case 'enter': if (this.element.value != this.opted) return true; if (this.selected && this.visible) { this.choiceSelect(this.selected); return !!(this.options.autoSubmit); } break; case 'up': case 'down': if (!this.prefetch() && this.queryValue !== null) { var up = (e.key == 'up'); this.choiceOver((this.selected || this.choices)[(this.selected) ? ((up) ? 'getPrevious' : 'getNext') : ((up) ? 'getLast' : 'getFirst')](this.options.choicesMatch), true); } return false; case 'esc': case 'tab': this.hideChoices(true); break; } } return true; }, setSelection: function (finish) { var input = this.selected.inputValue, value = input; var start = this.queryValue.length, end = input.length; if (input.substr(0, start).toLowerCase() != this.queryValue.toLowerCase()) start = 0; if (this.options.multiple) { var split = this.options.separatorSplit; value = this.element.value; start += this.queryIndex; end += this.queryIndex; var old = value.substr(this.queryIndex).split(split, 1)[0]; value = value.substr(0, this.queryIndex) + input + value.substr(this.queryIndex + old.length); if (finish) { var tokens = value.split(this.options.separatorSplit).filter(function (entry) { return this.test(entry); }, /[^\s,]+/); if (!this.options.allowDupes) tokens = [].combine(tokens); var sep = this.options.separator; value = tokens.join(sep) + sep; end = value.length; } } this.observer.setValue(value); this.opted = value; if (finish || this.selectMode == 'pick') start = end; this.element.selectRange(start, end); this.fireEvent('onSelection', [this.element, this.selected, value, input]); }, showChoices: function () { var match = this.options.choicesMatch, first = this.choices.getFirst(match); this.selected = this.selectedValue = null; if (this.fix) { var pos = this.element.getCoordinates(this.relative), width = this.options.width || 'auto'; this.choices.setStyles({ 'left': pos.left, 'top': pos.bottom, 'width': (width === true || width == 'inherit') ? pos.width : width }); } if (!first) return; if (!this.visible) { this.visible = true; this.choices.setStyle('display', ''); if (this.fx) this.fx.start(1); this.fireEvent('onShow', [this.element, this.choices]); } if (this.options.selectFirst || this.typeAhead || first.inputValue == this.queryValue) this.choiceOver(first, this.typeAhead); var items = this.choices.getChildren(match), max = this.options.maxChoices; var styles = { 'overflowY': 'hidden', 'height': '' }; this.overflown = false; if (items.length > max) { var item = items[max - 1]; styles.overflowY = 'scroll'; styles.height = item.getCoordinates(this.choices).bottom; this.overflown = true; }; this.choices.setStyles(styles); this.fix.show(); if (this.options.visibleChoices) { var scroll = document.getScroll(), size = document.getSize(), coords = this.choices.getCoordinates(); if (coords.right > scroll.x + size.x) scroll.x = coords.right - size.x; if (coords.bottom > scroll.y + size.y) scroll.y = coords.bottom - size.y; window.scrollTo(Math.min(scroll.x, coords.left), Math.min(scroll.y, coords.top)); } }, // TODO: No $arguments in MT 1.3 hideChoices: function (clear) { if (clear) { var value = this.element.value; if (this.options.forceSelect) value = this.opted; if (this.options.autoTrim) { value = value.split(this.options.separatorSplit).filter($arguments(0)).join(this.options.separator); } this.observer.setValue(value); } if (!this.visible) return; this.visible = false; if (this.selected) this.selected.removeClass('autocompleter-selected'); this.observer.clear(); var hide = function () { this.choices.setStyle('display', 'none'); this.fix.hide(); }.bind(this); if (this.fx) this.fx.start(0).chain(hide); else hide(); this.fireEvent('onHide', [this.element, this.choices]); }, prefetch: function () { var value = this.element.value, query = value; if (this.options.multiple) { var split = this.options.separatorSplit; var values = value.split(split); var index = this.element.getSelectedRange().start; var toIndex = value.substr(0, index).split(split); var last = toIndex.length - 1; index -= toIndex[last].length; query = values[last]; } if (query.length < this.options.minLength) { this.hideChoices(); } else { if (query === this.queryValue || (this.visible && query == this.selectedValue)) { if (this.visible) return false; this.showChoices(); } else { this.queryValue = query; this.queryIndex = index; if (!this.fetchCached()) this.query(); } } return true; }, fetchCached: function () { return false; if (!this.options.cache || !this.cached || !this.cached.length || this.cached.length >= this.options.maxChoices || this.queryValue) return false; this.update(this.filter(this.cached)); return true; }, update: function (tokens) { this.choices.empty(); this.cached = tokens; var type = tokens && typeOf(tokens); if (!type || (type == 'array' && !tokens.length) || (type == 'hash' && !tokens.getLength())) { (this.options.emptyChoices || this.hideChoices).call(this); } else { if (this.options.maxChoices < tokens.length && !this.options.overflow) tokens.length = this.options.maxChoices; tokens.each(this.options.injectChoice || function (token) { var choice = new Element('li', { 'html': this.markQueryValue(token) }); choice.inputValue = token; this.addChoiceEvents(choice).inject(this.choices); }, this); this.showChoices(); } }, choiceOver: function (choice, selection) { if (!choice || choice == this.selected) return; if (this.selected) this.selected.removeClass('autocompleter-selected'); this.selected = choice.addClass('autocompleter-selected'); this.fireEvent('onSelect', [this.element, this.selected, selection]); if (!this.selectMode) this.opted = this.element.value; if (!selection) return; this.selectedValue = this.selected.inputValue; if (this.overflown) { var coords = this.selected.getCoordinates(this.choices), margin = this.options.overflowMargin, top = this.choices.scrollTop, height = this.choices.offsetHeight, bottom = top + height; if (coords.top - margin < top && top) this.choices.scrollTop = Math.max(coords.top - margin, 0); else if (coords.bottom + margin > bottom) this.choices.scrollTop = Math.min(coords.bottom - height + margin, bottom); } if (this.selectMode) this.setSelection(); }, choiceSelect: function (choice) { if (choice) this.choiceOver(choice); this.setSelection(true); this.queryValue = false; this.hideChoices(); }, filter: function (tokens) { return (tokens || this.tokens).filter(function (token) { return this.test(token); }, new RegExp(((this.options.filterSubset) ? '' : '^') + this.queryValue.escapeRegExp(), (this.options.filterCase) ? '' : 'i')); }, markQueryValue: function (str) { return (!this.options.markQuery || !this.queryValue) ? str : str.replace(new RegExp('(' + ((this.options.filterSubset) ? '' : '^') + this.queryValue.escapeRegExp() + ')', (this.options.filterCase) ? '' : 'i'), '$1'); }, addChoiceEvents: function (el) { return el.addEvents({ 'mouseover': this.choiceOver.bind(this, el), 'click': this.choiceSelect.bind(this, el) }); } }); var OverlayFix = new Class({ initialize: function (el) { if (Browser.ie) { this.element = document.id(el); this.relative = this.element.getOffsetParent(); this.fix = new Element('iframe', { 'frameborder': '0', 'scrolling': 'no', 'src': 'javascript:false;', 'styles': { 'position': 'absolute', 'border': 'none', 'display': 'none', 'filter': 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)' } }).inject(this.element, 'after'); } }, show: function () { if (this.fix) { var coords = this.element.getCoordinates(this.relative); delete coords.right; delete coords.bottom; this.fix.setStyles(Object.append(coords, { 'display': '', 'zIndex': (this.element.getStyle('zIndex') || 1) - 1 })); } return this; }, hide: function () { if (this.fix) this.fix.setStyle('display', 'none'); return this; }, destroy: function () { if (this.fix) this.fix = this.fix.destroy(); } }); Element.implement({ getSelectedRange: function () { if (!Browser.ie) return { start: this.selectionStart, end: this.selectionEnd }; var pos = { start: 0, end: 0 }; var range = this.getDocument().selection.createRange(); if (!range || range.parentElement() != this) return pos; var dup = range.duplicate(); if (this.type == 'text') { pos.start = 0 - dup.moveStart('character', -100000); pos.end = pos.start + range.text.length; } else { var value = this.value; var offset = value.length - value.match(/[\n\r]*$/)[0].length; dup.moveToElementText(this); dup.setEndPoint('StartToEnd', range); pos.end = offset - dup.text.length; dup.setEndPoint('StartToStart', range); pos.start = offset - dup.text.length; } return pos; }, selectRange: function (start, end) { if (Browser.ie) { var diff = this.value.substr(start, end - start).replace(/\r/g, '').length; start = this.value.substr(0, start).replace(/\r/g, '').length; var range = this.createTextRange(); range.collapse(true); range.moveEnd('character', start + diff); range.moveStart('character', start); range.select(); } else { this.focus(); this.setSelectionRange(start, end); } return this; } }); Autocompleter.Base = Autocompleter; Autocompleter.Request = new Class({ Extends: Autocompleter, options: { postData: {}, ajaxOptions: {}, postVar: 'value' }, query: function () { var data = this.options.postData.unlink || {}; data[this.options.postVar] = this.queryValue; var indicator = document.id(this.options.indicator); if (indicator) indicator.setStyle('display', ''); var cls = this.options.indicatorClass; if (cls) this.element.addClass(cls); this.fireEvent('onRequest', [this.element, this.request, data, this.queryValue]); this.request.send({ 'data': data }); }, queryResponse: function () { var indicator = document.id(this.options.indicator); if (indicator) indicator.setStyle('display', 'none'); var cls = this.options.indicatorClass; if (cls) this.element.removeClass(cls); return this.fireEvent('onComplete', [this.element, this.request]); } }); Autocompleter.Request.JSON = new Class({ Extends: Autocompleter.Request, initialize: function (el, url, options) { this.parent(el, options); this.request = new Request.JSON(Object.merge({}, { 'url': url, 'link': 'cancel' }, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this)); }, queryResponse: function (response) { this.parent(); this.update(response); } }); Autocompleter.Request.HTML = new Class({ Extends: Autocompleter.Request, initialize: function (el, url, options) { this.parent(el, options); this.request = new Request.HTML(Object.merge({}, { 'url': url, 'link': 'cancel', 'update': this.choices }, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this)); }, queryResponse: function (tree, elements) { this.parent(); if (!elements || !elements.length) { this.hideChoices(); } else { this.choices.getChildren(this.options.choicesMatch).each(this.options.injectChoice || function (choice) { var value = choice.innerHTML; choice.inputValue = value; this.addChoiceEvents(choice.set('html', this.markQueryValue(value))); }, this); this.showChoices(); } } }); Autocompleter.Ajax = { Base: Autocompleter.Request, Json: Autocompleter.Request.JSON, Xhtml: Autocompleter.Request.HTML }; PKx>\) js/.htaccessnuW+A Order allow,deny Deny from all PKx>\6 js/index.htmlnuW+APKx>\y;C88 js/indexer.jsnuW+Avar FinderProgressBar = new Class({ Implements: [Events, Options], options: { container: document.body, boxID: 'progress-bar-box-id', percentageID: 'progress-bar-percentage-id', displayID: 'progress-bar-display-id', startPercentage: 0, displayText: false, speed: 10, step: 1, allowMore: false, onComplete: function () {}, onChange: function () {} }, initialize: function (options) { this.setOptions(options); this.options.container = document.id(this.options.container); this.createElements(); }, createElements: function () { var box = new Element('div', { id: this.options.boxID }); var perc = new Element('div', { id: this.options.percentageID, 'style': 'width:0px;' }); perc.inject(box); box.inject(this.options.container); if (this.options.displayText) { var text = new Element('div', { id: this.options.displayID }); text.inject(this.options.container); } this.set(this.options.startPercentage); }, calculate: function (percentage) { return (document.id(this.options.boxID).getStyle('width').replace('px', '') * (percentage / 100)).toInt(); }, animate: function (go) { var run = false; var self = this; if (!self.options.allowMore && go > 100) { go = 100; } self.to = go.toInt(); document.id(self.options.percentageID).set('morph', { duration: this.options.speed, link: 'cancel', onComplete: function () { self.fireEvent('change', [self.to]); if (go >= 100) { self.fireEvent('complete', [self.to]); } } }).morph({ width: self.calculate(go) }); if (self.options.displayText) { document.id(self.options.displayID).set('text', self.to + '%'); } }, set: function (to) { this.animate(to); }, step: function () { this.set(this.to + this.options.step); } }); var FinderIndexer = new Class({ totalItems: null, batchSize: null, offset: null, progress: null, optimized: false, path: 'index.php?option=com_finder&tmpl=component&format=json', initialize: function () { this.offset = 0; this.progress = 0; this.pb = new FinderProgressBar({ container: document.id('finder-progress-container'), startPercentage: 0, speed: 600, boxID: 'finder-progress-box', percentageID: 'finder-progress-perc', displayID: 'finder-progress-status', displayText: true }); this.path = this.path + '&' + document.id('finder-indexer-token').get('name') + '=1'; this.getRequest('indexer.start').send() }, getRequest: function (task) { return new Request.JSON({ url: this.path, method: 'get', data: 'task=' + task, onSuccess: this.handleResponse.bind(this), onFailure: this.handleFailure.bind(this) }); }, handleResponse: function (json, resp) { try { if (json === null) { throw resp; } if (json.error) { throw json; } if (json.start) this.totalItems = json.totalItems; this.offset += json.batchOffset; this.updateProgress(json.header, json.message); if (this.offset < this.totalItems) { this.getRequest('indexer.batch').send(); } else if (!this.optimized) { this.optimized = true; this.getRequest('indexer.optimize').send(); } } catch (error) { if (this.pb) document.id(this.pb.options.container).dispose(); try { if (json.error) { document.id('finder-progress-header').set('text', json.header).addClass('finder-error'); document.id('finder-progress-message').set('html', json.message).addClass('finder-error'); } } catch (ignore) { if (error == '') { error = Joomla.JText._('COM_FINDER_NO_ERROR_RETURNED'); } document.id('finder-progress-header').set('text', Joomla.JText._('COM_FINDER_AN_ERROR_HAS_OCCURRED')).addClass('finder-error'); document.id('finder-progress-message').set('html', error).addClass('finder-error'); } } return true; }, handleFailure: function (xhr) { json = (typeof xhr == 'object' && xhr.responseText) ? xhr.responseText : null; json = json ? JSON.decode(json, true) : null; if (this.pb) document.id(this.pb.options.container).dispose(); if (json) { json = json.responseText != null ? Json.evaluate(json.responseText, true) : json; } var header = json ? json.header : Joomla.JText._('COM_FINDER_AN_ERROR_HAS_OCCURRED'); var message = json ? json.message : Joomla.JText._('COM_FINDER_MESSAGE_RETURNED') + '
' + json document.id('finder-progress-header').set('text', header).addClass('finder-error'); document.id('finder-progress-message').set('html', message).addClass('finder-error'); }, updateProgress: function (header, message) { this.progress = (this.offset / this.totalItems) * 100; document.id('finder-progress-header').set('text', header); document.id('finder-progress-message').set('html', message); if (this.pb && this.progress < 100) { this.pb.set(this.progress); } else if (this.pb) { document.id(this.pb.options.container).dispose(); this.pb = false; } } }); window.addEvent('domready', function () { Indexer = new FinderIndexer(); if (typeof window.parent.SqueezeBox == 'object') { window.parent.SqueezeBox.addEvent('onClose', function () { window.parent.location.reload(true); }); } }); PKx>\WU js/finder.jsnuW+Awindow.addEvent('domready', function () { sm = document.id('system-message'); if (sm) { sm.addEvent('check', function () { open = 0; messages = this.getElements('li'); for (i = 0, n = messages.length; i < n; i++) { if (messages[i].getProperty('hidden') != 'hidden') { open++; } } if (open < 1) { this.remove(); } }); } function hideWarning(e) { new Json.Remote(this.getProperty('link') + '&format=json', { linkId: this.getProperty('id'), onComplete: function (response) { if (response.error == false) { document.id(this.options.linkId).fireEvent('hide'); document.id('system-message').fireEvent('check'); } else { alert(response.message); } } }).send(); } document.id('a.hide-warning').each(function (a) { a.setProperty('link', a.getProperty('href')); a.setProperty('href', 'javascript: void(0);'); a.addEvent('hide', function () { this.getParent().setProperty('hidden', 'hidden'); var mySlider = new Fx.Slide(this.getParent(), { duration: 300 }); mySlider.slideOut(); }); // TODO: bindWithEvent deprecated in MT 1.3 a.addEvent('click', hideWarning.bindWithEvent(a)); }); }); PKx>\mc$_DDcss/sliderfilter.cssnuW+A #finder-filter-window { width:100%; padding:0; margin:10px 0 10px; overflow:auto; } .checklist, #branch-selectors { border:1px solid #ccc; list-style: none; height:220px; overflow:auto; width:220px; float: left; margin:0; } #finder-filter-window dl { padding:0; margin:0; width:220px; } .checklist { border-left-width:0; } #filter_lists div { float: left; } .checklist dt, #branch-selectors dt { background-color:#F6F6F6; border-bottom:1px solid #ccc; padding-bottom:2px; width:100%; text-align: left; } .checklist, .checklist dd, #branch-selectors dd { margin:0; padding:0; width:100%; text-align: left; } .checklist label, #branch-selectors label { display:block; padding-left:25px; text-indent: -25px; } .checklist label:hover, #branch-selectors label:hover { background:#F6F6F6; color:#000; } PKx>\) css/.htaccessnuW+A Order allow,deny Deny from all PKx>\6css/index.htmlnuW+APKx>\jcss/selectfilter.cssnuW+A#finder-filter-window { width:100%; padding:0; margin:10px 0 10px; overflow:auto; } #finder-filter-select-list { clear: left; list-style: none; padding:0; margin:0; overflow:auto; } #finder-filter-select-list li, #finder-filter-select-list li.filter-branch { list-style: none; padding:5px 10px 5px 0; margin:0; float: left; width:49%; background: none; text-align: left; } #finder-filter-select-list li label { display:block; clear:right; } PKx>\ہ++css/indexer.cssnuW+A#finder-indexer-container { text-align: center; } #finder-progress-container { margin: 0 auto; text-align: center; width: 350px; } #finder-progress-box { background-color: #EEEEEE; border: 1px solid #CCCCCC; height: 20px; width: 350px; } #finder-progress-perc { background-color: #96B4E0; border: 1px solid #0B55C4; height: 20px; margin: -1px 0 0 -1px; } #finder-progress-status { font-size: 14px; font-weight: bold; padding: 3px 0 0 10px; } h1.finder-error { color: #FF0000; } p.finder-error { color: #FF0000; font-weight:bold; } PKx>\JbW css/dates.cssnuW+A#finder-filter-window { margin: 10px 0 10px; overflow: auto; padding: 0; width: 100%; } ul#finder-filter-select-dates { list-style: none; margin: 0; padding: 0; } ul#finder-filter-select-dates li.filter-date { background: none; float: left; list-style: none; margin: 0; padding: 5px 0; text-align: left; width: 49%; } ul#finder-filter-select-dates li.filter-date select.filter-date-operator { margin-right: 10px; } PKx>\iwWxxcss/finder.cssnuW+A#advanced-search { text-align:left; width:100%; padding:5px 0 15px; } #advanced-search-toggle { cursor:pointer; } #search-query-explained { padding:10px 0; } #search-query-explained span.term, #search-query-explained span.date, #search-query-explained span.when, #search-query-explained span.branch, #search-query-explained span.node, #search-query-explained span.op { font-weight:bold; } #search-query-explained span.op { text-transform:uppercase; } #search-results li.search-result .mime-pdf { padding-left:20px; background:url(../images/mime/pdf.png) no-repeat; } #search-results .search-pagination, #search-results .pagination, #search-results .search-pages-counter { clear:both; margin:0 auto; } #highlighter-start, #highlighter-end { display:none; height:0; opacity:0; } span.highlight { background-color:#FFFFCC; font-weight:bold; padding:1px 4px; } ul.autocompleter-choices { position:absolute; margin:0; padding:0; list-style:none; border:1px solid #EEEEEE; background-color:white; border-right-color:#DDDDDD; border-bottom-color:#DDDDDD; text-align:left; font-family:Verdana, Geneva, Arial, Helvetica, sans-serif; z-index:50; } ul.autocompleter-choices li { background:none; position:relative; padding:0.1em 1.5em 0.1em 1em; cursor:pointer; font-weight:normal; font-size:1em; } ul.autocompleter-choices li.autocompleter-selected { background-color:#444; color:#fff; } ul.autocompleter-choices span.autocompleter-queried { font-weight:bold; } ul.autocompleter-choices li.autocompleter-selected span.autocompleter-queried { color:#9FCFFF; } ul#finder-filter-select-list { top: 4em !important; } PK>\)controllers/.htaccessnuW+A Order allow,deny Deny from all PK>\6controllers/index.htmlnuW+APK>\Mcontrollers/filters.phpnuW+A true)) { $model = parent::getModel($name, $prefix, $config); return $model; } } PK>\YZ$$controllers/indexer.json.phpnuW+Aget('enable_logging', '0')) { if ($log == null) { $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'indexer.php'; $log = JLog::addLogger($options); } } // Log the start JLog::add('Starting the indexer', JLog::INFO); // We don't want this form to be cached. header('Pragma: no-cache'); header('Cache-Control: no-cache'); header('Expires: -1'); // Check for a valid token. If invalid, send a 403 with the error message. JSession::checkToken('request') or $this->sendResponse(new Exception(JText::_('JINVALID_TOKEN'), 403)); // Put in a buffer to silence noise. ob_start(); // Reset the indexer state. FinderIndexer::resetState(); // Import the finder plugins. JPluginHelper::importPlugin('finder'); // Add the indexer language to JS JText::script('COM_FINDER_AN_ERROR_HAS_OCCURRED'); JText::script('COM_FINDER_NO_ERROR_RETURNED'); // Start the indexer. try { // Trigger the onStartIndex event. JDispatcher::getInstance()->trigger('onStartIndex'); // Get the indexer state. $state = FinderIndexer::getState(); $state->start = 1; // Send the response. $this->sendResponse($state); } // Catch an exception and return the response. catch (Exception $e) { $this->sendResponse($e); } } /** * Method to run the next batch of content through the indexer. * * @return void * * @since 2.5 */ public function batch() { static $log; $params = JComponentHelper::getParams('com_finder'); if ($params->get('enable_logging', '0')) { if ($log == null) { $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'indexer.php'; $log = JLog::addLogger($options); } } // Log the start JLog::add('Starting the indexer batch process', JLog::INFO); // We don't want this form to be cached. header('Pragma: no-cache'); header('Cache-Control: no-cache'); header('Expires: -1'); // Check for a valid token. If invalid, send a 403 with the error message. JSession::checkToken('request') or $this->sendResponse(new Exception(JText::_('JINVALID_TOKEN'), 403)); // Put in a buffer to silence noise. ob_start(); // Remove the script time limit. @set_time_limit(0); // Get the indexer state. $state = FinderIndexer::getState(); // Reset the batch offset. $state->batchOffset = 0; // Update the indexer state. FinderIndexer::setState($state); // Import the finder plugins. JPluginHelper::importPlugin('finder'); /* * We are going to swap out the raw document object with an HTML document * in order to work around some plugins that don't do proper environment * checks before trying to use HTML document functions. */ $raw = clone(JFactory::getDocument()); $lang = JFactory::getLanguage(); // Get the document properties. $attributes = array ( 'charset' => 'utf-8', 'lineend' => 'unix', 'tab' => ' ', 'language' => $lang->getTag(), 'direction' => $lang->isRTL() ? 'rtl' : 'ltr' ); // Get the HTML document. $html = JDocument::getInstance('html', $attributes); $doc = JFactory::getDocument(); // Swap the documents. $doc = $html; // Get the admin application. $admin = clone(JFactory::getApplication()); // Get the site app. include_once JPATH_SITE . '/includes/application.php'; $site = JApplication::getInstance('site'); // Swap the app. $app = JFactory::getApplication(); $app = $site; // Start the indexer. try { // Trigger the onBeforeIndex event. JDispatcher::getInstance()->trigger('onBeforeIndex'); // Trigger the onBuildIndex event. JDispatcher::getInstance()->trigger('onBuildIndex'); // Get the indexer state. $state = FinderIndexer::getState(); $state->start = 0; $state->complete = 0; // Swap the documents back. $doc = $raw; // Swap the applications back. $app = $admin; // Send the response. $this->sendResponse($state); } // Catch an exception and return the response. catch (Exception $e) { // Swap the documents back. $doc = $raw; // Send the response. $this->sendResponse($e); } } /** * Method to optimize the index and perform any necessary cleanup. * * @return void * * @since 2.5 */ public function optimize() { // We don't want this form to be cached. header('Pragma: no-cache'); header('Cache-Control: no-cache'); header('Expires: -1'); // Check for a valid token. If invalid, send a 403 with the error message. JSession::checkToken('request') or $this->sendResponse(new Exception(JText::_('JINVALID_TOKEN'), 403)); // Put in a buffer to silence noise. ob_start(); // Import the finder plugins. JPluginHelper::importPlugin('finder'); try { // Optimize the index. FinderIndexer::optimize(); // Get the indexer state. $state = FinderIndexer::getState(); $state->start = 0; $state->complete = 1; // Send the response. $this->sendResponse($state); } // Catch an exception and return the response. catch (Exception $e) { $this->sendResponse($e); } } /** * Method to handle a send a JSON response. The body parameter * can be a Exception object for when an error has occurred or * a JObject for a good response. * * @param mixed $data JObject on success, Exception on error. [optional] * * @return void * * @since 2.5 */ public static function sendResponse($data = null) { static $log; $params = JComponentHelper::getParams('com_finder'); if ($params->get('enable_logging', '0')) { if ($log == null) { $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'indexer.php'; $log = JLog::addLogger($options); } } $backtrace = null; // Send the assigned error code if we are catching an exception. if ($data instanceof Exception) { JLog::add($data->getMessage(), JLog::ERROR); JResponse::setHeader('status', $data->getCode()); JResponse::sendHeaders(); } // Create the response object. $response = new FinderIndexerResponse($data); // Add the buffer. $response->buffer = JDEBUG ? ob_get_contents() : ob_end_clean(); // Send the JSON response. echo json_encode($response); // Close the application. JFactory::getApplication()->close(); } } /** * Finder Indexer JSON Response Class * * @package Joomla.Administrator * @subpackage com_finder * @since 2.5 */ class FinderIndexerResponse { /** * Class Constructor * * @param mixed $state The processing state for the indexer * * @since 2.5 */ public function __construct($state) { static $log; $params = JComponentHelper::getParams('com_finder'); if ($params->get('enable_logging', '0')) { if ($log == null) { $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'indexer.php'; $log = JLog::addLogger($options); } } // The old token is invalid so send a new one. $this->token = JFactory::getSession()->getFormToken(); // Check if we are dealing with an error. if ($state instanceof Exception) { // Log the error JLog::add($state->getMessage(), JLog::ERROR); // Prepare the error response. $this->error = true; $this->header = JText::_('COM_FINDER_INDEXER_HEADER_ERROR'); $this->message = $state->getMessage(); } else { // Prepare the response data. $this->batchSize = (int) $state->batchSize; $this->batchOffset = (int) $state->batchOffset; $this->totalItems = (int) $state->totalItems; $this->startTime = $state->startTime; $this->endTime = JFactory::getDate()->toSQL(); $this->start = !empty($state->start) ? (int) $state->start : 0; $this->complete = !empty($state->complete) ? (int) $state->complete : 0; // Set the appropriate messages. if ($this->totalItems <= 0 && $this->complete) { $this->header = JText::_('COM_FINDER_INDEXER_HEADER_COMPLETE'); $this->message = JText::_('COM_FINDER_INDEXER_MESSAGE_COMPLETE'); } elseif ($this->totalItems <= 0) { $this->header = JText::_('COM_FINDER_INDEXER_HEADER_OPTIMIZE'); $this->message = JText::_('COM_FINDER_INDEXER_MESSAGE_OPTIMIZE'); } else { $this->header = JText::_('COM_FINDER_INDEXER_HEADER_RUNNING'); $this->message = JText::_('COM_FINDER_INDEXER_MESSAGE_RUNNING'); } } } } // Register the error handler. JError::setErrorHandling(E_ALL, 'callback', array('FinderControllerIndexer', 'sendResponse')); PK>\h̀controllers/filter.phpnuW+Ainput; $lang = JFactory::getLanguage(); $model = $this->getModel(); $table = $model->getTable(); $data = $input->post->get('jform', array(), 'array'); $checkin = property_exists($table, 'checked_out'); $context = "$this->option.edit.$this->context"; $task = $this->getTask(); // Determine the name of the primary key for the data. if (empty($key)) { $key = $table->getKeyName(); } // To avoid data collisions the urlVar may be different from the primary key. if (empty($urlVar)) { $urlVar = $key; } $recordId = $input->get($urlVar, '', 'int'); $session = JFactory::getSession(); $registry = $session->get('registry'); if (!$this->checkEditId($context, $recordId)) { // Somehow the person just went to the form and tried to save it. We don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $recordId)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); return false; } // Populate the row id from the session. $data[$key] = $recordId; // The save2copy task needs to be handled slightly differently. if ($task == 'save2copy') { // Check-in the original row. if ($checkin && $model->checkin($data[$key]) === false) { // Check-in failed. Go back to the item and display a notice. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError())); $this->setMessage($this->getError(), 'error'); $this->setRedirect('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $urlVar)); return false; } // Reset the ID and then treat the request as for Apply. $data[$key] = 0; $task = 'apply'; } // Access check. if (!$this->allowSave($data, $key)) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); return false; } // Validate the posted data. // Sometimes the form needs some posted data, such as for plugins and modules. $form = $model->getForm($data, false); if (!$form) { $app->enqueueMessage($model->getError(), 'error'); return false; } // Test whether the data is valid. $validData = $model->validate($form, $data); // Check for validation errors. if ($validData === false) { // Get the validation messages. $errors = $model->getErrors(); // Push up to three validation messages out to the user. for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) { if (($errors[$i]) instanceof Exception) { $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); } else { $app->enqueueMessage($errors[$i], 'warning'); } } // Save the data in the session. $app->setUserState($context . '.data', $data); // Redirect back to the edit screen. $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key), false)); return false; } // Get and sanitize the filter data. $validData['data'] = $input->post->get('t', array(), 'array'); $validData['data'] = array_unique($validData['data']); JArrayHelper::toInteger($validData['data']); // Remove any values of zero. if (array_search(0, $validData['data'], true)) { unset($validData['data'][array_search(0, $validData['data'], true)]); } // Attempt to save the data. if (!$model->save($validData)) { // Save the data in the session. $app->setUserState($context . '.data', $validData); // Redirect back to the edit screen. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError())); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key), false)); return false; } // Save succeeded, so check-in the record. if ($checkin && $model->checkin($validData[$key]) === false) { // Save the data in the session. $app->setUserState($context . '.data', $validData); // Check-in failed, so go back to the record and display a notice. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError())); $this->setMessage($this->getError(), 'error'); $this->setRedirect('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key)); return false; } $this->setMessage( JText::_( ($lang->hasKey($this->text_prefix . ($recordId == 0 && $app->isSite() ? '_SUBMIT' : '') . '_SAVE_SUCCESS') ? $this->text_prefix : 'JLIB_APPLICATION') . ($recordId == 0 && $app->isSite() ? '_SUBMIT' : '') . '_SAVE_SUCCESS' ) ); // Redirect the user and adjust session state based on the chosen task. switch ($task) { case 'apply': // Set the record data in the session. $recordId = $model->getState($this->context . '.id'); $this->holdEditId($context, $recordId); $app->setUserState($context . '.data', null); $model->checkout($recordId); // Redirect back to the edit screen. $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key), false)); break; case 'save2new': // Clear the record id and data from the session. $this->releaseEditId($context, $recordId); $app->setUserState($context . '.data', null); // Redirect back to the edit screen. $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(null, $key), false)); break; default: // Clear the record id and data from the session. $this->releaseEditId($context, $recordId); $app->setUserState($context . '.data', null); // Redirect to the list screen. $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); break; } // Invoke the postSave method to allow for the child class to access the model. $this->postSaveHook($model, $validData); return true; } } PK>\G;controllers/maps.phpnuW+A true)) { $model = parent::getModel($name, $prefix, $config); return $model; } } PK>\econtrollers/index.phpnuW+A true)) { $model = parent::getModel($name, $prefix, $config); return $model; } /** * Method to purge all indexed links from the database. * * @return boolean True on success. * * @since 2.5 */ public function purge() { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Remove the script time limit. @set_time_limit(0); // Initialize variables. $model = $this->getModel('Index', 'FinderModel'); // Attempt to purge the index. $return = $model->purge(); if (!$return) { $message = JText::_('COM_FINDER_INDEX_PURGE_FAILED', $model->getError()); $this->setRedirect('index.php?option=com_finder&view=index', $message); return false; } else { $message = JText::_('COM_FINDER_INDEX_PURGE_SUCCESS'); $this->setRedirect('index.php?option=com_finder&view=index', $message); return true; } } } PK>\BTZZtables/filter.phpnuW+AloadArray($array['params']); $array['params'] = (string) $registry; } return parent::bind($array, $ignore); } /** * Method to perform sanity checks on the JTable instance properties to ensure * they are safe to store in the database. Child classes should override this * method to make sure the data they are storing in the database is safe and * as expected before storage. * * @return boolean True if the instance is sane and able to be stored in the database. * * @since 2.5 */ public function check() { if (trim($this->alias) == '') { $this->alias = $this->title; } $this->alias = JApplication::stringURLSafe($this->alias); if (trim(str_replace('-', '', $this->alias)) == '') { $this->alias = JFactory::getDate()->format('Y-m-d-H-i-s'); } // Check the end date is not earlier than start up. if ($this->d2 > $this->_db->getNullDate() && $this->d2 < $this->d1) { // Swap the dates. $temp = $this->d1; $this->d1 = $this->d2; $this->d2 = $temp; } return true; } /** * Method to set the publishing state for a row or list of rows in the database * table. The method respects checked out rows by other users and will attempt * to checkin rows that it can after adjustments are made. * * @param mixed $pks An array of primary key values to update. If not * set the instance property value is used. [optional] * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published] [optional] * @param integer $userId The user id of the user performing the operation. [optional] * * @return boolean True on success. * * @since 2.5 */ public function publish($pks = null, $state = 1, $userId = 0) { // Initialise variables. $k = $this->_tbl_key; // Sanitize input. JArrayHelper::toInteger($pks); $userId = (int) $userId; $state = (int) $state; // If there are no primary keys set check to see if the instance key is set. if (empty($pks)) { if ($this->$k) { $pks = array($this->$k); } // Nothing to set publishing state on, return false. else { $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); return false; } } // Build the WHERE clause for the primary keys. $where = $k . '=' . implode(' OR ' . $k . '=', $pks); // Determine if there is checkin support for the table. if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time')) { $checkin = ''; } else { $checkin = ' AND (checked_out = 0 OR checked_out = ' . (int) $userId . ')'; } // Update the publishing state for rows with the given primary keys. $query = $this->_db->getQuery(true); $query->update($this->_db->quoteName($this->_tbl)); $query->set($this->_db->quoteName('state') . ' = ' . (int) $state); $query->where($where); $this->_db->setQuery($query . $checkin); $this->_db->query(); // Check for a database error. if ($this->_db->getErrorNum()) { $this->setError($this->_db->getErrorMsg()); return false; } // If checkin is supported and all rows were adjusted, check them in. if ($checkin && (count($pks) == $this->_db->getAffectedRows())) { // Checkin the rows. foreach ($pks as $pk) { $this->checkin($pk); } } // If the JTable instance value is in the list of primary keys that were set, set the instance. if (in_array($this->$k, $pks)) { $this->state = $state; } $this->setError(''); return true; } /** * Method to store a row in the database from the JTable instance properties. * If a primary key value is set the row with that primary key value will be * updated with the instance property values. If no primary key value is set * a new row will be inserted into the database with the properties from the * JTable instance. * * @param boolean $updateNulls True to update fields even if they are null. [optional] * * @return boolean True on success. * * @since 2.5 */ public function store($updateNulls = false) { $date = JFactory::getDate(); $user = JFactory::getUser(); if ($this->filter_id) { // Existing item $this->modified = $date->toMySQL(); $this->modified_by = $user->get('id'); } else { // New item. A filter's created field can be set by the user, // so we don't touch it if it is set. if (!intval($this->created)) { $this->created = $date->toMySQL(); } if (empty($this->created_by)) { $this->created_by = $user->get('id'); } } if (is_array($this->data)) { $this->map_count = count($this->data); $this->data = implode(',', $this->data); } else { $this->map_count = 0; $this->data = implode(',', array()); } // Verify that the alias is unique $table = JTable::getInstance('Filter', 'FinderTable'); if ($table->load(array('alias' => $this->alias)) && ($table->filter_id != $this->filter_id || $this->filter_id == 0)) { $this->setError(JText::_('JLIB_DATABASE_ERROR_ARTICLE_UNIQUE_ALIAS')); return false; } return parent::store($updateNulls); } } PK>\] 8&tables/link.phpnuW+A\ H H tables/map.phpnuW+A_tbl_key; // Sanitize input. JArrayHelper::toInteger($pks); $userId = (int) $userId; $state = (int) $state; // If there are no primary keys set check to see if the instance key is set. if (empty($pks)) { if ($this->$k) { $pks = array($this->$k); } // Nothing to set publishing state on, return false. else { $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); return false; } } // Build the WHERE clause for the primary keys. $where = $k . '=' . implode(' OR ' . $k . '=', $pks); // Update the publishing state for rows with the given primary keys. $query = $this->_db->getQuery(true); $query->update($this->_db->quoteName($this->_tbl)); $query->set($this->_db->quoteName('state') . ' = ' . (int) $state); $query->where($where); $this->_db->setQuery($query); $this->_db->query(); // Check for a database error. if ($this->_db->getErrorNum()) { $this->setError($this->_db->getErrorMsg()); return false; } // If the JTable instance value is in the list of primary keys that were set, set the instance. if (in_array($this->$k, $pks)) { $this->state = $state; } $this->setError(''); return true; } } PK>\)tables/.htaccessnuW+A Order allow,deny Deny from all PK>\6tables/index.htmlnuW+APK>\6views/index.htmlnuW+APK>\Vviews/filter/index.htmlnuW+A PK>\)views/filter/tmpl/.htaccessnuW+A Order allow,deny Deny from all PK>\y views/filter/tmpl/edit.phpnuW+A
  • form->getLabel('title'); ?>
    form->getInput('title'); ?>
  • form->getLabel('alias'); ?>
    form->getInput('alias'); ?>
  • form->getLabel('state'); ?>
    form->getInput('state'); ?>
  • form->getLabel('map_count'); ?>
    form->getInput('map_count'); ?>
item->filter_id, array('useCookie' => 1)); ?>
    form->getGroup('params') as $field): ?>
  • hidden): ?> label; ?> input; ?>
form->getGroup('details'); ?>
  • form->getLabel('created_by'); ?> form->getInput('created_by'); ?>
  • form->getLabel('created_by_alias'); ?> form->getInput('created_by_alias'); ?>
  • form->getLabel('created'); ?> form->getInput('created'); ?>
  • item->modified_by) : ?>
  • form->getLabel('modified_by'); ?> form->getInput('modified_by'); ?>
  • form->getLabel('modified'); ?> form->getInput('modified'); ?>
$this->filter->data)); ?>
PK>\Vviews/filter/tmpl/index.htmlnuW+A PK>\ 0+ + views/filter/view.html.phpnuW+Afilter = $this->get('Filter'); $this->item = $this->get('Item'); $this->form = $this->get('Form'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); JHtml::addIncludePath(JPATH_SITE . '/components/com_finder/helpers/html'); // Configure the toolbar. $this->addToolbar(); parent::display($tpl); } /** * Method to configure the toolbar for this view. * * @return void * * @since 2.5 */ protected function addToolbar() { JFactory::getApplication()->input->set('hidemainmenu', true); $user = JFactory::getUser(); $userId = $user->get('id'); $isNew = ($this->item->filter_id == 0); $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); $canDo = FinderHelper::getActions(); // Configure the toolbar. JToolBarHelper::title(JText::_('COM_FINDER_FILTER_EDIT_TOOLBAR_TITLE'), 'finder'); // Set the actions for new and existing records. if ($isNew) { // For new records, check the create permission. if ($canDo->get('core.create')) { JToolBarHelper::apply('filter.apply'); JToolBarHelper::save('filter.save'); JToolBarHelper::save2new('filter.save2new'); } JToolBarHelper::cancel('filter.cancel'); } else { // Since it's an existing record, check the edit permission. if ($canDo->get('core.edit')) { JToolBarHelper::apply('filter.apply'); JToolBarHelper::save('filter.save'); // We can save this record, but check the create permission to see if we can return to make a new one. if ($canDo->get('core.create')) { JToolBarHelper::save2new('filter.save2new'); } } // If an existing item, can save as a copy if ($canDo->get('core.create')) { JToolBarHelper::save2copy('filter.save2copy'); } JToolBarHelper::cancel('filter.cancel', 'JTOOLBAR_CLOSE'); } JToolBarHelper::divider(); JToolBarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT'); } } PK>\)views/filter/.htaccessnuW+A Order allow,deny Deny from all PK>\6 views/statistics/tmpl/index.htmlnuW+APK>\g/!views/statistics/tmpl/default.phpnuW+A

data->term_count), number_format($this->data->link_count), number_format($this->data->taxonomy_node_count), number_format($this->data->taxonomy_branch_count)); ?>

data->type_list as $type) :?>
type_title;?> link_count);?>
data->link_count); ?>
PK>\)views/statistics/tmpl/.htaccessnuW+A Order allow,deny Deny from all PK>\)views/statistics/.htaccessnuW+A Order allow,deny Deny from all PK>\6views/statistics/index.htmlnuW+APK>\ʫviews/statistics/view.html.phpnuW+Adata = $this->get('Data'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } parent::display($tpl); } } PK>\Vviews/indexer/index.htmlnuW+A PK>\ʩ]$!!views/indexer/tmpl/default.phpnuW+A


PK>\)views/indexer/tmpl/.htaccessnuW+A Order allow,deny Deny from all PK>\Vviews/indexer/tmpl/index.htmlnuW+A PK>\)6 88views/indexer/view.html.phpnuW+A\)views/indexer/.htaccessnuW+A Order allow,deny Deny from all PK>\U/  views/filters/view.html.phpnuW+Aitems = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->total = $this->get('Total'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); // Configure the toolbar. $this->addToolbar(); parent::display($tpl); } /** * Method to configure the toolbar for this view. * * @return void * * @since 2.5 */ protected function addToolbar() { $canDo = FinderHelper::getActions(); JToolBarHelper::title(JText::_('COM_FINDER_FILTERS_TOOLBAR_TITLE'), 'finder'); $toolbar = JToolBar::getInstance('toolbar'); if ($canDo->get('core.create')) { JToolBarHelper::addNew('filter.add'); JToolBarHelper::editList('filter.edit'); JToolBarHelper::divider(); } if ($canDo->get('core.edit.state')) { JToolBarHelper::publishList('filters.publish'); JToolBarHelper::unpublishList('filters.unpublish'); JToolBarHelper::divider(); } if ($canDo->get('core.delete')) { JToolBarHelper::deleteList('', 'filters.delete'); JToolBarHelper::divider(); } if ($canDo->get('core.admin')) { JToolBarHelper::preferences('com_finder'); } JToolBarHelper::divider(); $toolbar->appendButton('Popup', 'stats', 'COM_FINDER_STATISTICS', 'index.php?option=com_finder&view=statistics&tmpl=component', 550, 500); JToolBarHelper::divider(); JToolBarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS'); } } PK>\Vviews/filters/tmpl/index.htmlnuW+A PK>\N4yfviews/filters/tmpl/default.phpnuW+Aget('id'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); ?>
items) == 0): ?> items as $i => $item): $canCreate = $user->authorise('core.create', 'com_finder'); $canEdit = $user->authorise('core.edit', 'com_finder'); $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; $canChange = $user->authorise('core.edit.state', 'com_finder') && $canCheckin; ?>
total == 0): echo JText::_('COM_FINDER_NO_FILTERS'); ?>
filter_id); ?> checked_out) { echo JHtml::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'filters.', $canCheckin); } ?> escape($item->title); ?> escape($item->title); } ?> state, $i, 'filters.', $canChange); ?> created_by_alias ? $item->created_by_alias : $item->user_name; ?> created, JText::_('DATE_FORMAT_LC4')); ?> map_count; ?> filter_id; ?>
pagination->getListFooter(); ?>
PK>\)views/filters/tmpl/.htaccessnuW+A Order allow,deny Deny from all PK>\Vviews/filters/index.htmlnuW+A PK>\)views/filters/.htaccessnuW+A Order allow,deny Deny from all PK>\5*= views/index/view.html.phpnuW+Aitems = $this->get('Items'); $this->total = $this->get('Total'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); $this->pluginState = $this->get('pluginState'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); // Configure the toolbar. $this->addToolbar(); parent::display($tpl); } /** * Method to configure the toolbar for this view. * * @return void * * @since 2.5 */ protected function addToolbar() { $canDo = FinderHelper::getActions(); JToolBarHelper::title(JText::_('COM_FINDER_INDEX_TOOLBAR_TITLE'), 'finder'); $toolbar = JToolBar::getInstance('toolbar'); $toolbar->appendButton('Popup', 'archive', 'COM_FINDER_INDEX', 'index.php?option=com_finder&view=indexer&tmpl=component', 500, 210); JToolBarHelper::divider(); if ($canDo->get('core.edit.state')) { JToolBarHelper::publishList('index.publish'); JToolBarHelper::unpublishList('index.unpublish'); JToolBarHelper::divider(); } if ($canDo->get('core.delete')) { JToolBarHelper::deleteList('', 'index.delete'); JToolBarHelper::divider(); } if ($canDo->get('core.edit.state')) { JToolBarHelper::trash('index.purge', 'COM_FINDER_INDEX_TOOLBAR_PURGE', false); JToolBarHelper::divider(); } if ($canDo->get('core.admin')) { JToolBarHelper::preferences('com_finder'); } JToolBarHelper::divider(); $toolbar->appendButton('Popup', 'stats', 'COM_FINDER_STATISTICS', 'index.php?option=com_finder&view=statistics&tmpl=component', 550, 500); JToolBarHelper::divider(); JToolBarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT'); } } PK>\zU}views/index/tmpl/default.phpnuW+Aescape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $lang = JFactory::getLanguage(); JText::script('COM_FINDER_INDEX_CONFIRM_PURGE_PROMPT'); JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); ?>
pluginState['plg_content_finder']->enabled) : ?> items) == 0): ?> authorise('core.manage', 'com_finder'); ?> items as $i => $item): ?>
total == 0) { echo JText::_('COM_FINDER_INDEX_NO_DATA') . ' ' . JText::_('COM_FINDER_INDEX_TIP'); } else { echo JText::_('COM_FINDER_INDEX_NO_CONTENT'); } ?>
link_id); ?> publish_start_date) or intval($item->publish_end_date) or intval($item->start_date) or intval($item->end_date)) : ?> escape($item->title); ?> published, $i, 'index.', $canChange, 'cb'); ?> t_title); echo $lang->hasKey($key) ? JText::_($key) : $item->t_title; ?> url) > 80) { echo substr($item->url, 0, 70) . '...'; } else { echo $item->url; } ?> indexdate, JText::_('DATE_FORMAT_LC4')); ?>
pagination->getListFooter(); ?>
PK>\)views/index/tmpl/.htaccessnuW+A Order allow,deny Deny from all PK>\Vviews/index/tmpl/index.htmlnuW+A PK>\)views/index/.htaccessnuW+A Order allow,deny Deny from all PK>\Vviews/index/index.htmlnuW+A PK>\)views/.htaccessnuW+A Order allow,deny Deny from all PK>\Vviews/maps/index.htmlnuW+A PK>\Vviews/maps/tmpl/index.htmlnuW+A PK>\)views/maps/tmpl/.htaccessnuW+A Order allow,deny Deny from all PK>\U{l}}views/maps/tmpl/default.phpnuW+Aescape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $lang = JFactory::getLanguage(); JText::script('COM_FINDER_MAPS_CONFIRM_DELETE_PROMPT'); ?>
items) == 0): ?> state->get('filter.branch') != 1) : ?> authorise('core.manage', 'com_finder'); ?> items as $i => $item): ?>
id); ?> title); $title = $lang->hasKey($key) ? JText::_($key) : $item->title; ?> state->get('filter.branch') == 1 && $item->num_children) : ?> escape($title); ?> escape(($title == '*') ? JText::_('JALL_LANGUAGE') : $title); ?> num_children > 0) : ?> (num_children; ?>) num_nodes > 0) : ?> (num_nodes; ?>) escape(trim($title, '**')) == 'Language' && JLanguageMultilang::isEnabled()) : ?> state, $i, 'maps.', $canChange, 'cb'); ?>
pagination->getListFooter(); ?>
PK>\ݴi views/maps/view.html.phpnuW+Aitems = $this->get('Items'); $this->total = $this->get('Total'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } // Prepare the view. $this->addToolbar(); JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); parent::display($tpl); } /** * Method to configure the toolbar for this view. * * @return void * * @since 2.5 */ protected function addToolbar() { // For whatever reason, the helper isn't being found include_once JPATH_COMPONENT . '/helpers/finder.php'; $canDo = FinderHelper::getActions(); JToolBarHelper::title(JText::_('COM_FINDER_MAPS_TOOLBAR_TITLE'), 'finder'); $toolbar = JToolBar::getInstance('toolbar'); if ($canDo->get('core.edit.state')) { JToolBarHelper::publishList('maps.publish'); JToolBarHelper::unpublishList('maps.unpublish'); JToolBarHelper::divider(); } if ($canDo->get('core.delete')) { JToolBarHelper::deleteList('', 'maps.delete'); JToolBarHelper::divider(); } if ($canDo->get('core.admin')) { JToolBarHelper::preferences('com_finder'); } JToolBarHelper::divider(); $toolbar->appendButton('Popup', 'stats', 'COM_FINDER_STATISTICS', 'index.php?option=com_finder&view=statistics&tmpl=component', 550, 500); JToolBarHelper::divider(); JToolBarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_CONTENT_MAPS'); } } PK>\)views/maps/.htaccessnuW+A Order allow,deny Deny from all PK>\9`Omodels/statistics.phpnuW+AgetDbo(); $query = $db->getQuery(true); $data = new JObject; $query->select('COUNT(term_id)'); $query->from($db->quoteName('#__finder_terms')); $db->setQuery($query); $data->term_count = $db->loadResult(); $query->clear(); $query->select('COUNT(link_id)'); $query->from($db->quoteName('#__finder_links')); $db->setQuery($query); $data->link_count = $db->loadResult(); $query->clear(); $query->select('COUNT(id)'); $query->from($db->quoteName('#__finder_taxonomy')); $query->where($db->quoteName('parent_id') . ' = 1'); $db->setQuery($query); $data->taxonomy_branch_count = $db->loadResult(); $query->clear(); $query->select('COUNT(id)'); $query->from($db->quoteName('#__finder_taxonomy')); $query->where($db->quoteName('parent_id') . ' > 1'); $db->setQuery($query); $data->taxonomy_node_count = $db->loadResult(); $query->clear(); $query->select('t.title AS type_title, COUNT(a.link_id) AS link_count'); $query->from($db->quoteName('#__finder_links') . ' AS a'); $query->join('INNER', $db->quoteName('#__finder_types') . ' AS t ON t.id = a.type_id'); $query->group('a.type_id, t.title'); $query->order($db->quoteName('type_title'), 'ASC'); $db->setQuery($query); $data->type_list = $db->loadObjectList(); return $data; } } PK>\Sn models/forms/filter.xmlnuW+A
PK>\)models/forms/.htaccessnuW+A Order allow,deny Deny from all PK>\6models/forms/index.htmlnuW+APK>\JFaamodels/fields/searchfilter.phpnuW+AgetQuery(true); $query->select('f.' . $db->quoteName('title') . ' AS text, f.' . $db->quoteName('filter_id') . ' AS value'); $query->from($db->quoteName('#__finder_filters') . ' AS f'); $query->where('f.' . $db->quoteName('state') . ' = 1'); $query->order('f.title ASC'); $db->setQuery($query); $options = $db->loadObjectList(); array_unshift($options, JHtml::_('select.option', '', JText::_('COM_FINDER_SELECT_SEARCH_FILTER'), 'value', 'text')); return $options; } } PK>\6models/fields/index.htmlnuW+APK>\1 models/fields/directories.phpnuW+AgetCfg('log_path'), JFactory::getApplication()->getCfg('tmp_path') ); // Get the base directories. $dirs = JFolder::folders(JPATH_SITE, '.', false, true); // Iterate through the base directories and find the subdirectories. foreach ($dirs as $dir) { // Check if the directory should be excluded. if (in_array($dir, $exclude)) { continue; } // Get the child directories. $return = JFolder::folders($dir, '.', true, true); // Merge the directories. if (is_array($return)) { $values[] = $dir; $values = array_merge($values, $return); } } // Convert the values to options. for ($i = 0, $c = count($values); $i < $c; $i++) { $options[] = JHtml::_('select.option', str_replace(JPATH_SITE . DS, '', $values[$i]), str_replace(JPATH_SITE . DS, '', $values[$i])); } // Add a null option. array_unshift($options, JHTML::_('select.option', '', '- ' . JText::_('JNONE') . ' -')); // Handle default values of value1|value2|value3 if (is_string($value) && strpos($value, '|') && preg_match('#(?\)models/fields/.htaccessnuW+A Order allow,deny Deny from all PK>\3}F F models/filter.phpnuW+AgetState('filter.id'); // Get a FinderTableFilter instance. $filter = $this->getTable(); // Attempt to load the row. $return = $filter->load($filter_id); // Check for a database error. if ($return === false && $filter->getError()) { $this->setError($filter->getError()); return false; } // Process the filter data. if (!empty($filter->data)) { $filter->data = explode(',', $filter->data); } elseif (empty($filter->data)) { $filter->data = array(); } // Check for a database error. if ($this->_db->getErrorNum()) { $this->setError($this->_db->getErrorMsg()); return false; } return $filter; } /** * Method to get the record form. * * @param array $data Data for the form. [optional] * @param boolean $loadData True if the form is to load its own data (default case), false if not. [optional] * * @return mixed A JForm object on success, false on failure * * @since 1.6 */ public function getForm($data = array(), $loadData = true) { // Get the form. $form = $this->loadForm('com_finder.filter', 'filter', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } return $form; } /** * Returns a JTable object, always creating it. * * @param string $type The table type to instantiate. [optional] * @param string $prefix A prefix for the table class name. [optional] * @param array $config Configuration array for model. [optional] * * @return JTable A database object * * @since 2.5 */ public function getTable($type = 'Filter', $prefix = 'FinderTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 2.5 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_finder.edit.filter.data', array()); if (empty($data)) { $data = $this->getItem(); } return $data; } } PK>\)models/.htaccessnuW+A Order allow,deny Deny from all PK>\dIj--models/index.phpnuW+Aauthorise('core.delete', $this->option); } /** * Method to test whether a record can be deleted. * * @param object $record A record object. * * @return boolean True if allowed to change the state of the record. Defaults to the permission for the component. * * @since 2.5 */ protected function canEditState($record) { $user = JFactory::getUser(); return $user->authorise('core.edit.state', $this->option); } /** * Method to delete one or more records. * * @param array &$pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * * @since 2.5 */ public function delete(&$pks) { // Initialise variables. $dispatcher = JDispatcher::getInstance(); $user = JFactory::getUser(); $pks = (array) $pks; $table = $this->getTable(); // Include the content and finder plugins for the on delete events. JPluginHelper::importPlugin('content'); JPluginHelper::importPlugin('finder'); // Iterate the items to delete each one. foreach ($pks as $i => $pk) { if ($table->load($pk)) { if ($this->canDelete($table)) { $context = $this->option . '.' . $this->name; // Trigger the onContentBeforeDelete event. $result = $dispatcher->trigger($this->event_before_delete, array($context, $table)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } if (!$table->delete($pk)) { $this->setError($table->getError()); return false; } // Trigger the onContentAfterDelete event. $dispatcher->trigger($this->event_after_delete, array($context, $table)); } else { // Prune items that you can't change. unset($pks[$i]); $error = $this->getError(); if ($error) { $this->setError($error); } else { $this->setError(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); } } } else { $this->setError($table->getError()); return false; } } // Clear the component's cache $this->cleanCache(); return true; } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery A JDatabaseQuery object * * @since 2.5 */ protected function getListQuery() { $db = $this->getDbo(); $query = $db->getQuery(true); $query->select('l.*'); $query->select('t.title AS t_title'); $query->from($db->quoteName('#__finder_links') . ' AS l'); $query->join('INNER', $db->quoteName('#__finder_types') . ' AS t ON t.id = l.type_id'); // Check the type filter. if ($this->getState('filter.type')) { $query->where($db->quoteName('l.type_id') . ' = ' . (int) $this->getState('filter.type')); } // Check for state filter. if (is_numeric($this->getState('filter.state'))) { $query->where($db->quoteName('l.published') . ' = ' . (int) $this->getState('filter.state')); } // Check the search phrase. if ($this->getState('filter.search') != '') { $search = $db->escape($this->getState('filter.search')); $query->where($db->quoteName('l.title') . ' LIKE "%' . $db->escape($search) . '%"' . ' OR ' . $db->quoteName('l.url') . ' LIKE "%' . $db->escape($search) . '%"' . ' OR ' . $db->quoteName('l.indexdate') . ' LIKE "%' . $db->escape($search) . '%"'); } // Handle the list ordering. $ordering = $this->getState('list.ordering'); $direction = $this->getState('list.direction'); if (!empty($ordering)) { $query->order($db->escape($ordering) . ' ' . $db->escape($direction)); } return $query; } /** * Method to get the state of the Smart Search plug-ins. * * @return array Array of relevant plug-ins and whether they are enabled or not. * * @since 2.5 */ public function getPluginState() { $db = $this->getDbo(); $query = $db->getQuery(true); $query->select('name, enabled'); $query->from($db->quoteName('#__extensions')); $query->where($db->quoteName('type') . ' = ' . $db->quote('plugin')); $query->where($db->quoteName('folder') . ' IN(' . $db->quote('system') . ',' . $db->quote('content') . ')'); $query->where($db->quoteName('element') . ' = ' . $db->quote('finder')); $db->setQuery($query); $db->query(); $plugins = $db->loadObjectList('name'); return $plugins; } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. [optional] * * @return string A store id. * * @since 2.5 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.state'); $id .= ':' . $this->getState('filter.type'); return parent::getStoreId($id); } /** * Returns a JTable object, always creating it. * * @param string $type The table type to instantiate. [optional] * @param string $prefix A prefix for the table class name. [optional] * @param array $config Configuration array for model. [optional] * * @return JTable A database object * * @since 2.5 */ public function getTable($type = 'Link', $prefix = 'FinderTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Method to purge the index, deleting all links. * * @return boolean True on success, false on failure. * * @since 2.5 */ public function purge() { $db = $this->getDbo(); // Truncate the links table. $db->truncateTable('#__finder_links'); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Truncate the links terms tables. for ($i = 0; $i <= 15; $i++) { // Get the mapping table suffix. $suffix = dechex($i); $db->truncateTable('#__finder_links_terms' . $suffix); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } } // Truncate the terms table. $db->truncateTable('#__finder_terms'); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Truncate the taxonomy map table. $db->truncateTable('#__finder_taxonomy_map'); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Delete all the taxonomy nodes except the root. $query = $db->getQuery(true); $query->delete(); $query->from($db->quoteName('#__finder_taxonomy')); $query->where($db->quoteName('id') . ' > 1'); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Truncate the tokens tables. $db->truncateTable('#__finder_tokens'); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Truncate the tokens aggregate table. $db->truncateTable('#__finder_tokens_aggregate'); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } return true; } /** * Method to auto-populate the model state. Calling getState in this method will result in recursion. * * @param string $ordering An optional ordering field. [optional] * @param string $direction An optional direction. [optional] * * @return void * * @since 2.5 */ protected function populateState($ordering = null, $direction = null) { // Load the filter state. $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string'); $this->setState('filter.state', $state); $type = $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string'); $this->setState('filter.type', $type); // Load the parameters. $params = JComponentHelper::getParams('com_finder'); $this->setState('params', $params); // List state information. parent::populateState('l.title', 'asc'); } /** * Method to change the published state of one or more records. * * @param array &$pks A list of the primary keys to change. * @param integer $value The value of the published state. [optional] * * @return boolean True on success. * * @since 2.5 */ public function publish(&$pks, $value = 1) { // Initialise variables. $dispatcher = JDispatcher::getInstance(); $user = JFactory::getUser(); $table = $this->getTable(); $pks = (array) $pks; // Include the content plugins for the change of state event. JPluginHelper::importPlugin('content'); // Access checks. foreach ($pks as $i => $pk) { $table->reset(); if ($table->load($pk)) { if (!$this->canEditState($table)) { // Prune items that you can't change. unset($pks[$i]); $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); return false; } } } // Attempt to change the state of the records. if (!$table->publish($pks, $value, $user->get('id'))) { $this->setError($table->getError()); return false; } $context = $this->option . '.' . $this->name; // Trigger the onContentChangeState event. $result = $dispatcher->trigger('onContentChangeState', array($context, $pks, $value)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } // Clear the component's cache $this->cleanCache(); return true; } } PK>\6models/index.htmlnuW+APK>\_models/indexer.phpnuW+A\K%%models/maps.phpnuW+Aauthorise('core.delete', $this->option); } /** * Method to test whether a record can be deleted. * * @param object $record A record object. * * @return boolean True if allowed to change the state of the record. Defaults to the permission for the component. * * @since 2.5 */ protected function canEditState($record) { $user = JFactory::getUser(); return $user->authorise('core.edit.state', $this->option); } /** * Method to delete one or more records. * * @param array &$pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * * @since 2.5 */ public function delete(&$pks) { // Initialise variables. $dispatcher = JDispatcher::getInstance(); $user = JFactory::getUser(); $pks = (array) $pks; $table = $this->getTable(); // Include the content plugins for the on delete events. JPluginHelper::importPlugin('content'); // Iterate the items to delete each one. foreach ($pks as $i => $pk) { if ($table->load($pk)) { if ($this->canDelete($table)) { $context = $this->option . '.' . $this->name; // Trigger the onContentBeforeDelete event. $result = $dispatcher->trigger('onContentBeforeDelete', array($context, $table)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } if (!$table->delete($pk)) { $this->setError($table->getError()); return false; } // Trigger the onContentAfterDelete event. $dispatcher->trigger('onContentAfterDelete', array($context, $table)); } else { // Prune items that you can't change. unset($pks[$i]); $error = $this->getError(); if ($error) { $this->setError($error); } else { $this->setError(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); } } } else { $this->setError($table->getError()); return false; } } // Clear the component's cache $this->cleanCache(); return true; } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery A JDatabaseQuery object * * @since 2.5 */ protected function getListQuery() { $db = $this->getDbo(); $query = $db->getQuery(true); // Select all fields from the table. $query->select('a.*'); $query->from($db->quoteName('#__finder_taxonomy') . ' AS a'); // Self-join to get children. $query->select('COUNT(b.id) AS num_children'); $query->join('LEFT', $db->quoteName('#__finder_taxonomy') . ' AS b ON b.parent_id=a.id'); // Join to get the map links $query->select('COUNT(c.node_id) AS num_nodes'); $query->join('LEFT', $db->quoteName('#__finder_taxonomy_map') . ' AS c ON c.node_id=a.id'); $query->group('a.id, a.parent_id, a.title, a.state, a.access, a.ordering'); // If the model is set to check item state, add to the query. if (is_numeric($this->getState('filter.state'))) { $query->where($db->quoteName('a.state') . ' = ' . (int) $this->getState('filter.state')); } // Filter the maps over the branch if set. $branch_id = $this->getState('filter.branch'); if (!empty($branch_id)) { $query->where($db->quoteName('a.parent_id') . ' = ' . (int) $branch_id); } // Filter the maps over the search string if set. $search = $this->getState('filter.search'); if (!empty($search)) { $query->where($db->quoteName('a.title') . ' LIKE ' . $db->quote('%' . $search . '%')); } // Handle the list ordering. $ordering = $this->getState('list.ordering'); $direction = $this->getState('list.direction'); if (!empty($ordering)) { $query->order($db->escape($ordering) . ' ' . $db->escape($direction)); } return $query; } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. [optional] * * @return string A store id. * * @since 2.5 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.state'); $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.branch'); return parent::getStoreId($id); } /** * Returns a JTable object, always creating it. * * @param string $type The table type to instantiate. [optional] * @param string $prefix A prefix for the table class name. [optional] * @param array $config Configuration array for model. [optional] * * @return JTable A database object * * @since 2.5 */ public function getTable($type = 'Map', $prefix = 'FinderTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Method to auto-populate the model state. Calling getState in this method will result in recursion. * * @param string $ordering An optional ordering field. [optional] * @param string $direction An optional direction. [optional] * * @return void * * @since 2.5 */ protected function populateState($ordering = null, $direction = null) { // Load the filter state. $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string'); $this->setState('filter.state', $state); $branch = $this->getUserStateFromRequest($this->context . '.filter.branch', 'filter_branch', '1', 'string'); $this->setState('filter.branch', $branch); // Load the parameters. $params = JComponentHelper::getParams('com_finder'); $this->setState('params', $params); // List state information. parent::populateState('a.title', 'asc'); } /** * Method to change the published state of one or more records. * * @param array &$pks A list of the primary keys to change. * @param integer $value The value of the published state. [optional] * * @return boolean True on success. * * @since 2.5 */ public function publish(&$pks, $value = 1) { // Initialise variables. $dispatcher = JDispatcher::getInstance(); $user = JFactory::getUser(); $table = $this->getTable(); $pks = (array) $pks; // Include the content plugins for the change of state event. JPluginHelper::importPlugin('content'); // Access checks. foreach ($pks as $i => $pk) { $table->reset(); if ($table->load($pk)) { if (!$this->canEditState($table)) { // Prune items that you can't change. unset($pks[$i]); $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); return false; } } } // Attempt to change the state of the records. if (!$table->publish($pks, $value, $user->get('id'))) { $this->setError($table->getError()); return false; } $context = $this->option . '.' . $this->name; // Trigger the onContentChangeState event. $result = $dispatcher->trigger('onContentChangeState', array($context, $pks, $value)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } // Clear the component's cache $this->cleanCache(); return true; } /** * Method to purge all maps from the taxonomy. * * @return boolean Returns true on success, false on failure. * * @since 2.5 */ public function purge() { $db = $this->getDbo(); $query = $db->getQuery(true); $query->delete(); $query->from($db->quoteName('#__finder_taxonomy')); $query->where($db->quoteName('parent_id') . ' > 1'); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { $this->setError($db->getErrorMsg()); return false; } $query->clear(); $query->delete(); $query->from($db->quoteName('#__finder_taxonomy_map')); $query->where('1'); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { $this->setError($db->getErrorMsg()); return false; } return true; } } PK>\@models/filters.phpnuW+AgetDbo(); $query = $db->getQuery(true); // Select all fields from the table. $query->select('a.*'); $query->from($db->quoteName('#__finder_filters') . ' AS a'); // Join over the users for the checked out user. $query->select('uc.name AS editor'); $query->join('LEFT', $db->quoteName('#__users') . ' AS uc ON uc.id=a.checked_out'); // Join over the users for the author. $query->select('ua.name AS user_name'); $query->join('LEFT', $db->quoteName('#__users') . ' AS ua ON ua.id = a.created_by'); // Check for a search filter. if ($this->getState('filter.search')) { $query->where('( ' . $db->quoteName('a.title') . ' LIKE \'%' . $db->escape($this->getState('filter.search')) . '%\' )'); } // If the model is set to check item state, add to the query. if (is_numeric($this->getState('filter.state'))) { $query->where($db->quoteName('a.state') . ' = ' . (int) $this->getState('filter.state')); } // Add the list ordering clause. $query->order($db->escape($this->getState('list.ordering') . ' ' . $db->escape($this->getState('list.direction')))); return $query; } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. [optional] * * @return string A store id. * * @since 2.5 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.state'); return parent::getStoreId($id); } /** * Method to auto-populate the model state. Calling getState in this method will result in recursion. * * @param string $ordering An optional ordering field. [optional] * @param string $direction An optional direction. [optional] * * @return void * * @since 2.5 */ protected function populateState($ordering = null, $direction = null) { // Load the filter state. $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string'); $this->setState('filter.state', $state); // Load the parameters. $params = JComponentHelper::getParams('com_finder'); $this->setState('params', $params); // List state information. parent::populateState('a.title', 'asc'); } } PK>\aY<<sql/install.mysql.sqlnuW+A-- -- Table structure for table `#__finder_filters` -- CREATE TABLE IF NOT EXISTS `#__finder_filters` ( `filter_id` int(10) unsigned NOT NULL auto_increment, `title` varchar(255) NOT NULL, `alias` varchar(255) NOT NULL, `state` tinyint(1) NOT NULL default '1', `created` datetime NOT NULL default '0000-00-00 00:00:00', `created_by` int(10) unsigned NOT NULL, `created_by_alias` varchar(255) NOT NULL, `modified` datetime NOT NULL default '0000-00-00 00:00:00', `modified_by` int(10) unsigned NOT NULL default '0', `checked_out` int(10) unsigned NOT NULL default '0', `checked_out_time` datetime NOT NULL default '0000-00-00 00:00:00', `map_count` int(10) unsigned NOT NULL default '0', `data` text NOT NULL, `params` mediumtext, PRIMARY KEY (`filter_id`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links` -- CREATE TABLE IF NOT EXISTS `#__finder_links` ( `link_id` int(10) unsigned NOT NULL auto_increment, `url` varchar(255) NOT NULL, `route` varchar(255) NOT NULL, `title` varchar(255) default NULL, `description` varchar(255) default NULL, `indexdate` datetime NOT NULL default '0000-00-00 00:00:00', `md5sum` varchar(32) default NULL, `published` tinyint(1) NOT NULL default '1', `state` int(5) default '1', `access` int(5) default '0', `language` varchar(8) NOT NULL, `publish_start_date` datetime NOT NULL default '0000-00-00 00:00:00', `publish_end_date` datetime NOT NULL default '0000-00-00 00:00:00', `start_date` datetime NOT NULL default '0000-00-00 00:00:00', `end_date` datetime NOT NULL default '0000-00-00 00:00:00', `list_price` double unsigned NOT NULL default '0', `sale_price` double unsigned NOT NULL default '0', `type_id` int(11) NOT NULL, `object` mediumblob NOT NULL, PRIMARY KEY (`link_id`), KEY `idx_type` (`type_id`), KEY `idx_title` (`title`), KEY `idx_md5` (`md5sum`), KEY `idx_url` (`url`(75)), KEY `idx_published_list` (`published`,`state`,`access`,`publish_start_date`,`publish_end_date`,`list_price`), KEY `idx_published_sale` (`published`,`state`,`access`,`publish_start_date`,`publish_end_date`,`sale_price`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms0` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms0` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms1` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms1` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms2` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms2` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms3` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms3` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms4` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms4` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms5` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms5` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms6` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms6` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms7` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms7` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms8` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms8` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms9` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms9` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_termsa` -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsa` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_termsb` -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsb` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_termsc` -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsc` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_termsd` -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsd` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_termse` -- CREATE TABLE IF NOT EXISTS `#__finder_links_termse` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_termsf` -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsf` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_taxonomy` -- CREATE TABLE IF NOT EXISTS `#__finder_taxonomy` ( `id` int(10) unsigned NOT NULL auto_increment, `parent_id` int(10) unsigned NOT NULL default '0', `title` varchar(255) NOT NULL, `state` tinyint(1) unsigned NOT NULL default '1', `access` tinyint(1) unsigned NOT NULL default '0', `ordering` tinyint(1) unsigned NOT NULL default '0', PRIMARY KEY (`id`), KEY `parent_id` (`parent_id`), KEY `state` (`state`), KEY `ordering` (`ordering`), KEY `access` (`access`), KEY `idx_parent_published` (`parent_id`,`state`,`access`) ) DEFAULT CHARSET=utf8; -- -- Dumping data for table `#__finder_taxonomy` -- REPLACE INTO `#__finder_taxonomy` (`id`, `parent_id`, `title`, `state`, `access`, `ordering`) VALUES (1, 0, 'ROOT', 0, 0, 0); -- -------------------------------------------------------- -- -- Table structure for table `#__finder_taxonomy_map` -- CREATE TABLE IF NOT EXISTS `#__finder_taxonomy_map` ( `link_id` int(10) unsigned NOT NULL, `node_id` int(10) unsigned NOT NULL, PRIMARY KEY (`link_id`,`node_id`), KEY `link_id` (`link_id`), KEY `node_id` (`node_id`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_terms` -- CREATE TABLE IF NOT EXISTS `#__finder_terms` ( `term_id` int(10) unsigned NOT NULL auto_increment, `term` varchar(75) NOT NULL, `stem` varchar(75) NOT NULL, `common` tinyint(1) unsigned NOT NULL default '0', `phrase` tinyint(1) unsigned NOT NULL default '0', `weight` float unsigned NOT NULL default '0', `soundex` varchar(75) NOT NULL, `links` int(10) NOT NULL default '0', PRIMARY KEY (`term_id`), UNIQUE KEY `idx_term` (`term`), KEY `idx_term_phrase` (`term`,`phrase`), KEY `idx_stem_phrase` (`stem`,`phrase`), KEY `idx_soundex_phrase` (`soundex`,`phrase`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_terms_common` -- CREATE TABLE IF NOT EXISTS `#__finder_terms_common` ( `term` varchar(75) NOT NULL, `language` varchar(3) NOT NULL, KEY `idx_word_lang` (`term`,`language`), KEY `idx_lang` (`language`) ) DEFAULT CHARSET=utf8; -- -- Dumping data for table `#__finder_terms_common` -- REPLACE INTO `#__finder_terms_common` (`term`, `language`) VALUES ('a', 'en'), ('about', 'en'), ('after', 'en'), ('ago', 'en'), ('all', 'en'), ('am', 'en'), ('an', 'en'), ('and', 'en'), ('ani', 'en'), ('any', 'en'), ('are', 'en'), ('aren''t', 'en'), ('as', 'en'), ('at', 'en'), ('be', 'en'), ('but', 'en'), ('by', 'en'), ('for', 'en'), ('from', 'en'), ('get', 'en'), ('go', 'en'), ('how', 'en'), ('if', 'en'), ('in', 'en'), ('into', 'en'), ('is', 'en'), ('isn''t', 'en'), ('it', 'en'), ('its', 'en'), ('me', 'en'), ('more', 'en'), ('most', 'en'), ('must', 'en'), ('my', 'en'), ('new', 'en'), ('no', 'en'), ('none', 'en'), ('not', 'en'), ('noth', 'en'), ('nothing', 'en'), ('of', 'en'), ('off', 'en'), ('often', 'en'), ('old', 'en'), ('on', 'en'), ('onc', 'en'), ('once', 'en'), ('onli', 'en'), ('only', 'en'), ('or', 'en'), ('other', 'en'), ('our', 'en'), ('ours', 'en'), ('out', 'en'), ('over', 'en'), ('page', 'en'), ('she', 'en'), ('should', 'en'), ('small', 'en'), ('so', 'en'), ('some', 'en'), ('than', 'en'), ('thank', 'en'), ('that', 'en'), ('the', 'en'), ('their', 'en'), ('theirs', 'en'), ('them', 'en'), ('then', 'en'), ('there', 'en'), ('these', 'en'), ('they', 'en'), ('this', 'en'), ('those', 'en'), ('thus', 'en'), ('time', 'en'), ('times', 'en'), ('to', 'en'), ('too', 'en'), ('true', 'en'), ('under', 'en'), ('until', 'en'), ('up', 'en'), ('upon', 'en'), ('use', 'en'), ('user', 'en'), ('users', 'en'), ('veri', 'en'), ('version', 'en'), ('very', 'en'), ('via', 'en'), ('want', 'en'), ('was', 'en'), ('way', 'en'), ('were', 'en'), ('what', 'en'), ('when', 'en'), ('where', 'en'), ('whi', 'en'), ('which', 'en'), ('who', 'en'), ('whom', 'en'), ('whose', 'en'), ('why', 'en'), ('wide', 'en'), ('will', 'en'), ('with', 'en'), ('within', 'en'), ('without', 'en'), ('would', 'en'), ('yes', 'en'), ('yet', 'en'), ('you', 'en'), ('your', 'en'), ('yours', 'en'); -- -------------------------------------------------------- -- -- Table structure for table `#__finder_tokens` -- CREATE TABLE IF NOT EXISTS `#__finder_tokens` ( `term` varchar(75) NOT NULL, `stem` varchar(75) NOT NULL, `common` tinyint(1) unsigned NOT NULL default '0', `phrase` tinyint(1) unsigned NOT NULL default '0', `weight` float unsigned NOT NULL default '1', `context` tinyint(1) unsigned NOT NULL default '2', KEY `idx_word` (`term`), KEY `idx_context` (`context`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_tokens_aggregate` -- CREATE TABLE IF NOT EXISTS `#__finder_tokens_aggregate` ( `term_id` int(10) unsigned NOT NULL, `map_suffix` char(1) NOT NULL, `term` varchar(75) NOT NULL, `stem` varchar(75) NOT NULL, `common` tinyint(1) unsigned NOT NULL default '0', `phrase` tinyint(1) unsigned NOT NULL default '0', `term_weight` float unsigned NOT NULL, `context` tinyint(1) unsigned NOT NULL default '2', `context_weight` float unsigned NOT NULL, `total_weight` float unsigned NOT NULL, KEY `token` (`term`), KEY `keyword_id` (`term_id`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_types` -- CREATE TABLE IF NOT EXISTS `#__finder_types` ( `id` int(10) unsigned NOT NULL auto_increment, `title` varchar(100) NOT NULL, `mime` varchar(100) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `title` (`title`) ) DEFAULT CHARSET=utf8; PK>\) sql/.htaccessnuW+A Order allow,deny Deny from all PK>\6sql/index.htmlnuW+APK>\)sql/install.postgresql.sqlnuW+A-- -- Table: #__finder_filters -- CREATE TABLE "#__finder_filters" ( "filter_id" serial NOT NULL, "title" character varying(255) NOT NULL, "alias" character varying(255) NOT NULL, "state" smallint DEFAULT 1 NOT NULL, "created" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "created_by" integer NOT NULL, "created_by_alias" character varying(255) NOT NULL, "modified" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "modified_by" integer DEFAULT 0 NOT NULL, "checked_out" integer DEFAULT 0 NOT NULL, "checked_out_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "map_count" integer DEFAULT 0 NOT NULL, "data" text NOT NULL, "params" text, PRIMARY KEY ("filter_id") ); -- -- Table: #__finder_links -- CREATE TABLE "#__finder_links" ( "link_id" serial NOT NULL, "url" character varying(255) NOT NULL, "route" character varying(255) NOT NULL, "title" character varying(255) DEFAULT NULL, "description" character varying(255) DEFAULT NULL, "indexdate" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "md5sum" character varying(32) DEFAULT NULL, "published" smallint DEFAULT 1 NOT NULL, "state" integer DEFAULT 1, "access" integer DEFAULT 0, "language" character varying(8) NOT NULL, "publish_start_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "publish_end_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "start_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "end_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "list_price" numeric(8,2) DEFAULT 0 NOT NULL, "sale_price" numeric(8,2) DEFAULT 0 NOT NULL, "type_id" bigint NOT NULL, "object" bytea NOT NULL, PRIMARY KEY ("link_id") ); CREATE INDEX "#__finder_links_idx_type" on "#__finder_links" ("type_id"); CREATE INDEX "#__finder_links_idx_title" on "#__finder_links" ("title"); CREATE INDEX "#__finder_links_idx_md5" on "#__finder_links" ("md5sum"); CREATE INDEX "#__finder_links_idx_url" on "#__finder_links" (url(75)); CREATE INDEX "#__finder_links_idx_published_list" on "#__finder_links" ("published", "state", "access", "publish_start_date", "publish_end_date", "list_price"); CREATE INDEX "#__finder_links_idx_published_sale" on "#__finder_links" ("published", "state", "access", "publish_start_date", "publish_end_date", "sale_price"); -- -- Table: #__finder_links_terms0 -- CREATE TABLE "#__finder_links_terms0" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms0_idx_term_weight" on "#__finder_links_terms0" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms0_idx_link_term_weight" on "#__finder_links_terms0" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms1 -- CREATE TABLE "#__finder_links_terms1" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms1_idx_term_weight" on "#__finder_links_terms1" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms1_idx_link_term_weight" on "#__finder_links_terms1" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms2 -- CREATE TABLE "#__finder_links_terms2" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms2_idx_term_weight" on "#__finder_links_terms2" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms2_idx_link_term_weight" on "#__finder_links_terms2" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms3 -- CREATE TABLE "#__finder_links_terms3" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms3_idx_term_weight" on "#__finder_links_terms3" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms3_idx_link_term_weight" on "#__finder_links_terms3" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms4 -- CREATE TABLE "#__finder_links_terms4" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms4_idx_term_weight" on "#__finder_links_terms4" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms4_idx_link_term_weight" on "#__finder_links_terms4" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms5 -- CREATE TABLE "#__finder_links_terms5" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms5_idx_term_weight" on "#__finder_links_terms5" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms5_idx_link_term_weight" on "#__finder_links_terms5" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms6 -- CREATE TABLE "#__finder_links_terms6" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms6_idx_term_weight" on "#__finder_links_terms6" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms6_idx_link_term_weight" on "#__finder_links_terms6" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms7 -- CREATE TABLE "#__finder_links_terms7" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms7_idx_term_weight" on "#__finder_links_terms7" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms7_idx_link_term_weight" on "#__finder_links_terms7" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms8 -- CREATE TABLE "#__finder_links_terms8" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms8_idx_term_weight" on "#__finder_links_terms8" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms8_idx_link_term_weight" on "#__finder_links_terms8" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms9 -- CREATE TABLE "#__finder_links_terms9" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms9_idx_term_weight" on "#__finder_links_terms9" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms9_idx_link_term_weight" on "#__finder_links_terms9" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_termsa -- CREATE TABLE "#__finder_links_termsa" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_termsa_idx_term_weight" on "#__finder_links_termsa" ("term_id", "weight"); CREATE INDEX "#__finder_links_termsa_idx_link_term_weight" on "#__finder_links_termsa" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_termsb -- CREATE TABLE "#__finder_links_termsb" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_termsb_idx_term_weight" on "#__finder_links_termsb" ("term_id", "weight"); CREATE INDEX "#__finder_links_termsb_idx_link_term_weight" on "#__finder_links_termsb" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_termsc -- CREATE TABLE "#__finder_links_termsc" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_termsc_idx_term_weight" on "#__finder_links_termsc" ("term_id", "weight"); CREATE INDEX "#__finder_links_termsc_idx_link_term_weight" on "#__finder_links_termsc" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_termsd -- CREATE TABLE "#__finder_links_termsd" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_termsd_idx_term_weight" on "#__finder_links_termsd" ("term_id", "weight"); CREATE INDEX "#__finder_links_termsd_idx_link_term_weight" on "#__finder_links_termsd" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_termse -- CREATE TABLE "#__finder_links_termse" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_termse_idx_term_weight" on "#__finder_links_termse" ("term_id", "weight"); CREATE INDEX "#__finder_links_termse_idx_link_term_weight" on "#__finder_links_termse" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_termsf -- CREATE TABLE "#__finder_links_termsf" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_termsf_idx_term_weight" on "#__finder_links_termsf" ("term_id", "weight"); CREATE INDEX "#__finder_links_termsf_idx_link_term_weight" on "#__finder_links_termsf" ("link_id", "term_id", "weight"); -- -- Table: #__finder_taxonomy -- CREATE TABLE "#__finder_taxonomy" ( "id" serial NOT NULL, "parent_id" integer DEFAULT 0 NOT NULL, "title" character varying(255) NOT NULL, "state" smallint DEFAULT 1 NOT NULL, "access" smallint DEFAULT 0 NOT NULL, "ordering" smallint DEFAULT 0 NOT NULL, PRIMARY KEY ("id") ); CREATE INDEX "#__finder_taxonomy_parent_id" on "#__finder_taxonomy" ("parent_id"); CREATE INDEX "#__finder_taxonomy_state" on "#__finder_taxonomy" ("state"); CREATE INDEX "#__finder_taxonomy_ordering" on "#__finder_taxonomy" ("ordering"); CREATE INDEX "#__finder_taxonomy_access" on "#__finder_taxonomy" ("access"); CREATE INDEX "#__finder_taxonomy_idx_parent_published" on "#__finder_taxonomy" ("parent_id", "state", "access"); -- -- Dumping data for table #__finder_taxonomy -- UPDATE "#__finder_taxonomy" SET ("id", "parent_id", "title", "state", "access", "ordering") = (1, 0, 'ROOT', 0, 0, 0) WHERE "id"=1; INSERT INTO "#__finder_taxonomy" ("id", "parent_id", "title", "state", "access", "ordering") SELECT 1, 0, 'ROOT', 0, 0, 0 WHERE 1 NOT IN (SELECT 1 FROM "#__finder_taxonomy" WHERE "id"=1); -- -- Table: #__finder_taxonomy_map -- CREATE TABLE "#__finder_taxonomy_map" ( "link_id" integer NOT NULL, "node_id" integer NOT NULL, PRIMARY KEY ("link_id", "node_id") ); CREATE INDEX "#__finder_taxonomy_map_link_id" on "#__finder_taxonomy_map" ("link_id"); CREATE INDEX "#__finder_taxonomy_map_node_id" on "#__finder_taxonomy_map" ("node_id"); -- -- Table: #__finder_terms -- CREATE TABLE "#__finder_terms" ( "term_id" serial NOT NULL, "term" character varying(75) NOT NULL, "stem" character varying(75) NOT NULL, "common" smallint DEFAULT 0 NOT NULL, "phrase" smallint DEFAULT 0 NOT NULL, "weight" numeric(8,2) DEFAULT 0 NOT NULL, "soundex" character varying(75) NOT NULL, "links" integer DEFAULT 0 NOT NULL, PRIMARY KEY ("term_id"), CONSTRAINT "#__finder_terms_idx_term" UNIQUE ("term") ); CREATE INDEX "#__finder_terms_idx_term_phrase" on "#__finder_terms" ("term", "phrase"); CREATE INDEX "#__finder_terms_idx_stem_phrase" on "#__finder_terms" ("stem", "phrase"); CREATE INDEX "#__finder_terms_idx_soundex_phrase" on "#__finder_terms" ("soundex", "phrase"); -- -- Table: #__finder_terms_common -- CREATE TABLE "#__finder_terms_common" ( "term" character varying(75) NOT NULL, "language" character varying(3) NOT NULL ); CREATE INDEX "#__finder_terms_common_idx_word_lang" on "#__finder_terms_common" ("term", "language"); CREATE INDEX "#__finder_terms_common_idx_lang" on "#__finder_terms_common" ("language"); -- -- Dumping data for table `#__finder_terms_common` -- -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('a', 'en') WHERE "term"='a'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'a', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='a'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('about', 'en') WHERE "term"='about'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'about', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='about'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('after', 'en') WHERE "term"='after'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'after', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='after'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('ago', 'en') WHERE "term"='ago'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'ago', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='ago'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('all', 'en') WHERE "term"='all'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'all', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='all'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('am', 'en') WHERE "term"='am'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'am', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='am'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('an', 'en') WHERE "term"='an'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'an', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='an'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('and', 'en') WHERE "term"='and'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'and', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='and'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('ani', 'en') WHERE "term"='ani'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'ani', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='ani'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('any', 'en') WHERE "term"='any'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'any', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='any'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('are', 'en') WHERE "term"='are'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'are', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='are'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('aren''t', 'en') WHERE "term"='aren''t'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'aren''t', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='aren''t'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('as', 'en') WHERE "term"='as'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'as', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='as'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('at', 'en') WHERE "term"='at'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'at', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='at'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('be', 'en') WHERE "term"='be'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'be', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='be'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('but', 'en') WHERE "term"='but'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'but', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='but'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('by', 'en') WHERE "term"='by'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'by', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='by'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('for', 'en') WHERE "term"='for'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'for', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='for'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('from', 'en') WHERE "term"='from'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'from', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='from'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('get', 'en') WHERE "term"='get'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'get', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='get'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('go', 'en') WHERE "term"='go'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'go', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='go'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('how', 'en') WHERE "term"='how'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'how', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='how'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('if', 'en') WHERE "term"='if'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'if', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='if'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('in', 'en') WHERE "term"='in'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'in', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='in'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('into', 'en') WHERE "term"='into'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'into', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='into'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('is', 'en') WHERE "term"='is'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'is', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='is'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('isn''t', 'en') WHERE "term"='isn''t'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'isn''t', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='isn''t'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('it', 'en') WHERE "term"='it'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'it', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='it'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('its', 'en') WHERE "term"='its'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'its', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='its'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('me', 'en') WHERE "term"='me'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'me', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='me'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('more', 'en') WHERE "term"='more'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'more', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='more'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('most', 'en') WHERE "term"='most'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'most', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='most'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('must', 'en') WHERE "term"='must'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'must', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='must'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('my', 'en') WHERE "term"='my'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'my', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='my'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('new', 'en') WHERE "term"='new'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'new', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='new'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('no', 'en') WHERE "term"='no'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'no', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='no'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('none', 'en') WHERE "term"='none'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'none', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='none'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('not', 'en') WHERE "term"='not'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'not', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='not'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('noth', 'en') WHERE "term"='noth'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'noth', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='noth'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('nothing', 'en') WHERE "term"='nothing'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'nothing', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='nothing'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('of', 'en') WHERE "term"='of'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'of', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='of'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('off', 'en') WHERE "term"='off'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'off', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='off'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('often', 'en') WHERE "term"='often'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'often', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='often'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('old', 'en') WHERE "term"='old'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'old', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='old'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('on', 'en') WHERE "term"='on'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'on', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='on'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('onc', 'en') WHERE "term"='onc'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'onc', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='onc'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('once', 'en') WHERE "term"='once'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'once', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='once'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('onli', 'en') WHERE "term"='onli'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'onli', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='onli'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('only', 'en') WHERE "term"='only'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'only', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='only'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('or', 'en') WHERE "term"='or'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'or', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='or'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('other', 'en') WHERE "term"='other'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'other', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='other'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('our', 'en') WHERE "term"='our'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'our', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='our'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('ours', 'en') WHERE "term"='ours'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'ours', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='ours'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('out', 'en') WHERE "term"='out'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'out', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='out'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('over', 'en') WHERE "term"='over'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'over', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='over'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('page', 'en') WHERE "term"='page'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'page', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='page'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('she', 'en') WHERE "term"='she'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'she', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='she'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('should', 'en') WHERE "term"='should'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'should', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='should'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('small', 'en') WHERE "term"='small'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'small', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='small'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('so', 'en') WHERE "term"='so'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'so', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='so'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('some', 'en') WHERE "term"='some'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'some', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='some'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('than', 'en') WHERE "term"='than'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'than', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='than'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('thank', 'en') WHERE "term"='thank'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'thank', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='thank'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('that', 'en') WHERE "term"='that'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'that', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='that'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('the', 'en') WHERE "term"='the'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'the', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='the'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('their', 'en') WHERE "term"='their'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'their', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='their'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('theirs', 'en') WHERE "term"='theirs'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'theirs', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='theirs'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('them', 'en') WHERE "term"='them'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'them', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='them'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('then', 'en') WHERE "term"='then'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'then', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='then'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('there', 'en') WHERE "term"='there'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'there', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='there'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('these', 'en') WHERE "term"='these'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'these', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='these'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('they', 'en') WHERE "term"='they'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'they', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='they'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('this', 'en') WHERE "term"='this'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'this', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='this'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('those', 'en') WHERE "term"='those'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'those', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='those'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('thus', 'en') WHERE "term"='thus'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'thus', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='thus'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('time', 'en') WHERE "term"='time'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'time', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='time'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('times', 'en') WHERE "term"='times'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'times', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='times'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('to', 'en') WHERE "term"='to'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'to', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='to'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('too', 'en') WHERE "term"='too'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'too', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='too'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('true', 'en') WHERE "term"='true'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'true', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='true'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('under', 'en')WHERE "term"='under'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'under', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='under'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('until', 'en') WHERE "term"='until'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'until', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='until'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('up', 'en') WHERE "term"='up'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'up', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='up'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('upon', 'en') WHERE "term"='upon'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'upon', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='upon'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('use', 'en') WHERE "term"='use'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'use', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='use'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('user', 'en') WHERE "term"='user'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'user', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='user'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('users', 'en') WHERE "term"='users'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'users', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='users'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('veri', 'en') WHERE "term"='veri'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'veri', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='veri'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('version', 'en') WHERE "term"='version'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'version', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='version'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('very', 'en') WHERE "term"='very'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'very', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='very'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('via', 'en') WHERE "term"='via'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'via', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='via'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('want', 'en') WHERE "term"='want'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'want', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='want'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('was', 'en') WHERE "term"='was'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'was', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='was'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('way', 'en') WHERE "term"='way'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'way', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='way'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('were', 'en') WHERE "term"='were'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'were', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='were'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('what', 'en') WHERE "term"='what'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'what', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='what'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('when', 'en') WHERE "term"='when'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'when', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='when'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('where', 'en') WHERE "term"='where'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'where', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='where'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('whi', 'en') WHERE "term"='whi'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'whi', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='whi'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('which', 'en') WHERE "term"='which'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'which', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='which'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('who', 'en') WHERE "term"='who'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'who', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='who'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('whom', 'en') WHERE "term"='whom'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'whom', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='whom'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('whose', 'en') WHERE "term"='whose'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'whose', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='whose'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('why', 'en') WHERE "term"='why'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'why', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='why'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('wide', 'en') WHERE "term"='wide'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'wide', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='wide'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('will', 'en') WHERE "term"='will'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'will', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='will'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('with', 'en') WHERE "term"='with'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'with', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='with'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('within', 'en') WHERE "term"='within'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'within', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='within'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('without', 'en') WHERE "term"='without'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'without', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='without'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('would', 'en') WHERE "term"='would'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'would', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='would'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('yes', 'en') WHERE "term"='yes'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'yes', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='yes'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('yet', 'en') WHERE "term"='yet'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'yet', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='yet'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('you', 'en') WHERE "term"='you'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'you', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='you'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('your', 'en') WHERE "term"='your'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'your', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='your'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('yours', 'en') WHERE "term"='yours'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'yours', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='yours'); -- -- Table: #__finder_tokens -- CREATE TABLE "#__finder_tokens" ( "term" character varying(75) NOT NULL, "stem" character varying(75) NOT NULL, "common" smallint DEFAULT 0 NOT NULL, "phrase" smallint DEFAULT 0 NOT NULL, "weight" numeric(8,2) DEFAULT 1 NOT NULL, "context" smallint DEFAULT 2 NOT NULL ); CREATE INDEX "#__finder_tokens_idx_word" on "#__finder_tokens" ("term"); CREATE INDEX "#__finder_tokens_idx_context" on "#__finder_tokens" ("context"); -- -- Table: #__finder_tokens_aggregate -- CREATE TABLE "#__finder_tokens_aggregate" ( "term_id" integer NOT NULL, "map_suffix" character(1) NOT NULL, "term" character varying(75) NOT NULL, "stem" character varying(75) NOT NULL, "common" smallint DEFAULT 0 NOT NULL, "phrase" smallint DEFAULT 0 NOT NULL, "term_weight" numeric(8,2) NOT NULL, "context" smallint DEFAULT 2 NOT NULL, "context_weight" numeric(8,2) NOT NULL, "total_weight" numeric(8,2) NOT NULL ); CREATE INDEX "#__finder_tokens_aggregate_token" on "#__finder_tokens_aggregate" ("term"); CREATE INDEX "_#__finder_tokens_aggregate_keyword_id" on "#__finder_tokens_aggregate" ("term_id"); -- -- Table: #__finder_types -- CREATE TABLE "#__finder_types" ( "id" serial NOT NULL, "title" character varying(100) NOT NULL, "mime" character varying(100) NOT NULL, PRIMARY KEY ("id"), CONSTRAINT "#__finder_types_title" UNIQUE ("title") ); PK>\1iwwsql/uninstall.mysql.sqlnuW+ADROP TABLE IF EXISTS `#__finder_filters`; DROP TABLE IF EXISTS `#__finder_links`; DROP TABLE IF EXISTS `#__finder_links_terms0`; DROP TABLE IF EXISTS `#__finder_links_terms1`; DROP TABLE IF EXISTS `#__finder_links_terms2`; DROP TABLE IF EXISTS `#__finder_links_terms3`; DROP TABLE IF EXISTS `#__finder_links_terms4`; DROP TABLE IF EXISTS `#__finder_links_terms5`; DROP TABLE IF EXISTS `#__finder_links_terms6`; DROP TABLE IF EXISTS `#__finder_links_terms7`; DROP TABLE IF EXISTS `#__finder_links_terms8`; DROP TABLE IF EXISTS `#__finder_links_terms9`; DROP TABLE IF EXISTS `#__finder_links_termsa`; DROP TABLE IF EXISTS `#__finder_links_termsb`; DROP TABLE IF EXISTS `#__finder_links_termsc`; DROP TABLE IF EXISTS `#__finder_links_termsd`; DROP TABLE IF EXISTS `#__finder_links_termse`; DROP TABLE IF EXISTS `#__finder_links_termsf`; DROP TABLE IF EXISTS `#__finder_taxonomy`; DROP TABLE IF EXISTS `#__finder_taxonomy_map`; DROP TABLE IF EXISTS `#__finder_terms`; DROP TABLE IF EXISTS `#__finder_terms_common`; DROP TABLE IF EXISTS `#__finder_tokens`; DROP TABLE IF EXISTS `#__finder_tokens_aggregate`; DROP TABLE IF EXISTS `#__finder_types`; PK>\|wwsql/uninstall.postgresql.sqlnuW+ADROP TABLE IF EXISTS "#__finder_filters"; DROP TABLE IF EXISTS "#__finder_links"; DROP TABLE IF EXISTS "#__finder_links_terms0"; DROP TABLE IF EXISTS "#__finder_links_terms1"; DROP TABLE IF EXISTS "#__finder_links_terms2"; DROP TABLE IF EXISTS "#__finder_links_terms3"; DROP TABLE IF EXISTS "#__finder_links_terms4"; DROP TABLE IF EXISTS "#__finder_links_terms5"; DROP TABLE IF EXISTS "#__finder_links_terms6"; DROP TABLE IF EXISTS "#__finder_links_terms7"; DROP TABLE IF EXISTS "#__finder_links_terms8"; DROP TABLE IF EXISTS "#__finder_links_terms9"; DROP TABLE IF EXISTS "#__finder_links_termsa"; DROP TABLE IF EXISTS "#__finder_links_termsb"; DROP TABLE IF EXISTS "#__finder_links_termsc"; DROP TABLE IF EXISTS "#__finder_links_termsd"; DROP TABLE IF EXISTS "#__finder_links_termse"; DROP TABLE IF EXISTS "#__finder_links_termsf"; DROP TABLE IF EXISTS "#__finder_taxonomy"; DROP TABLE IF EXISTS "#__finder_taxonomy_map"; DROP TABLE IF EXISTS "#__finder_terms"; DROP TABLE IF EXISTS "#__finder_terms_common"; DROP TABLE IF EXISTS "#__finder_tokens"; DROP TABLE IF EXISTS "#__finder_tokens_aggregate"; DROP TABLE IF EXISTS "#__finder_types"; PK>\)helpers/.htaccessnuW+A Order allow,deny Deny from all PK>\6helpers/index.htmlnuW+APK>\/ helpers/language.phpnuW+Aload('com_finder', JPATH_SITE); } /** * Method to load Smart Search plug-in language files. * * @return void * * @since 2.5 */ public static function loadPluginLanguage() { static $loaded = false; // If already loaded, don't load again. if ($loaded) { return; } $loaded = true; // Get array of all the enabled Smart Search plug-in names. $db = JFactory::getDbo(); $query = $db->getQuery(true); $query->select('name'); $query->from($db->quoteName('#__extensions')); $query->where($db->quoteName('type') . ' = ' . $db->quote('plugin')); $query->where($db->quoteName('folder') . ' = ' . $db->quote('finder')); $query->where($db->quoteName('enabled') . ' = 1'); $db->setQuery($query); $plugins = $db->loadObjectList(); if (empty($plugins)) { return; } // Load generic language strings. $lang = JFactory::getLanguage(); $lang->load('plg_content_finder', JPATH_ADMINISTRATOR); // Load language file for each plug-in. foreach ($plugins as $plugin) { $lang->load($plugin->name, JPATH_ADMINISTRATOR); } } } PK>\eâ77helpers/indexer/helper.phpnuW+Aparse($input); } /** * Method to tokenize a text string. * * @param string $input The input to tokenize. * @param string $lang The language of the input. * @param boolean $phrase Flag to indicate whether input could be a phrase. [optional] * * @return array An array of FinderIndexerToken objects. * * @since 2.5 */ public static function tokenize($input, $lang, $phrase = false) { static $cache; $store = JString::strlen($input) < 128 ? md5($input . '::' . $lang . '::' . $phrase) : null; // Check if the string has been tokenized already. if ($store && isset($cache[$store])) { return $cache[$store]; } $tokens = array(); $terms = array(); $quotes = html_entity_decode('‘’'', ENT_QUOTES, 'UTF-8'); // Get the simple language key. $lang = FinderIndexerHelper::getPrimaryLanguage($lang); /* * Parsing the string input into terms is a multi-step process. * * Regexes: * 1. Remove everything except letters, numbers, quotes, apostrophe, plus, dash, period, and comma. * 2. Remove plus, dash, period, and comma characters located before letter characters. * 3. Remove plus, dash, period, and comma characters located after other characters. * 4. Remove plus, period, and comma characters enclosed in alphabetical characters. Ungreedy. * 5. Remove orphaned apostrophe, plus, dash, period, and comma characters. * 6. Remove orphaned quote characters. * 7. Replace the assorted single quotation marks with the ASCII standard single quotation. * 8. Remove multiple space characters and replaces with a single space. */ $input = JString::strtolower($input); $input = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,]+#mui', ' ', $input); $input = preg_replace('#(^|\s)[+-.,]+([\pL\pM]+)#mui', ' $1', $input); $input = preg_replace('#([\pL\pM\pN]+)[+-.,]+(\s|$)#mui', '$1 ', $input); $input = preg_replace('#([\pL\pM]+)[+.,]+([\pL\pM]+)#muiU', '$1 $2', $input); // Ungreedy $input = preg_replace('#(^|\s)[\'+-.,]+(\s|$)#mui', ' ', $input); $input = preg_replace('#(^|\s)[\p{Pi}\p{Pf}]+(\s|$)#mui', ' ', $input); $input = preg_replace('#[' . $quotes . ']+#mui', '\'', $input); $input = preg_replace('#\s+#mui', ' ', $input); $input = JString::trim($input); // Explode the normalized string to get the terms. $terms = explode(' ', $input); /* * If we have Unicode support and are dealing with Chinese text, Chinese * has to be handled specially because there are not necessarily any spaces * between the "words". So, we have to test if the words belong to the Chinese * character set and if so, explode them into single glyphs or "words". */ if ($lang === 'zh') { // Iterate through the terms and test if they contain Chinese. for ($i = 0, $n = count($terms); $i < $n; $i++) { $charMatches = array(); $charCount = preg_match_all('#[\p{Han}]#mui', $terms[$i], $charMatches); // Split apart any groups of Chinese characters. for ($j = 0; $j < $charCount; $j++) { $tSplit = JString::str_ireplace($charMatches[0][$j], '', $terms[$i], false); if (!empty($tSplit)) { $terms[$i] = $tSplit; } else { unset($terms[$i]); } $terms[] = $charMatches[0][$j]; } } // Reset array keys. $terms = array_values($terms); } /* * If we have to handle the input as a phrase, that means we don't * tokenize the individual terms and we do not create the two and three * term combinations. The phrase must contain more than one word! */ if ($phrase === true && count($terms) > 1) { // Create tokens from the phrase. $tokens[] = new FinderIndexerToken($terms, $lang); } else { // Create tokens from the terms. for ($i = 0, $n = count($terms); $i < $n; $i++) { $tokens[] = new FinderIndexerToken($terms[$i], $lang); } // Create two and three word phrase tokens from the individual words. for ($i = 0, $n = count($tokens); $i < $n; $i++) { // Setup the phrase positions. $i2 = $i + 1; $i3 = $i + 2; // Create the two word phrase. if ($i2 < $n && isset($tokens[$i2])) { // Tokenize the two word phrase. $token = new FinderIndexerToken(array($tokens[$i]->term, $tokens[$i2]->term), $lang, $lang === 'zh' ? '' : ' '); $token->derived = true; // Add the token to the stack. $tokens[] = $token; } // Create the three word phrase. if ($i3 < $n && isset($tokens[$i3])) { // Tokenize the three word phrase. $token = new FinderIndexerToken(array($tokens[$i]->term, $tokens[$i2]->term, $tokens[$i3]->term), $lang, $lang === 'zh' ? '' : ' '); $token->derived = true; // Add the token to the stack. $tokens[] = $token; } } } if ($store) { $cache[$store] = count($tokens) > 1 ? $tokens : array_shift($tokens); return $cache[$store]; } else { return count($tokens) > 1 ? $tokens : array_shift($tokens); } } /** * Method to get the base word of a token. This method uses the public * {@link FinderIndexerHelper::$stemmer} object if it is set. If no stemmer is set, * the original token is returned. * * @param string $token The token to stem. * @param string $lang The language of the token. * * @return string The root token. * * @since 2.5 */ public static function stem($token, $lang) { // Trim apostrophes at either end of the token. $token = JString::trim($token, '\''); // Trim everything after any apostrophe in the token. if (($pos = JString::strpos($token, '\'')) !== false) { $token = JString::substr($token, 0, $pos); } // Stem the token if we have a valid stemmer to use. if (self::$stemmer instanceof FinderIndexerStemmer) { return self::$stemmer->stem($token, $lang); } else { return $token; } } /** * Method to add a content type to the database. * * @param string $title The type of content. For example: PDF * @param string $mime The mime type of the content. For example: PDF [optional] * * @return integer The id of the content type. * * @since 2.5 * @throws Exception on database error. */ public static function addContentType($title, $mime = null) { static $types; $db = JFactory::getDBO(); $query = $db->getQuery(true); // Check if the types are loaded. if (empty($types)) { // Build the query to get the types. $query->select('*'); $query->from($db->quoteName('#__finder_types')); // Get the types. $db->setQuery($query); $types = $db->loadObjectList('title'); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } } // Check if the type already exists. if (isset($types[$title])) { return (int) $types[$title]->id; } // Add the type. $query->clear(); $query->insert($db->quoteName('#__finder_types')); $query->columns(array($db->quoteName('title'), $db->quoteName('mime'))); $query->values($db->quote($title) . ', ' . $db->quote($mime)); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Return the new id. return (int) $db->insertid(); } /** * Method to check if a token is common in a language. * * @param string $token The token to test. * @param string $lang The language to reference. * * @return boolean True if common, false otherwise. * * @since 2.5 */ public static function isCommon($token, $lang) { static $data; // Load the common tokens for the language if necessary. if (!isset($data[$lang])) { $data[$lang] = FinderIndexerHelper::getCommonWords($lang); } // Check if the token is in the common array. if (in_array($token, $data[$lang])) { return true; } else { return false; } } /** * Method to get an array of common terms for a language. * * @param string $lang The language to use. * * @return array Array of common terms. * * @since 2.5 * @throws Exception on database error. */ public static function getCommonWords($lang) { $db = JFactory::getDBO(); // Create the query to load all the common terms for the language. $query = $db->getQuery(true); $query->select($db->quoteName('term')); $query->from($db->quoteName('#__finder_terms_common')); $query->where($db->quoteName('language') . ' = ' . $db->quote($lang)); // Load all of the common terms for the language. $db->setQuery($query); $results = $db->loadColumn(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } return $results; } /** * Method to get the default language for the site. * * @return string The default language string. * * @since 2.5 */ public static function getDefaultLanguage() { static $lang; // Get the default language. if (empty($lang)) { $lang = JComponentHelper::getParams('com_languages')->get('site', 'en-GB'); } return $lang; } /** * Method to parse a language/locale key and return a simple language string. * * @param string $lang The language/locale key. For example: en-GB * * @return string The simple language string. For example: en * * @since 2.5 */ public static function getPrimaryLanguage($lang) { static $data; // Only parse the identifier if necessary. if (!isset($data[$lang])) { if (is_callable(array('Locale', 'getPrimaryLanguage'))) { // Get the language key using the Locale package. $data[$lang] = Locale::getPrimaryLanguage($lang); } else { // Get the language key using string position. $data[$lang] = JString::substr($lang, 0, JString::strpos($lang, '-')); } } return $data[$lang]; } /** * Method to get the path (SEF route) for a content item. * * @param string $url The non-SEF route to the content item. * * @return string The path for the content item. * * @since 2.5 */ public static function getContentPath($url) { static $router; // Only get the router once. if (!($router instanceof JRouter)) { jimport('joomla.application.router'); include_once JPATH_SITE . '/includes/application.php'; // Get and configure the site router. $config = JFactory::getConfig(); $router = JRouter::getInstance('site'); $router->setMode($config->get('sef', 1)); } // Build the relative route. $uri = $router->build($url); $route = $uri->toString(array('path', 'query', 'fragment')); $route = str_replace(JURI::base(true) . '/', '', $route); return $route; } /** * Method to get extra data for a content before being indexed. This is how * we add Comments, Tags, Labels, etc. that should be available to Finder. * * @param FinderIndexerResult &$item The item to index as an FinderIndexerResult object. * * @return boolean True on success, false on failure. * * @since 2.5 * @throws Exception on database error. */ public static function getContentExtras(FinderIndexerResult &$item) { // Get the event dispatcher. $dispatcher = JDispatcher::getInstance(); // Load the finder plugin group. JPluginHelper::importPlugin('finder'); try { // Trigger the event. $results = $dispatcher->trigger('onPrepareFinderContent', array(&$item)); // Check the returned results. This is for plugins that don't throw // exceptions when they encounter serious errors. if (in_array(false, $results)) { throw new Exception($dispatcher->getError(), 500); } } catch (Exception $e) { // Handle a caught exception. throw $e; } return true; } /** * Method to process content text using the onContentPrepare event trigger. * * @param string $text The content to process. * @param JRegistry $params The parameters object. [optional] * * @return string The processed content. * * @since 2.5 */ public static function prepareContent($text, $params = null) { static $loaded; // Get the dispatcher. $dispatcher = JDispatcher::getInstance(); // Load the content plugins if necessary. if (empty($loaded)) { JPluginHelper::importPlugin('content'); $loaded = true; } // Instantiate the parameter object if necessary. if (!($params instanceof JRegistry)) { $registry = new JRegistry; $registry->loadString($params); $params = $registry; } // Create a mock content object. $content = JTable::getInstance('Content'); $content->text = $text; // Fire the onContentPrepare event. $dispatcher->trigger('onContentPrepare', array('com_finder.indexer', &$content, &$params, 0)); return $content->text; } } PK>\6helpers/indexer/index.htmlnuW+APK>\)helpers/indexer/.htaccessnuW+A Order allow,deny Deny from all PK>\}lW W helpers/indexer/parser.phpnuW+Aclean($format, 'cmd'); $path = dirname(__FILE__) . '/parser/' . $format . '.php'; $class = 'FinderIndexerParser' . ucfirst($format); // Check if a parser exists for the format. if (file_exists($path)) { // Instantiate the parser. include_once $path; $instances[$format] = new $class; } else { // Throw invalid format exception. throw new Exception(JText::sprintf('COM_FINDER_INDEXER_INVALID_PARSER', $format)); } return $instances[$format]; } /** * Method to parse input and extract the plain text. Because this method is * called from both inside and outside the indexer, it needs to be able to * batch out its parsing functionality to deal with the inefficiencies of * regular expressions. We will parse recursively in 2KB chunks. * * @param string $input The input to parse. * * @return string The plain text input. * * @since 2.5 */ public function parse($input) { $return = null; // Parse the input in batches if bigger than 2KB. if (strlen($input) > 2048) { $start = 0; $end = strlen($input); $chunk = 2048; while ($start < $end) { // Setup the string. $string = substr($input, $start, $chunk); // Find the last space character if we aren't at the end. $ls = (($start + $chunk) < $end ? strrpos($string, ' ') : false); // Truncate to the last space character. if ($ls !== false) { $string = substr($string, 0, $ls); } // Adjust the start position for the next iteration. $start += ($ls !== false ? ($ls + 1 - $chunk) + $chunk : $chunk); // Parse the chunk. $return .= $this->process($string); } } // The input is less than 2KB so we can parse it efficiently. else { // Parse the chunk. $return .= $this->process($input); } return $return; } /** * Method to process input and extract the plain text. * * @param string $input The input to process. * * @return string The plain text input. * * @since 2.5 */ abstract protected function process($input); } PK>\>YYhelpers/indexer/indexer.phpnuW+Aget('_finder.state', null); // If the state is empty, load the values for the first time. if (empty($data)) { $data = new JObject; // Load the default configuration options. $data->options = JComponentHelper::getParams('com_finder'); // Setup the weight lookup information. $data->weights = array( self::TITLE_CONTEXT => round($data->options->get('title_multiplier', 1.7), 2), self::TEXT_CONTEXT => round($data->options->get('text_multiplier', 0.7), 2), self::META_CONTEXT => round($data->options->get('meta_multiplier', 1.2), 2), self::PATH_CONTEXT => round($data->options->get('path_multiplier', 2.0), 2), self::MISC_CONTEXT => round($data->options->get('misc_multiplier', 0.3), 2) ); // Set the current time as the start time. $data->startTime = JFactory::getDate()->toSQL(); // Set the remaining default values. $data->batchSize = (int) $data->options->get('batch_size', 50); $data->batchOffset = 0; $data->totalItems = 0; $data->pluginState = array(); } // Setup the profiler if debugging is enabled. if (JFactory::getApplication()->getCfg('debug')) { jimport('joomla.error.profiler'); self::$profiler = JProfiler::getInstance('FinderIndexer'); } // Setup the stemmer. if ($data->options->get('stem', 1) && $data->options->get('stemmer', 'porter_en')) { FinderIndexerHelper::$stemmer = FinderIndexerStemmer::getInstance($data->options->get('stemmer', 'porter_en')); } // Set the state. self::$state = $data; return self::$state; } /** * Method to set the indexer state. * * @param object $data A new indexer state object. * * @return boolean True on success, false on failure. * * @since 2.5 */ public static function setState($data) { // Check the state object. if (empty($data) || !$data instanceof JObject) { return false; } // Set the new internal state. self::$state = $data; // Set the new session state. $session = JFactory::getSession(); $session->set('_finder.state', $data); return true; } /** * Method to reset the indexer state. * * @return void * * @since 2.5 */ public static function resetState() { // Reset the internal state to null. self::$state = null; // Reset the session state to null. $session = JFactory::getSession(); $session->set('_finder.state', null); } /** * Method to index a content item. * * @param FinderIndexerResult $item The content item to index. * @param string $format The format of the content. [optional] * * @return integer The ID of the record in the links table. * * @since 2.5 * @throws Exception on database error. */ public static function index($item, $format = 'html') { // Mark beforeIndexing in the profiler. self::$profiler ? self::$profiler->mark('beforeIndexing') : null; $db = JFactory::getDBO(); $nd = $db->getNullDate(); // Check if the item is in the database. $query = $db->getQuery(true); $query->select($db->quoteName('link_id') . ', ' . $db->quoteName('md5sum')); $query->from($db->quoteName('#__finder_links')); $query->where($db->quoteName('url') . ' = ' . $db->quote($item->url)); // Load the item from the database. $db->setQuery($query); $link = $db->loadObject(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Get the indexer state. $state = FinderIndexer::getState(); // Get the signatures of the item. $curSig = self::getSignature($item); $oldSig = isset($link->md5sum) ? $link->md5sum : null; // Get the other item information. $linkId = empty($link->link_id) ? null : $link->link_id; $isNew = empty($link->link_id) ? true : false; // Check the signatures. If they match, the item is up to date. if (!$isNew && $curSig == $oldSig) { return $linkId; } /* * If the link already exists, flush all the term maps for the item. * Maps are stored in 16 tables so we need to iterate through and flush * each table one at a time. */ if (!$isNew) { for ($i = 0; $i <= 15; $i++) { // Flush the maps for the link. $query->clear(); $query->delete(); $query->from($db->quoteName('#__finder_links_terms' . dechex($i))); $query->where($db->quoteName('link_id') . ' = ' . (int) $linkId); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } } // Remove the taxonomy maps. FinderIndexerTaxonomy::removeMaps($linkId); } // Mark afterUnmapping in the profiler. self::$profiler ? self::$profiler->mark('afterUnmapping') : null; // Perform cleanup on the item data. $item->publish_start_date = intval($item->publish_start_date) != 0 ? $item->publish_start_date : $nd; $item->publish_end_date = intval($item->publish_end_date) != 0 ? $item->publish_end_date : $nd; $item->start_date = intval($item->start_date) != 0 ? $item->start_date : $nd; $item->end_date = intval($item->end_date) != 0 ? $item->end_date : $nd; // Prepare the item description. $item->description = FinderIndexerHelper::parse($item->summary); /* * Now, we need to enter the item into the links table. If the item * already exists in the database, we need to use an UPDATE query. * Otherwise, we need to use an INSERT to get the link id back. */ if ($isNew) { $columnsArray = array( $db->quoteName('url'), $db->quoteName('route'), $db->quoteName('title'), $db->quoteName('description'), $db->quoteName('indexdate'), $db->quoteName('published'), $db->quoteName('state'), $db->quoteName('access'), $db->quoteName('language'), $db->quoteName('type_id'), $db->quoteName('object'), $db->quoteName('publish_start_date'), $db->quoteName('publish_end_date'), $db->quoteName('start_date'), $db->quoteName('end_date'), $db->quoteName('list_price'), $db->quoteName('sale_price') ); // Insert the link. $query->clear(); $query->insert($db->quoteName('#__finder_links')); $query->columns($columnsArray); $query->values( $db->quote($item->url) . ', ' . $db->quote($item->route) . ', ' . $db->quote($item->title) . ', ' . $db->quote($item->description) . ', ' . $query->currentTimestamp() . ', ' . '1, ' . (int) $item->state . ', ' . (int) $item->access . ', ' . $db->quote($item->language) . ', ' . (int) $item->type_id . ', ' . $db->quote(serialize($item)) . ', ' . $db->quote($item->publish_start_date) . ', ' . $db->quote($item->publish_end_date) . ', ' . $db->quote($item->start_date) . ', ' . $db->quote($item->end_date) . ', ' . $db->quote($item->list_price) . ', ' . $db->quote($item->sale_price) ); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Get the link id. $linkId = (int) $db->insertid(); } else { // Update the link. //@TODO: Implement this $query->clear(); $query->update($db->qn('#__finder_links')); $query->set($db->qn('route') . ' = ' . $db->quote($item->route)); $query->set($db->qn('title') . ' = ' . $db->quote($item->title)); $query->set($db->qn('description') . ' = ' . $db->quote($item->description)); $query->set($db->qn('indexdate') . ' = ' . $query->currentTimestamp()); $query->set($db->qn('state') . ' = ' . (int) $item->state); $query->set($db->qn('access') . ' = ' . (int) $item->access); $query->set($db->qn('language') . ' = ' . $db->quote($item->language)); $query->set($db->qn('type_id') . ' = ' . (int) $item->type_id); $query->set($db->qn('object') . ' = ' . $db->quote(serialize($item))); $query->set($db->qn('publish_start_date') . ' = ' . $db->quote($item->publish_start_date)); $query->set($db->qn('publish_end_date') . ' = ' . $db->quote($item->publish_end_date)); $query->set($db->qn('start_date') . ' = ' . $db->quote($item->start_date)); $query->set($db->qn('end_date') . ' = ' . $db->quote($item->end_date)); $query->set($db->qn('list_price') . ' = ' . $db->quote($item->list_price)); $query->set($db->qn('sale_price') . ' = ' . $db->quote($item->sale_price)); $query->where('link_id = ' . (int) $linkId); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } } // Set up the variables we will need during processing. $tokens = array(); $count = 0; // Mark afterLinking in the profiler. self::$profiler ? self::$profiler->mark('afterLinking') : null; // Truncate the tokens tables. $db->truncateTable('#__finder_tokens'); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Truncate the tokens aggregate table. $db->truncateTable('#__finder_tokens_aggregate'); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } /* * Process the item's content. The items can customize their * processing instructions to define extra properties to process * or rearrange how properties are weighted. */ foreach ($item->getInstructions() as $group => $properties) { // Iterate through the properties of the group. foreach ($properties as $property) { // Check if the property exists in the item. if (empty($item->$property)) { continue; } // Tokenize the property. if (is_array($item->$property)) { // Tokenize an array of content and add it to the database. foreach ($item->$property as $ip) { // If the group is path, we need to a few extra processing // steps to strip the extension and convert slashes and dashes // to spaces. if ($group === self::PATH_CONTEXT) { $ip = JFile::stripExt($ip); $ip = str_replace('/', ' ', $ip); $ip = str_replace('-', ' ', $ip); } // Tokenize a string of content and add it to the database. $count += FinderIndexer::tokenizeToDB($ip, $group, $item->language, $format); // Check if we're approaching the memory limit of the token table. if ($count > self::$state->options->get('memory_table_limit', 30000)) { FinderIndexer::toggleTables(false); } } } else { // If the group is path, we need to a few extra processing // steps to strip the extension and convert slashes and dashes // to spaces. if ($group === self::PATH_CONTEXT) { $item->$property = JFile::stripExt($item->$property); $item->$property = str_replace('/', ' ', $item->$property); $item->$property = str_replace('-', ' ', $item->$property); } // Tokenize a string of content and add it to the database. $count += FinderIndexer::tokenizeToDB($item->$property, $group, $item->language, $format); // Check if we're approaching the memory limit of the token table. if ($count > self::$state->options->get('memory_table_limit', 30000)) { FinderIndexer::toggleTables(false); } } } } /* * Process the item's taxonomy. The items can customize their * taxonomy mappings to define extra properties to map. */ foreach ($item->getTaxonomy() as $branch => $nodes) { // Iterate through the nodes and map them to the branch. foreach ($nodes as $node) { // Add the node to the tree. $nodeId = FinderIndexerTaxonomy::addNode($branch, $node->title, $node->state, $node->access); // Add the link => node map. FinderIndexerTaxonomy::addMap($linkId, $nodeId); // Tokenize the node title and add them to the database. $count += FinderIndexer::tokenizeToDB($node->title, self::META_CONTEXT, $item->language, $format); } } // Mark afterProcessing in the profiler. self::$profiler ? self::$profiler->mark('afterProcessing') : null; /* * At this point, all of the item's content has been parsed, tokenized * and inserted into the #__finder_tokens table. Now, we need to * aggregate all the data into that table into a more usable form. The * aggregated data will be inserted into #__finder_tokens_aggregate * table. */ $query = 'INSERT INTO ' . $db->quoteName('#__finder_tokens_aggregate') . ' (' . $db->quoteName('term_id') . ', ' . $db->quoteName('term') . ', ' . $db->quoteName('stem') . ', ' . $db->quoteName('common') . ', ' . $db->quoteName('phrase') . ', ' . $db->quoteName('term_weight') . ', ' . $db->quoteName('context') . ', ' . $db->quoteName('context_weight') . ')' . ' SELECT' . ' t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context,' . ' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight' . ' FROM (' . ' SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context' . ' FROM ' . $db->quoteName('#__finder_tokens') . ' AS t1' . ' WHERE t1.context = %d' . ' ) AS t1' . ' JOIN ' . $db->quoteName('#__finder_tokens') . ' AS t2 ON t2.term = t1.term' . ' LEFT JOIN ' . $db->quoteName('#__finder_terms') . ' AS t ON t.term = t1.term' . ' WHERE t2.context = %d' . ' GROUP BY t1.term' . ' ORDER BY t1.term DESC'; // Iterate through the contexts and aggregate the tokens per context. foreach ($state->weights as $context => $multiplier) { // Run the query to aggregate the tokens for this context.. $db->setQuery(sprintf($query, $multiplier, $context, $context)); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } } // Mark afterAggregating in the profiler. self::$profiler ? self::$profiler->mark('afterAggregating') : null; /* * When we pulled down all of the aggregate data, we did a LEFT JOIN * over the terms table to try to find all the term ids that * already exist for our tokens. If any of the rows in the aggregate * table have a term of 0, then no term record exists for that * term so we need to add it to the terms table. */ //@TODO: PostgreSQL doesn't support SOUNDEX out of the box /* This edit is causing the indexer to fail. $queryInsIgn = 'INSERT INTO ' . $db->quoteName('#__finder_terms') . ' (' . $db->quoteName('term') . ', ' . $db->quoteName('stem') . ', ' . $db->quoteName('common') . ', ' . $db->quoteName('phrase') . ', ' . $db->quoteName('weight') . ', ' . $db->quoteName('soundex') . ')' . ' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term)' . ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' AS ta' . ' WHERE 1 NOT IN ' . '( SELECT 1 FROM ' . $db->quoteName('#__finder_terms') . ' WHERE ta.term_id = 0 )' . ' AND ta.term_id = 0' . ' GROUP BY ta.term'; $db->setQuery($queryInsIgn); $db->query(); // Check for a database error. if ($db->getErrorNum()) { //@TODO: PostgreSQL doesn't support SOUNDEX out of the box $query->clear(); $query->select('ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term)') ->from($db->quoteName('#__finder_tokens_aggregate') . ' AS ta') ->where('ta.term_id = 0'); $db->setQuery($query); $subQuVal = $db->loadObject(); $quRepl_p1 = 'UPDATE ' . $db->quoteName('#__finder_terms') . ' AS ta' . ' SET ' . ' (' . $db->quoteName('term') . ', ' . $db->quoteName('stem') . ', ' . $db->quoteName('common') . ', ' . $db->quoteName('phrase') . ', ' . $db->quoteName('weight') . ', ' . $db->quoteName('soundex') . ')' . ' = ' . ' (' . $db->quote($subQuVal->term) . ', ' . $db->quote($subQuVal->stem) . ', ' . $db->quote($subQuVal->common) . ', ' . $db->quote($subQuVal->phrase) . ', ' . $db->quote($subQuVal->weight) . ', ' . $db->quote($subQuVal->soundex) . ')' . ' WHERE ' . $db->quoteName('term') . ' = ' . $db->quote($subQuVal->term) . ' AND ' . $db->quoteName('stem') . ' = ' . $db->quote($subQuVal->stem) . ' AND ' . $db->quoteName('common') . ' = ' . $db->quote($subQuVal->common) . ' AND ' . $db->quoteName('phrase') . ' = ' . $db->quote($subQuVal->phrase) . ' AND ' . $db->quoteName('weight') . ' = ' . $db->quote($subQuVal->weight) . ' AND ' . $db->quoteName('soundex') . ' = ' . $db->quote($subQuVal->soundex); $db->setQuery($quRepl_p1); $db->query(); $quRepl_p2 = 'INSERT INTO ' . $db->quoteName('#__finder_terms') . ' (' . $db->quoteName('term') . ', ' . $db->quoteName('stem') . ', ' . $db->quoteName('common') . ', ' . $db->quoteName('phrase') . ', ' . $db->quoteName('weight') . ', ' . $db->quoteName('soundex') . ')' . ' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term)' . ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' AS ta' . ' WHERE 1 NOT IN ' . '( SELECT 1 FROM ' . $db->quoteName('#__finder_terms') . ' WHERE ta.term_id = 0 )' . ' AND ta.term_id = 0' . ' GROUP BY ta.term'; $db->setQuery($quRepl_p2); $db->query(); // Check for a database error. if ($db->getErrorNum()) { throw new Exception($db->getErrorMsg(), 500); } } End of failing edit */ //@TODO: PostgreSQL doesn't support INSERT IGNORE INTO //@TODO: PostgreSQL doesn't support SOUNDEX out of the box $db->setQuery( 'INSERT IGNORE INTO ' . $db->quoteName('#__finder_terms') . ' (' . $db->quoteName('term') . ', ' . $db->quoteName('stem') . ', ' . $db->quoteName('common') . ', ' . $db->quoteName('phrase') . ', ' . $db->quoteName('weight') . ', ' . $db->quoteName('soundex') . ')' . ' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term)' . ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' AS ta' . ' WHERE ta.term_id = 0' . ' GROUP BY ta.term' ); $db->query(); // Check for a database error. if ($db->getErrorNum()) { { throw new Exception($db->getErrorMsg(), 500); } } /* * Now, we just inserted a bunch of new records into the terms table * so we need to go back and update the aggregate table with all the * new term ids. */ $query = $db->getQuery(true); $query->update($db->quoteName('#__finder_tokens_aggregate') . ' AS ta'); $query->join('INNER', $db->quoteName('#__finder_terms') . ' AS t ON t.term = ta.term'); $query->set('ta.term_id = t.term_id'); $query->where('ta.term_id = 0'); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Mark afterTerms in the profiler. self::$profiler ? self::$profiler->mark('afterTerms') : null; /* * After we've made sure that all of the terms are in the terms table * and the aggregate table has the correct term ids, we need to update * the links counter for each term by one. */ $query->clear(); $query->update($db->quoteName('#__finder_terms') . ' AS t'); $query->join('INNER', $db->quoteName('#__finder_tokens_aggregate') . ' AS ta ON ta.term_id = t.term_id'); $query->set('t.' . $db->quoteName('links') . ' = t.links + 1'); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Mark afterTerms in the profiler. self::$profiler ? self::$profiler->mark('afterTerms') : null; /* * Before we can insert all of the mapping rows, we have to figure out * which mapping table the rows need to be inserted into. The mapping * table for each term is based on the first character of the md5 of * the first character of the term. In php, it would be expressed as * substr(md5(substr($token, 0, 1)), 0, 1) */ $query->clear(); $query->update($db->quoteName('#__finder_tokens_aggregate')); $query->set($db->quoteName('map_suffix') . ' = SUBSTR(MD5(SUBSTR(' . $db->quoteName('term') . ', 1, 1)), 1, 1)'); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } /* * At this point, the aggregate table contains a record for each * term in each context. So, we're going to pull down all of that * data while grouping the records by term and add all of the * sub-totals together to arrive at the final total for each token for * this link. Then, we insert all of that data into the appropriate * mapping table. */ for ($i = 0; $i <= 15; $i++) { // Get the mapping table suffix. $suffix = dechex($i); /* * We have to run this query 16 times, one for each link => term * mapping table. */ //@TODO: Convert to JDatabaseQuery $db->setQuery( 'INSERT INTO ' . $db->quoteName('#__finder_links_terms' . $suffix) . ' (' . $db->quoteName('link_id') . ', ' . $db->quoteName('term_id') . ', ' . $db->quoteName('weight') . ')' . ' SELECT ' . (int) $linkId . ', ' . $db->quoteName('term_id') . ',' . ' ROUND(SUM(' . $db->quoteName('context_weight') . '), 8)' . ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' WHERE ' . $db->quoteName('map_suffix') . ' = ' . $db->quote($suffix) . ' GROUP BY ' . $db->quoteName('term') . ' ORDER BY ' . $db->quoteName('term') . ' DESC' ); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } } // Mark afterMapping in the profiler. self::$profiler ? self::$profiler->mark('afterMapping') : null; // Update the signature. $query->clear(); $query->update($db->quoteName('#__finder_links')); $query->set($db->quoteName('md5sum') . ' = ' . $db->quote($curSig)); $query->where($db->quoteName('link_id') . ' = ' . $db->quote($linkId)); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Mark afterSigning in the profiler. self::$profiler ? self::$profiler->mark('afterSigning') : null; // Truncate the tokens tables. $db->truncateTable('#__finder_tokens'); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Truncate the tokens aggregate table. $db->truncateTable('#__finder_tokens_aggregate'); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Toggle the token tables back to memory tables. FinderIndexer::toggleTables(true); // Mark afterTruncating in the profiler. self::$profiler ? self::$profiler->mark('afterTruncating') : null; return $linkId; } /** * Method to remove a link from the index. * * @param integer $linkId The id of the link. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ public static function remove($linkId) { $db = JFactory::getDBO(); $query = $db->getQuery(true); // Get the indexer state. $state = FinderIndexer::getState(); // Update the link counts and remove the mapping records. for ($i = 0; $i <= 15; $i++) { // Update the link counts for the terms. $query->update($db->quoteName('#__finder_terms') . ' AS t'); $query->join('INNER', $db->quoteName('#__finder_links_terms' . dechex($i)) . ' AS m ON m.term_id = t.term_id'); $query->set($db->quoteName('t'). '.' . $db->quoteName('links') . ' ='. $db->quoteName('t') .'.' . $db->quoteName('links') . ' - 1'); $query->where($db->quoteName('m') . '.' . $db->quoteName('link_id') . ' = ' . $db->quote((int) $linkId)); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Remove all records from the mapping tables. $query->clear(); $query->delete(); $query->from($db->quoteName('#__finder_links_terms' . dechex($i))); $query->where($db->quoteName('link_id') . ' = ' . (int) $linkId); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } } // Delete all orphaned terms. $query->clear(); $query->delete(); $query->from($db->quoteName('#__finder_terms')); $query->where($db->quoteName('links') . ' <= 0'); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Delete the link from the index. $query->clear(); $query->delete(); $query->from($db->quoteName('#__finder_links')); $query->where($db->quoteName('link_id') . ' = ' . $db->quote((int) $linkId)); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Remove the taxonomy maps. FinderIndexerTaxonomy::removeMaps($linkId); // Remove the orphaned taxonomy nodes. FinderIndexerTaxonomy::removeOrphanNodes(); return true; } /** * Method to optimize the index. We use this method to remove unused terms * and any other optimizations that might be necessary. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ public static function optimize() { // Get the indexer state. $state = FinderIndexer::getState(); // Get the database object. $db = JFactory::getDBO(); $query = $db->getQuery(true); // Delete all orphaned terms. $query->delete(); $query->from($db->quoteName('#__finder_terms')); $query->where($db->quoteName('links') . ' <= 0'); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Optimize the links table. //@TODO: PostgreSQL doesn't support OPTIMIZE TABLE // Temporary workaround for non-MySQL solutions if (strpos($db->name, 'mysql') === 0) { $db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_links')); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } } //@TODO: PostgreSQL doesn't support OPTIMIZE TABLE // Temporary workaround for non-MySQL solutions if (strpos($db->name, 'mysql') === 0) { for ($i = 0; $i <= 15; $i++) { // Optimize the terms mapping table. $db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_links_terms' . dechex($i))); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } } } // Optimize the terms mapping table. //@TODO: PostgreSQL doesn't support OPTIMIZE TABLE // Temporary workaround for non-MySQL solutions if (strpos($db->name, 'mysql') === 0) { $db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_links_terms')); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } } // Remove the orphaned taxonomy nodes. FinderIndexerTaxonomy::removeOrphanNodes(); // Optimize the taxonomy mapping table. //@TODO: PostgreSQL doesn't support OPTIMIZE TABLE // Temporary workaround for non-MySQL solutions if (strpos($db->name, 'mysql') === 0) { $db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_taxonomy_map')); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } } return true; } /** * Method to get a content item's signature. * * @param object $item The content item to index. * * @return string The content item's signature. * * @since 2.5 */ protected static function getSignature($item) { // Get the indexer state. $state = FinderIndexer::getState(); // Get the relevant configuration variables. $config = array(); $config[] = $state->weights; $config[] = $state->options->get('stem', 1); $config[] = $state->options->get('stemmer', 'porter_en'); return md5(serialize(array($item, $config))); } /** * Method to parse input, tokenize it, and then add it to the database. * * @param mixed $input String or resource to use as input. A resource * input will automatically be chunked to conserve * memory. Strings will be chunked if longer than * 2K in size. * @param integer $context The context of the input. See context constants. * @param string $lang The language of the input. * @param string $format The format of the input. * * @return integer The number of tokens extracted from the input. * * @since 2.5 */ protected static function tokenizeToDB($input, $context, $lang, $format) { $count = 0; $buffer = null; // If the input is a resource, batch the process out. if (is_resource($input)) { // Batch the process out to avoid memory limits. while (!feof($input)) { // Read into the buffer. $buffer .= fread($input, 2048); // If we haven't reached the end of the file, seek to the last // space character and drop whatever is after that to make sure // we didn't truncate a term while reading the input. if (!feof($input)) { // Find the last space character. $ls = strrpos($buffer, ' '); // Adjust string based on the last space character. if ($ls) { // Truncate the string to the last space character. $string = substr($buffer, 0, $ls); // Adjust the buffer based on the last space for the // next iteration and trim. $buffer = JString::trim(substr($buffer, $ls)); } // No space character was found. else { $string = $buffer; } } // We've reached the end of the file, so parse whatever remains. else { $string = $buffer; } // Parse the input. $string = FinderIndexerHelper::parse($string, $format); // Check the input. if (empty($string)) { continue; } // Tokenize the input. $tokens = FinderIndexerHelper::tokenize($string, $lang); // Add the tokens to the database. $count += FinderIndexer::addTokensToDB($tokens, $context); // Check if we're approaching the memory limit of the token table. if ($count > self::$state->options->get('memory_table_limit', 30000)) { FinderIndexer::toggleTables(false); } unset($string); unset($tokens); } } // If the input is greater than 2K in size, it is more efficient to // batch out the operation into smaller chunks of work. elseif (strlen($input) > 2048) { $start = 0; $end = strlen($input); $chunk = 2048; // As it turns out, the complex regular expressions we use for // sanitizing input are not very efficient when given large // strings. It is much faster to process lots of short strings. while ($start < $end) { // Setup the string. $string = substr($input, $start, $chunk); // Find the last space character if we aren't at the end. $ls = (($start + $chunk) < $end ? strrpos($string, ' ') : false); // Truncate to the last space character. if ($ls !== false) { $string = substr($string, 0, $ls); } // Adjust the start position for the next iteration. $start += ($ls !== false ? ($ls + 1 - $chunk) + $chunk : $chunk); // Parse the input. $string = FinderIndexerHelper::parse($string, $format); // Check the input. if (empty($string)) { continue; } // Tokenize the input. $tokens = FinderIndexerHelper::tokenize($string, $lang); // Add the tokens to the database. $count += FinderIndexer::addTokensToDB($tokens, $context); // Check if we're approaching the memory limit of the token table. if ($count > self::$state->options->get('memory_table_limit', 30000)) { FinderIndexer::toggleTables(false); } } } else { // Parse the input. $input = FinderIndexerHelper::parse($input, $format); // Check the input. if (empty($input)) { return $count; } // Tokenize the input. $tokens = FinderIndexerHelper::tokenize($input, $lang); // Add the tokens to the database. $count = FinderIndexer::addTokensToDB($tokens, $context); } return $count; } /** * Method to add a set of tokens to the database. * * @param mixed $tokens An array or single FinderIndexerToken object. * @param mixed $context The context of the tokens. See context constants. [optional] * * @return integer The number of tokens inserted into the database. * * @since 2.5 * @throws Exception on database error. */ protected static function addTokensToDB($tokens, $context = '') { // Get the database object. $db = JFactory::getDBO(); $query = $db->getQuery(true); // Force tokens to an array. $tokens = is_array($tokens) ? $tokens : array($tokens); // Count the number of token values. $values = 0; // Iterate through the tokens to create SQL value sets. foreach ($tokens as $token) { $query->values( $db->quote($token->term) . ', ' . $db->quote($token->stem) . ', ' . (int) $token->common . ', ' . (int) $token->phrase . ', ' . (float) $token->weight . ', ' . (int) $context ); $values++; } // Insert the tokens into the database. $query->insert($db->quoteName('#__finder_tokens')); $query->columns( array( $db->quoteName('term'), $db->quoteName('stem'), $db->quoteName('common'), $db->quoteName('phrase'), $db->quoteName('weight'), $db->quoteName('context') ) ); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } return $values; } /** * Method to switch the token tables from Memory tables to MyISAM tables * when they are close to running out of memory. * * @param boolean $memory Flag to control how they should be toggled. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. * @todo PostgreSQL doesn't support setting ENGINEs, determine how to handle setting tables */ protected static function toggleTables($memory) { static $state; // Get the database adapter. $db = JFactory::getDBO(); // Temporary workaround for non-MySQL solutions if (strpos($db->name, 'mysql') !== 0) { return true; } // Check if we are setting the tables to the Memory engine. if ($memory === true && $state !== true) { // Set the tokens table to Memory. $db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens') . ' ENGINE = MEMORY'); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Set the tokens aggregate table to Memory. $db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens_aggregate') . ' ENGINE = MEMORY'); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Set the internal state. $state = $memory; } // We must be setting the tables to the MyISAM engine. elseif ($memory === false && $state !== false) { // Set the tokens table to MyISAM. $db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens') . ' ENGINE = MYISAM'); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Set the tokens aggregate table to MyISAM. $db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens_aggregate') . ' ENGINE = MYISAM'); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Set the internal state. $state = $memory; } return true; } } PK>\߶ɥhelpers/indexer/parser/txt.phpnuW+A\6!helpers/indexer/parser/index.htmlnuW+APK>\) helpers/indexer/parser/.htaccessnuW+A Order allow,deny Deny from all PK>\J\ ,VEEhelpers/indexer/parser/html.phpnuW+A]*>.*?#si', ' ', $input); // Deal with spacing issues in the input. $input = str_replace('>', '> ', $input); $input = str_replace(array(' ', ' '), ' ', $input); $input = trim(preg_replace('#\s+#u', ' ', $input)); // Strip the tags from the input and decode entities. $input = strip_tags($input); $input = html_entity_decode($input, ENT_QUOTES, 'UTF-8'); $input = trim(preg_replace('#\s+#u', ' ', $input)); return $input; } } PK>\8\#'#'%helpers/indexer/stemmer/porter_en.phpnuW+Acache[$lang][$token])) { // Stem the token. $result = $token; $result = self::_step1ab($result); $result = self::_step1c($result); $result = self::_step2($result); $result = self::_step3($result); $result = self::_step4($result); $result = self::_step5($result); // Add the token to the cache. $this->cache[$lang][$token] = $result; } return $this->cache[$lang][$token]; } /** * Step 1 * * @param string $word The token to stem. * * @return string * * @since 2.5 */ private static function _step1ab($word) { // Part a if (substr($word, -1) == 's') { self::_replace($word, 'sses', 'ss') or self::_replace($word, 'ies', 'i') or self::_replace($word, 'ss', 'ss') or self::_replace($word, 's', ''); } // Part b if (substr($word, -2, 1) != 'e' or !self::_replace($word, 'eed', 'ee', 0)) { // First rule $v = self::$_regex_vowel; // ing and ed // Note use of && and OR, for precedence reasons if (preg_match("#$v+#", substr($word, 0, -3)) && self::_replace($word, 'ing', '') or preg_match("#$v+#", substr($word, 0, -2)) && self::_replace($word, 'ed', '')) { // If one of above two test successful if (!self::_replace($word, 'at', 'ate') and !self::_replace($word, 'bl', 'ble') and !self::_replace($word, 'iz', 'ize')) { // Double consonant ending if (self::_doubleConsonant($word) and substr($word, -2) != 'll' and substr($word, -2) != 'ss' and substr($word, -2) != 'zz') { $word = substr($word, 0, -1); } elseif (self::_m($word) == 1 and self::_cvc($word)) { $word .= 'e'; } } } } return $word; } /** * Step 1c * * @param string $word The token to stem. * * @return string * * @since 2.5 */ private static function _step1c($word) { $v = self::$_regex_vowel; if (substr($word, -1) == 'y' && preg_match("#$v+#", substr($word, 0, -1))) { self::_replace($word, 'y', 'i'); } return $word; } /** * Step 2 * * @param string $word The token to stem. * * @return string * * @since 2.5 */ private static function _step2($word) { switch (substr($word, -2, 1)) { case 'a': self::_replace($word, 'ational', 'ate', 0) or self::_replace($word, 'tional', 'tion', 0); break; case 'c': self::_replace($word, 'enci', 'ence', 0) or self::_replace($word, 'anci', 'ance', 0); break; case 'e': self::_replace($word, 'izer', 'ize', 0); break; case 'g': self::_replace($word, 'logi', 'log', 0); break; case 'l': self::_replace($word, 'entli', 'ent', 0) or self::_replace($word, 'ousli', 'ous', 0) or self::_replace($word, 'alli', 'al', 0) or self::_replace($word, 'bli', 'ble', 0) or self::_replace($word, 'eli', 'e', 0); break; case 'o': self::_replace($word, 'ization', 'ize', 0) or self::_replace($word, 'ation', 'ate', 0) or self::_replace($word, 'ator', 'ate', 0); break; case 's': self::_replace($word, 'iveness', 'ive', 0) or self::_replace($word, 'fulness', 'ful', 0) or self::_replace($word, 'ousness', 'ous', 0) or self::_replace($word, 'alism', 'al', 0); break; case 't': self::_replace($word, 'biliti', 'ble', 0) or self::_replace($word, 'aliti', 'al', 0) or self::_replace($word, 'iviti', 'ive', 0); break; } return $word; } /** * Step 3 * * @param string $word The token to stem. * * @return string * * @since 2.5 */ private static function _step3($word) { switch (substr($word, -2, 1)) { case 'a': self::_replace($word, 'ical', 'ic', 0); break; case 's': self::_replace($word, 'ness', '', 0); break; case 't': self::_replace($word, 'icate', 'ic', 0) or self::_replace($word, 'iciti', 'ic', 0); break; case 'u': self::_replace($word, 'ful', '', 0); break; case 'v': self::_replace($word, 'ative', '', 0); break; case 'z': self::_replace($word, 'alize', 'al', 0); break; } return $word; } /** * Step 4 * * @param string $word The token to stem. * * @return string * * @since 2.5 */ private static function _step4($word) { switch (substr($word, -2, 1)) { case 'a': self::_replace($word, 'al', '', 1); break; case 'c': self::_replace($word, 'ance', '', 1) or self::_replace($word, 'ence', '', 1); break; case 'e': self::_replace($word, 'er', '', 1); break; case 'i': self::_replace($word, 'ic', '', 1); break; case 'l': self::_replace($word, 'able', '', 1) or self::_replace($word, 'ible', '', 1); break; case 'n': self::_replace($word, 'ant', '', 1) or self::_replace($word, 'ement', '', 1) or self::_replace($word, 'ment', '', 1) or self::_replace($word, 'ent', '', 1); break; case 'o': if (substr($word, -4) == 'tion' or substr($word, -4) == 'sion') { self::_replace($word, 'ion', '', 1); } else { self::_replace($word, 'ou', '', 1); } break; case 's': self::_replace($word, 'ism', '', 1); break; case 't': self::_replace($word, 'ate', '', 1) or self::_replace($word, 'iti', '', 1); break; case 'u': self::_replace($word, 'ous', '', 1); break; case 'v': self::_replace($word, 'ive', '', 1); break; case 'z': self::_replace($word, 'ize', '', 1); break; } return $word; } /** * Step 5 * * @param string $word The token to stem. * * @return string * * @since 2.5 */ private static function _step5($word) { // Part a if (substr($word, -1) == 'e') { if (self::_m(substr($word, 0, -1)) > 1) { self::_replace($word, 'e', ''); } elseif (self::_m(substr($word, 0, -1)) == 1) { if (!self::_cvc(substr($word, 0, -1))) { self::_replace($word, 'e', ''); } } } // Part b if (self::_m($word) > 1 and self::_doubleConsonant($word) and substr($word, -1) == 'l') { $word = substr($word, 0, -1); } return $word; } /** * Replaces the first string with the second, at the end of the string. If third * arg is given, then the preceding string must match that m count at least. * * @param string &$str String to check * @param string $check Ending to check for * @param string $repl Replacement string * @param integer $m Optional minimum number of m() to meet * * @return boolean Whether the $check string was at the end * of the $str string. True does not necessarily mean * that it was replaced. * * @since 2.5 */ private static function _replace(&$str, $check, $repl, $m = null) { $len = 0 - strlen($check); if (substr($str, $len) == $check) { $substr = substr($str, 0, $len); if (is_null($m) or self::_m($substr) > $m) { $str = $substr . $repl; } return true; } return false; } /** * m() measures the number of consonant sequences in $str. if c is * a consonant sequence and v a vowel sequence, and <..> indicates arbitrary * presence, * * gives 0 * vc gives 1 * vcvc gives 2 * vcvcvc gives 3 * * @param string $str The string to return the m count for * * @return integer The m count * * @since 2.5 */ private static function _m($str) { $c = self::$_regex_consonant; $v = self::$_regex_vowel; $str = preg_replace("#^$c+#", '', $str); $str = preg_replace("#$v+$#", '', $str); preg_match_all("#($v+$c+)#", $str, $matches); return count($matches[1]); } /** * Returns true/false as to whether the given string contains two * of the same consonant next to each other at the end of the string. * * @param string $str String to check * * @return boolean Result * * @since 2.5 */ private static function _doubleConsonant($str) { $c = self::$_regex_consonant; return preg_match("#$c{2}$#", $str, $matches) and $matches[0]{0} == $matches[0]{1}; } /** * Checks for ending CVC sequence where second C is not W, X or Y * * @param string $str String to check * * @return boolean Result * * @since 2.5 */ private static function _cvc($str) { $c = self::$_regex_consonant; $v = self::$_regex_vowel; return preg_match("#($c$v$c)$#", $str, $matches) and strlen($matches[1]) == 3 and $matches[1]{2} != 'w' and $matches[1]{2} != 'x' and $matches[1]{2} != 'y'; } } PK>\6"helpers/indexer/stemmer/index.htmlnuW+APK>\ $helpers/indexer/stemmer/snowball.phpnuW+Asef) ? $languages[0]->sef : '*'; $lang = $defaultLang; } // Stem the token if it is not in the cache. if (!isset($this->cache[$lang][$token])) { // Get the stem function from the language string. switch ($lang) { // Danish stemmer. case 'da': $function = 'stem_danish'; break; // German stemmer. case 'de': $function = 'stem_german'; break; // English stemmer. default: case 'en': $function = 'stem_english'; break; // Spanish stemmer. case 'es': $function = 'stem_spanish'; break; // Finnish stemmer. case 'fi': $function = 'stem_finnish'; break; // French stemmer. case 'fr': $function = 'stem_french'; break; // Hungarian stemmer. case 'hu': $function = 'stem_hungarian'; break; // Italian stemmer. case 'it': $function = 'stem_italian'; break; // Norwegian stemmer. case 'nb': $function = 'stem_norwegian'; break; // Dutch stemmer. case 'nl': $function = 'stem_dutch'; break; // Portuguese stemmer. case 'pt': $function = 'stem_portuguese'; break; // Romanian stemmer. case 'ro': $function = 'stem_romanian'; break; // Russian stemmer. case 'ru': $function = 'stem_russian_unicode'; break; // Swedish stemmer. case 'sv': $function = 'stem_swedish'; break; // Turkish stemmer. case 'tr': $function = 'stem_turkish_unicode'; break; } // Stem the word if the stemmer method exists. $this->cache[$lang][$token] = function_exists($function) ? $function($token) : $token; } return $this->cache[$lang][$token]; } } PK>\)!helpers/indexer/stemmer/.htaccessnuW+A Order allow,deny Deny from all PK>\helpers/indexer/stemmer.phpnuW+Aclean($adapter, 'cmd'); $path = dirname(__FILE__) . '/stemmer/' . $adapter . '.php'; $class = 'FinderIndexerStemmer' . ucfirst($adapter); // Check if a stemmer exists for the adapter. if (file_exists($path)) { // Instantiate the stemmer. include_once $path; $instances[$adapter] = new $class; } else { // Throw invalid adapter exception. throw new Exception(JText::sprintf('COM_FINDER_INDEXER_INVALID_STEMMER', $adapter)); } return $instances[$adapter]; } /** * Method to stem a token and return the root. * * @param string $token The token to stem. * @param string $lang The language of the token. * * @return string The root token. * * @since 2.5 */ abstract public function stem($token, $lang); } PK>\HV helpers/indexer/token.phpnuW+Aterm = implode($spacer, $term); $this->stem = implode($spacer, array_map(array('FinderIndexerHelper', 'stem'), $term, array($lang))); $this->numeric = false; $this->common = false; $this->phrase = true; $this->length = JString::strlen($this->term); /* * Calculate the weight of the token. * * 1. Length of the token up to 30 and divide by 30, add 1. * 2. Round weight to 4 decimal points. */ $this->weight = (($this->length >= 30 ? 30 : $this->length) / 30) + 1; $this->weight = round($this->weight, 4); } else { // Populate the token instance. $this->term = $term; $this->stem = FinderIndexerHelper::stem($this->term, $lang); $this->numeric = (is_numeric($this->term) || (bool) preg_match('#^[0-9,.\-\+]+$#', $this->term)); $this->common = $this->numeric ? false : FinderIndexerHelper::isCommon($this->term, $lang); $this->phrase = false; $this->length = JString::strlen($this->term); /* * Calculate the weight of the token. * * 1. Length of the token up to 15 and divide by 15. * 2. If common term, divide weight by 8. * 3. If numeric, multiply weight by 1.5. * 4. Round weight to 4 decimal points. */ $this->weight = (($this->length >= 15 ? 15 : $this->length) / 15); $this->weight = ($this->common == true ? $this->weight / 8 : $this->weight); $this->weight = ($this->numeric == true ? $this->weight * 1.5 : $this->weight); $this->weight = round($this->weight, 4); } } } PK>\ehelpers/indexer/query.phpnuW+Ainput = isset($options['input']) ? $options['input'] : null; // Get the empty query setting. $this->empty = isset($options['empty']) ? (bool) $options['empty'] : false; // Get the input language. $this->language = !empty($options['language']) ? $options['language'] : FinderIndexerHelper::getDefaultLanguage(); $this->language = FinderIndexerHelper::getPrimaryLanguage($this->language); // Get the matching mode. $this->mode = 'AND'; // Initialize the temporary date storage. $this->dates = new JRegistry; // Populate the temporary date storage. if (isset($options['date1']) && !empty($options['date1'])) { $this->dates->set('date1', $options['date1']); } if (isset($options['date2']) && !empty($options['date1'])) { $this->dates->set('date2', $options['date2']); } if (isset($options['when1']) && !empty($options['date1'])) { $this->dates->set('when1', $options['when1']); } if (isset($options['when2']) && !empty($options['date1'])) { $this->dates->set('when2', $options['when2']); } // Process the static taxonomy filters. if (isset($options['filter']) && !empty($options['filter'])) { $this->processStaticTaxonomy($options['filter']); } // Process the dynamic taxonomy filters. if (isset($options['filters']) && !empty($options['filters'])) { $this->processDynamicTaxonomy($options['filters']); } // Get the date filters. $d1 = $this->dates->get('date1'); $d2 = $this->dates->get('date2'); $w1 = $this->dates->get('when1'); $w2 = $this->dates->get('when2'); // Process the date filters. if (!empty($d1) || !empty($d2)) { $this->processDates($d1, $d2, $w1, $w2); } // Process the input string. $this->processString($this->input, $this->language, $this->mode); // Get the number of matching terms. foreach ($this->included as $token) { $this->terms += count($token->matches); } // Remove the temporary date storage. unset($this->dates); /* * Lastly, determine whether this query can return a result set. */ // Check if we have a query string. if (!empty($this->input)) { $this->search = true; } // Check if we can search without a query string. elseif ($this->empty && (!empty($this->filter) || !empty($this->filters) || !empty($this->date1) || !empty($this->date2))) { $this->search = true; } // We do not have a valid search query. else { $this->search = false; } } /** * Method to convert the query object into a URI string. * * @param string $base The base URI. [optional] * * @return string The complete query URI. * * @since 2.5 */ public function toURI($base = null) { // Set the base if not specified. if (empty($base)) { $base = 'index.php?option=com_finder&view=search'; } // Get the base URI. $uri = JURI::getInstance($base); // Add the static taxonomy filter if present. if (!empty($this->filter)) { $uri->setVar('f', $this->filter); } // Get the filters in the request. $input = JFactory::getApplication()->input; $t = $input->request->get('t', array(), 'array'); // Add the dynamic taxonomy filters if present. if (!empty($this->filters)) { foreach ($this->filters as $nodes) { foreach ($nodes as $node) { if (!in_array($node, $t)) { continue; } $uri->setVar('t[]', $node); } } } // Add the input string if present. if (!empty($this->input)) { $uri->setVar('q', $this->input); } // Add the start date if present. if (!empty($this->date1)) { $uri->setVar('d1', $this->date1); } // Add the end date if present. if (!empty($this->date2)) { $uri->setVar('d2', $this->date2); } // Add the start date modifier if present. if (!empty($this->when1)) { $uri->setVar('w1', $this->when1); } // Add the end date modifier if present. if (!empty($this->when2)) { $uri->setVar('w2', $this->when2); } // Add a menu item id if one is not present. if (!$uri->getVar('Itemid')) { // Get the menu item id. $query = array( 'view' => $uri->getVar('view'), 'f' => $uri->getVar('f'), 'q' => $uri->getVar('q') ); $item = FinderHelperRoute::getItemid($query); // Add the menu item id if present. if ($item !== null) { $uri->setVar('Itemid', $item); } } return $uri->toString(array('path', 'query')); } /** * Method to get a list of excluded search term ids. * * @return array An array of excluded term ids. * * @since 2.5 */ public function getExcludedTermIds() { $results = array(); // Iterate through the excluded tokens and compile the matching terms. for ($i = 0, $c = count($this->excluded); $i < $c; $i++) { $results = array_merge($results, $this->excluded[$i]->matches); } // Sanitize the terms. //@TODO: Should toInteger use $return? $return = array_unique($results); JArrayHelper::toInteger($results); return $results; } /** * Method to get a list of included search term ids. * * @return array An array of included term ids. * * @since 2.5 */ public function getIncludedTermIds() { $results = array(); // Iterate through the included tokens and compile the matching terms. for ($i = 0, $c = count($this->included); $i < $c; $i++) { // Check if we have any terms. if (empty($this->included[$i]->matches)) { continue; } // Get the term. $term = $this->included[$i]->term; // Prepare the container for the term if necessary. if (!array_key_exists($term, $results)) { $results[$term] = array(); } // Add the matches to the stack. $results[$term] = array_merge($results[$term], $this->included[$i]->matches); } // Sanitize the terms. foreach ($results as $key => $value) { $results[$key] = array_unique($results[$key]); JArrayHelper::toInteger($results[$key]); } return $results; } /** * Method to get a list of required search term ids. * * @return array An array of required term ids. * * @since 2.5 */ public function getRequiredTermIds() { $results = array(); // Iterate through the included tokens and compile the matching terms. for ($i = 0, $c = count($this->included); $i < $c; $i++) { // Check if the token is required. if ($this->included[$i]->required) { // Get the term. $term = $this->included[$i]->term; // Prepare the container for the term if necessary. if (!array_key_exists($term, $results)) { $results[$term] = array(); } // Add the matches to the stack. $results[$term] = array_merge($results[$term], $this->included[$i]->matches); } } // Sanitize the terms. foreach ($results as $key => $value) { $results[$key] = array_unique($results[$key]); JArrayHelper::toInteger($results[$key]); } return $results; } /** * Method to process the static taxonomy input. The static taxonomy input * comes in the form of a pre-defined search filter that is assigned to the * search form. * * @param integer $filterId The id of static filter. * * @return boolean True on success, false on failure. * * @since 2.5 * @throws Exception on database error. */ protected function processStaticTaxonomy($filterId) { // Get the database object. $db = JFactory::getDBO(); // Initialize user variables $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); // Load the predefined filter. $query = $db->getQuery(true); $query->select('f.' . $db->quoteName('data') . ', f.' . $db->quoteName('params')); $query->from($db->quoteName('#__finder_filters') . ' AS f'); $query->where('f.' . $db->quoteName('filter_id') . ' = ' . (int) $filterId); $db->setQuery($query); $return = $db->loadObject(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Check the returned filter. if (empty($return)) { return false; } // Set the filter. $this->filter = (int) $filterId; // Get a parameter object for the filter date options. $registry = new JRegistry; $registry->loadString($return->params); $params = $registry; // Set the dates if not already set. $this->dates->def('date1', $params->get('d1')); $this->dates->def('date2', $params->get('d2')); $this->dates->def('when1', $params->get('w1')); $this->dates->def('when2', $params->get('w2')); // Remove duplicates and sanitize. $filters = explode(',', $return->data); $filters = array_unique($filters); JArrayHelper::toInteger($filters); // Remove any values of zero. if (array_search(0, $filters, true) !== false) { unset($filters[array_search(0, $filters, true)]); } // Check if we have any real input. if (empty($filters)) { return true; } /* * Create the query to get filters from the database. We do this for * two reasons: one, it allows us to ensure that the filters being used * are real; two, we need to sort the filters by taxonomy branch. */ $query->clear(); $query->select('t1.id, t1.title, t2.title AS branch'); $query->from($db->quoteName('#__finder_taxonomy') . ' AS t1'); $query->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id'); $query->where('t1.state = 1'); $query->where('t1.' . $db->quoteName('access') . ' IN (' . $groups . ')'); $query->where('t1.id IN (' . implode(',', $filters) . ')'); $query->where('t2.state = 1'); $query->where('t2.' . $db->quoteName('access') . ' IN (' . $groups . ')'); // Load the filters. $db->setQuery($query); $results = $db->loadObjectList(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Sort the filter ids by branch. foreach ($results as $result) { $this->filters[$result->branch][$result->title] = (int) $result->id; } return true; } /** * Method to process the dynamic taxonomy input. The dynamic taxonomy input * comes in the form of select fields that the user chooses from. The * dynamic taxonomy input is processed AFTER the static taxonomy input * because the dynamic options can be used to further narrow a static * taxonomy filter. * * @param array $filters An array of taxonomy node ids. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ protected function processDynamicTaxonomy($filters) { // Initialize user variables $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); // Remove duplicates and sanitize. $filters = array_unique($filters); JArrayHelper::toInteger($filters); // Remove any values of zero. if (array_search(0, $filters, true) !== false) { unset($filters[array_search(0, $filters, true)]); } // Check if we have any real input. if (empty($filters)) { return true; } // Get the database object. $db = JFactory::getDBO(); $query = $db->getQuery(true); /* * Create the query to get filters from the database. We do this for * two reasons: one, it allows us to ensure that the filters being used * are real; two, we need to sort the filters by taxonomy branch. */ $query->select('t1.id, t1.title, t2.title AS branch'); $query->from($db->quoteName('#__finder_taxonomy') . ' AS t1'); $query->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id'); $query->where('t1.state = 1'); $query->where('t1.' . $db->quoteName('access') . ' IN (' . $groups . ')'); $query->where('t1.id IN (' . implode(',', $filters) . ')'); $query->where('t2.state = 1'); $query->where('t2.' . $db->quoteName('access') . ' IN (' . $groups . ')'); // Load the filters. $db->setQuery($query); $results = $db->loadObjectList(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Cleared filter branches. $cleared = array(); /* * Sort the filter ids by branch. Because these filters are designed to * override and further narrow the items selected in the static filter, * we will clear the values from the static filter on a branch by * branch basis before adding the dynamic filters. So, if the static * filter defines a type filter of "articles" and three "category" * filters but the user only limits the category further, the category * filters will be flushed but the type filters will not. */ foreach ($results as $result) { // Check if the branch has been cleared. if (!in_array($result->branch, $cleared)) { // Clear the branch. $this->filters[$result->branch] = array(); // Add the branch to the cleared list. $cleared[] = $result->branch; } // Add the filter to the list. $this->filters[$result->branch][$result->title] = (int) $result->id; } return true; } /** * Method to process the query date filters to determine start and end * date limitations. * * @param string $date1 The first date filter. * @param string $date2 The second date filter. * @param string $when1 The first date modifier. * @param string $when2 The second date modifier. * * @return boolean True on success. * * @since 2.5 */ protected function processDates($date1, $date2, $when1, $when2) { // Clean up the inputs. $date1 = JString::trim(JString::strtolower($date1)); $date2 = JString::trim(JString::strtolower($date2)); $when1 = JString::trim(JString::strtolower($when1)); $when2 = JString::trim(JString::strtolower($when2)); // Get the time offset. $offset = JFactory::getApplication()->getCfg('offset'); // Array of allowed when values. $whens = array('before', 'after', 'exact'); // The value of 'today' is a special case that we need to handle. if ($date1 === JString::strtolower(JText::_('COM_FINDER_QUERY_FILTER_TODAY'))) { $today = JFactory::getDate('now', $offset); $date1 = $today->format('%Y-%m-%d'); } // Try to parse the date string. $date = JFactory::getDate($date1, $offset); // Check if the date was parsed successfully. if ($date->toUnix() !== null) { // Set the date filter. $this->date1 = $date->toSQL(); $this->when1 = in_array($when1, $whens) ? $when1 : 'before'; } // The value of 'today' is a special case that we need to handle. if ($date2 === JString::strtolower(JText::_('COM_FINDER_QUERY_FILTER_TODAY'))) { $today = JFactory::getDate('now', $offset); $date2 = $today->format('%Y-%m-%d'); } // Try to parse the date string. $date = JFactory::getDate($date2, $offset); // Check if the date was parsed successfully. if ($date->toUnix() !== null) { // Set the date filter. $this->date2 = $date->toSQL(); $this->when2 = in_array($when2, $whens) ? $when2 : 'before'; } return true; } /** * Method to process the query input string and extract required, optional, * and excluded tokens; taxonomy filters; and date filters. * * @param string $input The query input string. * @param string $lang The query input language. * @param string $mode The query matching mode. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ protected function processString($input, $lang, $mode) { // Clean up the input string. $input = html_entity_decode($input, ENT_QUOTES, 'UTF-8'); $input = JString::strtolower($input); $input = preg_replace('#\s+#mi', ' ', $input); $input = JString::trim($input); $debug = JFactory::getConfig()->get('debug_lang'); /* * First, we need to handle string based modifiers. String based * modifiers could potentially include things like "category:blah" or * "before:2009-10-21" or "type:article", etc. */ $patterns = array( 'before' => JText::_('COM_FINDER_FILTER_WHEN_BEFORE'), 'after' => JText::_('COM_FINDER_FILTER_WHEN_AFTER') ); // Add the taxonomy branch titles to the possible patterns. foreach (FinderIndexerTaxonomy::getBranchTitles() as $branch) { // Add the pattern. $patterns[$branch] = JString::strtolower(JText::_(FinderHelperLanguage::branchSingular($branch))); } // Container for search terms and phrases. $terms = array(); $phrases = array(); // Cleared filter branches. $cleared = array(); /* * Compile the suffix pattern. This is used to match the values of the * filter input string. Single words can be input directly, multi-word * values have to be wrapped in double quotes. */ $quotes = html_entity_decode('‘’'', ENT_QUOTES, 'UTF-8'); $suffix = '(([\w\d' . $quotes . '-]+)|\"([\w\d\s' . $quotes . '-]+)\")'; /* * Iterate through the possible filter patterns and search for matches. * We need to match the key, colon, and a value pattern for the match * to be valid. */ foreach ($patterns as $modifier => $pattern) { $matches = array(); if ($debug) { $pattern = substr($pattern, 2, -2); } // Check if the filter pattern is in the input string. if (preg_match('#' . $pattern . '\s*:\s*' . $suffix . '#mi', $input, $matches)) { // Get the value given to the modifier. $value = isset($matches[3]) ? $matches[3] : $matches[1]; // Now we have to handle the filter string. switch ($modifier) { // Handle a before and after date filters. case 'before': case 'after': { // Get the time offset. $offset = JFactory::getApplication()->getCfg('offset'); // Array of allowed when values. $whens = array('before', 'after', 'exact'); // The value of 'today' is a special case that we need to handle. if ($value === JString::strtolower(JText::_('COM_FINDER_QUERY_FILTER_TODAY'))) { $today = JFactory::getDate('now', $offset); $value = $today->format('%Y-%m-%d'); } // Try to parse the date string. $date = JFactory::getDate($value, $offset); // Check if the date was parsed successfully. if ($date->toUnix() !== null) { // Set the date filter. $this->date1 = $date->toSQL(); $this->when1 = in_array($modifier, $whens) ? $modifier : 'before'; } break; } // Handle a taxonomy branch filter. default: { // Try to find the node id. $return = FinderIndexerTaxonomy::getNodeByTitle($modifier, $value); // Check if the node id was found. if ($return) { // Check if the branch has been cleared. if (!in_array($modifier, $cleared)) { // Clear the branch. $this->filters[$modifier] = array(); // Add the branch to the cleared list. $cleared[] = $modifier; } // Add the filter to the list. $this->filters[$modifier][$return->title] = (int) $return->id; } break; } } // Clean up the input string again. $input = str_replace($matches[0], '', $input); $input = preg_replace('#\s+#mi', ' ', $input); $input = JString::trim($input); } } /* * Extract the tokens enclosed in double quotes so that we can handle * them as phrases. */ if (JString::strpos($input, '"') !== false) { $matches = array(); // Extract the tokens enclosed in double quotes. if (preg_match_all('#\"([^"]+)\"#mi', $input, $matches)) { /* * One or more phrases were found so we need to iterate through * them, tokenize them as phrases, and remove them from the raw * input string before we move on to the next processing step. */ foreach ($matches[1] as $key => $match) { // Find the complete phrase in the input string. $pos = JString::strpos($input, $matches[0][$key]); $len = JString::strlen($matches[0][$key]); // Add any terms that are before this phrase to the stack. if (JString::trim(JString::substr($input, 0, $pos))) { $terms = array_merge($terms, explode(' ', JString::trim(JString::substr($input, 0, $pos)))); } // Strip out everything up to and including the phrase. $input = JString::substr($input, $pos + $len); // Clean up the input string again. $input = preg_replace('#\s+#mi', ' ', $input); $input = JString::trim($input); // Get the number of words in the phrase. $parts = explode(' ', $match); // Check if the phrase is longer than three words. if (count($parts) > 3) { /* * If the phrase is longer than three words, we need to * break it down into smaller chunks of phrases that * are less than or equal to three words. We overlap * the chunks so that we can ensure that a match is * found for the complete phrase and not just portions * of it. */ for ($i = 0, $c = count($parts); $i < $c; $i += 2) { // Set up the chunk. $chunk = array(); // The chunk has to be assembled based on how many // pieces are available to use. switch ($c - $i) { // If only one word is left, we can break from // the switch and loop because the last word // was already used at the end of the last // chunk. case 1: break 2; // If there words are left, we use them both as // the last chunk of the phrase and we're done. case 2: $chunk[] = $parts[$i]; $chunk[] = $parts[$i + 1]; break; // If there are three or more words left, we // build a three word chunk and continue on. default: $chunk[] = $parts[$i]; $chunk[] = $parts[$i + 1]; $chunk[] = $parts[$i + 2]; break; } // If the chunk is not empty, add it as a phrase. if (count($chunk)) { $phrases[] = implode(' ', $chunk); $terms[] = implode(' ', $chunk); } } } else { // The phrase is <= 3 words so we can use it as is. $phrases[] = $match; $terms[] = $match; } } } } // Add the remaining terms if present. if (!empty($input)) { $terms = array_merge($terms, explode(' ', $input)); } // An array of our boolean operators. $operator => $translation $operators = array( 'AND' => JString::strtolower(JText::_('COM_FINDER_QUERY_OPERATOR_AND')), 'OR' => JString::strtolower(JText::_('COM_FINDER_QUERY_OPERATOR_OR')), 'NOT' => JString::strtolower(JText::_('COM_FINDER_QUERY_OPERATOR_NOT')) ); // If language debugging is enabled you need to ignore the debug strings in matching. if (JDEBUG) { $debugStrings = array('**', '??'); $operators = str_replace($debugStrings, '', $operators); } /* * Iterate through the terms and perform any sorting that needs to be * done based on boolean search operators. Terms that are before an * and/or/not modifier have to be handled in relation to their operator. */ for ($i = 0, $c = count($terms); $i < $c; $i++) { // Check if the term is followed by an operator that we understand. if (isset($terms[$i + 1]) && in_array($terms[$i + 1], $operators)) { // Get the operator mode. $op = array_search($terms[$i + 1], $operators); // Handle the AND operator. if ($op === 'AND' && isset($terms[$i + 2])) { // Tokenize the current term. $token = FinderIndexerHelper::tokenize($terms[$i], $lang, true); $token = $this->getTokenData($token); // Set the required flag. $token->required = true; // Add the current token to the stack. $this->included[] = $token; $this->highlight = array_merge($this->highlight, array_keys($token->matches)); // Skip the next token (the mode operator). $this->operators[] = $terms[$i + 1]; // Tokenize the term after the next term (current plus two). $other = FinderIndexerHelper::tokenize($terms[$i + 2], $lang, true); $other = $this->getTokenData($other); // Set the required flag. $other->required = true; // Add the token after the next token to the stack. $this->included[] = $other; $this->highlight = array_merge($this->highlight, array_keys($other->matches)); // Remove the processed phrases if possible. if (($pk = array_search($terms[$i], $phrases)) !== false) { unset($phrases[$pk]); } if (($pk = array_search($terms[$i + 2], $phrases)) !== false) { unset($phrases[$pk]); } // Remove the processed terms. unset($terms[$i]); unset($terms[$i + 1]); unset($terms[$i + 2]); // Adjust the loop. $i += 2; continue; } // Handle the OR operator. elseif ($op === 'OR' && isset($terms[$i + 2])) { // Tokenize the current term. $token = FinderIndexerHelper::tokenize($terms[$i], $lang, true); $token = $this->getTokenData($token); // Set the required flag. $token->required = false; // Add the current token to the stack. if (count($token->matches)) { $this->included[] = $token; $this->highlight = array_merge($this->highlight, array_keys($token->matches)); } else { $this->ignored[] = $token; } // Skip the next token (the mode operator). $this->operators[] = $terms[$i + 1]; // Tokenize the term after the next term (current plus two). $other = FinderIndexerHelper::tokenize($terms[$i + 2], $lang, true); $other = $this->getTokenData($other); // Set the required flag. $other->required = false; // Add the token after the next token to the stack. if (count($other->matches)) { $this->included[] = $other; $this->highlight = array_merge($this->highlight, array_keys($other->matches)); } else { $this->ignored[] = $other; } // Remove the processed phrases if possible. if (($pk = array_search($terms[$i], $phrases)) !== false) { unset($phrases[$pk]); } if (($pk = array_search($terms[$i + 2], $phrases)) !== false) { unset($phrases[$pk]); } // Remove the processed terms. unset($terms[$i]); unset($terms[$i + 1]); unset($terms[$i + 2]); // Adjust the loop. $i += 2; continue; } } // Handle an orphaned OR operator. elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators) === 'OR') { // Skip the next token (the mode operator). $this->operators[] = $terms[$i]; // Tokenize the next term (current plus one). $other = FinderIndexerHelper::tokenize($terms[$i + 1], $lang, true); $other = $this->getTokenData($other); // Set the required flag. $other->required = false; // Add the token after the next token to the stack. if (count($other->matches)) { $this->included[] = $other; $this->highlight = array_merge($this->highlight, array_keys($other->matches)); } else { $this->ignored[] = $other; } // Remove the processed phrase if possible. if (($pk = array_search($terms[$i + 1], $phrases)) !== false) { unset($phrases[$pk]); } // Remove the processed terms. unset($terms[$i]); unset($terms[$i + 1]); // Adjust the loop. $i += 1; continue; } // Handle the NOT operator. elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators) === 'NOT') { // Skip the next token (the mode operator). $this->operators[] = $terms[$i]; // Tokenize the next term (current plus one). $other = FinderIndexerHelper::tokenize($terms[$i + 1], $lang, true); $other = $this->getTokenData($other); // Set the required flag. $other->required = false; // Add the next token to the stack. if (count($other->matches)) { $this->excluded[] = $other; } else { $this->ignored[] = $other; } // Remove the processed phrase if possible. if (($pk = array_search($terms[$i + 1], $phrases)) !== false) { unset($phrases[$pk]); } // Remove the processed terms. unset($terms[$i]); unset($terms[$i + 1]); // Adjust the loop. $i += 1; continue; } } /* * Iterate through any search phrases and tokenize them. We handle * phrases as autonomous units and do not break them down into two and * three word combinations. */ for ($i = 0, $c = count($phrases); $i < $c; $i++) { // Tokenize the phrase. $token = FinderIndexerHelper::tokenize($phrases[$i], $lang, true); $token = $this->getTokenData($token); // Set the required flag. $token->required = true; // Add the current token to the stack. $this->included[] = $token; $this->highlight = array_merge($this->highlight, array_keys($token->matches)); // Remove the processed term if possible. if (($pk = array_search($phrases[$i], $terms)) !== false) { unset($terms[$pk]); } // Remove the processed phrase. unset($phrases[$i]); } /* * Handle any remaining tokens using the standard processing mechanism. */ if (!empty($terms)) { // Tokenize the terms. $terms = implode(' ', $terms); $tokens = FinderIndexerHelper::tokenize($terms, $lang, false); // Make sure we are working with an array. $tokens = is_array($tokens) ? $tokens : array($tokens); // Get the token data and required state for all the tokens. foreach ($tokens as $token) { // Get the token data. $token = $this->getTokenData($token); // Set the required flag for the token. $token->required = $mode === 'AND' ? ($token->phrase ? false : true) : false; // Add the token to the appropriate stack. if (count($token->matches) || $token->required) { $this->included[] = $token; $this->highlight = array_merge($this->highlight, array_keys($token->matches)); } else { $this->ignored[] = $token; } } } return true; } /** * Method to get the base and similar term ids and, if necessary, suggested * term data from the database. The terms ids are identified based on a * 'like' match in MySQL and/or a common stem. If no term ids could be * found, then we know that we will not be able to return any results for * that term and we should try to find a similar term to use that we can * match so that we can suggest the alternative search query to the user. * * @param FinderIndexerToken $token A FinderIndexerToken object. * * @return FinderIndexerToken A FinderIndexerToken object. * * @since 2.5 * @throws Exception on database error. */ protected function getTokenData($token) { // Get the database object. $db = JFactory::getDBO(); // Create a database query to build match the token. $query = $db->getQuery(true); $query->select('t.term, t.term_id'); $query->from('#__finder_terms AS t'); /* * If the token is a phrase, the lookup process is fairly simple. If * the token is a word, it is a little more complicated. We have to * create two queries to lookup the term and the stem respectively, * then union the result sets together. This is MUCH faster than using * an or condition in the database query. */ if ($token->phrase) { // Add the phrase to the query. $query->where('t.term = ' . $db->quote($token->term)); $query->where('t.phrase = 1'); } else { // Add the term to the query. $query->where('t.term = ' . $db->quote($token->term)); $query->where('t.phrase = 0'); // Clone the query, replace the WHERE clause. $sub = clone($query); $sub->clear('where'); $sub->where('t.stem = '.$db->quote($token->stem)); $sub->where('t.phrase = 0'); // Union the two queries. $query->union($sub); // $query->where('(t.term = ' . $db->quote($token->term) . ' OR t.stem = ' . $db->quote($token->stem) . ')'); // $query->where('t.phrase = 0'); } // Get the terms. $db->setQuery($query); $matches = $db->loadObjectList(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Setup the container. $token->matches = array(); // Check the matching terms. if (!empty($matches)) { // Add the matches to the token. for ($i = 0, $c = count($matches); $i < $c; $i++) { $token->matches[$matches[$i]->term] = (int) $matches[$i]->term_id; } } // If no matches were found, try to find a similar but better token. if (empty($token->matches)) { // Create a database query to get the similar terms. //@TODO: PostgreSQL doesn't support SOUNDEX out of the box $query->clear(); $query->select('DISTINCT t.term_id AS id, t.term AS term'); $query->from('#__finder_terms AS t'); //$query->where('t.soundex = ' . soundex($db->quote($token->term))); $query->where('t.soundex = SOUNDEX(' . $db->quote($token->term) . ')'); $query->where('t.phrase = ' . (int) $token->phrase); // Get the terms. $db->setQuery($query); $results = $db->loadObjectList(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Check if any similar terms were found. if (empty($results)) { return $token; } // Stack for sorting the similar terms. $suggestions = array(); // Get the levnshtein distance for all suggested terms. foreach ($results as $sk => $st) { // Get the levenshtein distance between terms. $distance = levenshtein($st->term, $token->term); // Make sure the levenshtein distance isn't over 50. if ($distance < 50) { $suggestions[$sk] = $distance; } } // Sort the suggestions. asort($suggestions, SORT_NUMERIC); // Get the closest match. $keys = array_keys($suggestions); $key = $keys[0]; // Add the suggested term. $token->suggestion = $results[$key]->term; } return $token; } } PK>\|/^/^helpers/indexer/adapter.phpnuW+Adb = JFactory::getDBO(); // Call the parent constructor. parent::__construct($subject, $config); // Get the type id. $this->type_id = $this->getTypeId(); // Add the content type if it doesn't exist and is set. if (empty($this->type_id) && !empty($this->type_title)) { $this->type_id = FinderIndexerHelper::addContentType($this->type_title, $this->mime); } // Check for a layout override. if ($this->params->get('layout')) { $this->layout = $this->params->get('layout'); } } /** * Method to get the adapter state and push it into the indexer. * * @return boolean True on success. * * @since 2.5 * @throws Exception on error. */ public function onStartIndex() { JLog::add('FinderIndexerAdapter::onStartIndex', JLog::INFO); // Get the indexer state. $iState = FinderIndexer::getState(); // Get the number of content items. $total = (int) $this->getContentCount(); // Add the content count to the total number of items. $iState->totalItems += $total; // Populate the indexer state information for the adapter. $iState->pluginState[$this->context]['total'] = $total; $iState->pluginState[$this->context]['offset'] = 0; // Set the indexer state. FinderIndexer::setState($iState); } /** * Method to prepare for the indexer to be run. This method will often * be used to include dependencies and things of that nature. * * @return boolean True on success. * * @since 2.5 * @throws Exception on error. */ public function onBeforeIndex() { JLog::add('FinderIndexerAdapter::onBeforeIndex', JLog::INFO); // Get the indexer and adapter state. $iState = FinderIndexer::getState(); $aState = $iState->pluginState[$this->context]; // Check the progress of the indexer and the adapter. if ($iState->batchOffset == $iState->batchSize || $aState['offset'] == $aState['total']) { return true; } // Run the setup method. return $this->setup(); } /** * Method to index a batch of content items. This method can be called by * the indexer many times throughout the indexing process depending on how * much content is available for indexing. It is important to track the * progress correctly so we can display it to the user. * * @return boolean True on success. * * @since 2.5 * @throws Exception on error. */ public function onBuildIndex() { JLog::add('FinderIndexerAdapter::onBuildIndex', JLog::INFO); // Get the indexer and adapter state. $iState = FinderIndexer::getState(); $aState = $iState->pluginState[$this->context]; // Check the progress of the indexer and the adapter. if ($iState->batchOffset == $iState->batchSize || $aState['offset'] == $aState['total']) { return true; } // Get the batch offset and size. $offset = (int) $aState['offset']; $limit = (int) ($iState->batchSize - $iState->batchOffset); // Get the content items to index. $items = $this->getItems($offset, $limit); // Iterate through the items and index them. for ($i = 0, $n = count($items); $i < $n; $i++) { // Index the item. $this->index($items[$i]); // Adjust the offsets. $offset++; $iState->batchOffset++; $iState->totalItems--; } // Update the indexer state. $aState['offset'] = $offset; $iState->pluginState[$this->context] = $aState; FinderIndexer::setState($iState); return true; } /** * Method to change the value of a content item's property in the links * table. This is used to synchronize published and access states that * are changed when not editing an item directly. * * @param string $id The ID of the item to change. * @param string $property The property that is being changed. * @param integer $value The new value of that property. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ protected function change($id, $property, $value) { JLog::add('FinderIndexerAdapter::change', JLog::INFO); // Check for a property we know how to handle. if ($property !== 'state' && $property !== 'access') { return true; } // Get the url for the content id. $item = $this->db->quote($this->getUrl($id, $this->extension, $this->layout)); // Update the content items. $query = $this->db->getQuery(true); $query->update($this->db->quoteName('#__finder_links')); $query->set($this->db->quoteName($property) . ' = ' . (int) $value); $query->where($this->db->quoteName('url') . ' = ' . $item); $this->db->setQuery($query); $this->db->query(); // Check for a database error. if ($this->db->getErrorNum()) { // Throw database error exception. throw new Exception($this->db->getErrorMsg(), 500); } return true; } /** * Method to index an item. * * @param FinderIndexerResult $item The item to index as a FinderIndexerResult object. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ abstract protected function index(FinderIndexerResult $item); /** * Method to reindex an item. * * @param integer $id The ID of the item to reindex. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ protected function reindex($id) { // Run the setup method. $this->setup(); // Remove the old item. $this->remove($id); // Get the item. $item = $this->getItem($id); // Index the item. $this->index($item); } /** * Method to remove an item from the index. * * @param string $id The ID of the item to remove. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ protected function remove($id) { JLog::add('FinderIndexerAdapter::remove', JLog::INFO); // Get the item's URL $url = $this->db->quote($this->getUrl($id, $this->extension, $this->layout)); // Get the link ids for the content items. $query = $this->db->getQuery(true); $query->select($this->db->quoteName('link_id')); $query->from($this->db->quoteName('#__finder_links')); $query->where($this->db->quoteName('url') . ' = ' . $url); $this->db->setQuery($query); $items = $this->db->loadColumn(); // Check for a database error. if ($this->db->getErrorNum()) { // Throw database error exception. throw new Exception($this->db->getErrorMsg(), 500); } // Check the items. if (empty($items)) { return true; } // Remove the items. foreach ($items as $item) { FinderIndexer::remove($item); } return true; } /** * Method to setup the adapter before indexing. * * @return boolean True on success, false on failure. * * @since 2.5 * @throws Exception on database error. */ abstract protected function setup(); /** * Method to update index data on category access level changes * * @param JTable $row A JTable object * * @return void * * @since 2.5 */ protected function categoryAccessChange($row) { $sql = clone($this->getStateQuery()); $sql->where('c.id = ' . (int) $row->id); // Get the access level. $this->db->setQuery($sql); $items = $this->db->loadObjectList(); // Adjust the access level for each item within the category. foreach ($items as $item) { // Set the access level. $temp = max($item->access, $row->access); // Update the item. $this->change((int) $item->id, 'access', $temp); // Reindex the item $this->reindex($item->id); } } /** * Method to update index data on category access level changes * * @param array $pks A list of primary key ids of the content that has changed state. * @param integer $value The value of the state that the content has been changed to. * * @return void * * @since 2.5 */ protected function categoryStateChange($pks, $value) { // The item's published state is tied to the category // published state so we need to look up all published states // before we change anything. foreach ($pks as $pk) { $sql = clone($this->getStateQuery()); $sql->where('c.id = ' . (int) $pk); // Get the published states. $this->db->setQuery($sql); $items = $this->db->loadObjectList(); // Adjust the state for each item within the category. foreach ($items as $item) { // Translate the state. $temp = $this->translateState($item->state, $value); // Update the item. $this->change($item->id, 'state', $temp); // Reindex the item $this->reindex($item->id); } } } /** * Method to check the existing access level for categories * * @param JTable $row A JTable object * * @return void * * @since 2.5 */ protected function checkCategoryAccess($row) { $query = $this->db->getQuery(true); $query->select($this->db->quoteName('access')); $query->from($this->db->quoteName('#__categories')); $query->where($this->db->quoteName('id') . ' = ' . (int)$row->id); $this->db->setQuery($query); // Store the access level to determine if it changes $this->old_cataccess = $this->db->loadResult(); } /** * Method to check the existing access level for items * * @param JTable $row A JTable object * * @return void * * @since 2.5 */ protected function checkItemAccess($row) { $query = $this->db->getQuery(true); $query->select($this->db->quoteName('access')); $query->from($this->db->quoteName($this->table)); $query->where($this->db->quoteName('id') . ' = ' . (int)$row->id); $this->db->setQuery($query); // Store the access level to determine if it changes $this->old_access = $this->db->loadResult(); } /** * Method to get the number of content items available to index. * * @return integer The number of content items available to index. * * @since 2.5 * @throws Exception on database error. */ protected function getContentCount() { JLog::add('FinderIndexerAdapter::getContentCount', JLog::INFO); $return = 0; // Get the list query. $sql = $this->getListQuery(); // Check if the query is valid. if (empty($sql)) { return $return; } // Tweak the SQL query to make the total lookup faster. if ($sql instanceof JDatabaseQuery) { $sql = clone($sql); $sql->clear('select'); $sql->select('COUNT(*)'); $sql->clear('order'); } // Get the total number of content items to index. $this->db->setQuery($sql); $return = (int) $this->db->loadResult(); // Check for a database error. if ($this->db->getErrorNum()) { // Throw database error exception. throw new Exception($this->db->getErrorMsg(), 500); } return $return; } /** * Method to get a content item to index. * * @param integer $id The id of the content item. * * @return FinderIndexerResult A FinderIndexerResult object. * * @since 2.5 * @throws Exception on database error. */ protected function getItem($id) { JLog::add('FinderIndexerAdapter::getItem', JLog::INFO); // Get the list query and add the extra WHERE clause. $sql = $this->getListQuery(); $sql->where('a.' . $this->db->quoteName('id') . ' = ' . (int) $id); // Get the item to index. $this->db->setQuery($sql); $row = $this->db->loadAssoc(); // Check for a database error. if ($this->db->getErrorNum()) { // Throw database error exception. throw new Exception($this->db->getErrorMsg(), 500); } // Convert the item to a result object. $item = JArrayHelper::toObject($row, 'FinderIndexerResult'); // Set the item type. $item->type_id = $this->type_id; // Set the item layout. $item->layout = $this->layout; return $item; } /** * Method to get a list of content items to index. * * @param integer $offset The list offset. * @param integer $limit The list limit. * @param JDatabaseQuery $sql A JDatabaseQuery object. [optional] * * @return array An array of FinderIndexerResult objects. * * @since 2.5 * @throws Exception on database error. */ protected function getItems($offset, $limit, $sql = null) { JLog::add('FinderIndexerAdapter::getItems', JLog::INFO); $items = array(); // Get the content items to index. $this->db->setQuery($this->getListQuery($sql), $offset, $limit); $rows = $this->db->loadAssocList(); // Check for a database error. if ($this->db->getErrorNum()) { // Throw database error exception. throw new Exception($this->db->getErrorMsg(), 500); } // Convert the items to result objects. foreach ($rows as $row) { // Convert the item to a result object. $item = JArrayHelper::toObject($row, 'FinderIndexerResult'); // Set the item type. $item->type_id = $this->type_id; // Set the mime type. $item->mime = $this->mime; // Set the item layout. $item->layout = $this->layout; // Set the extension if present if (isset($row->extension)) { $item->extension = $row->extension; } // Add the item to the stack. $items[] = $item; } return $items; } /** * Method to get the SQL query used to retrieve the list of content items. * * @param mixed $sql A JDatabaseQuery object. [optional] * * @return JDatabaseQuery A database object. * * @since 2.5 */ protected function getListQuery($sql = null) { JLog::add('FinderIndexerAdapter::getListQuery', JLog::INFO); // Check if we can use the supplied SQL query. $sql = $sql instanceof JDatabaseQuery ? $sql : $this->db->getQuery(true); return $sql; } /** * Method to get the plugin type * * @param integer $id The plugin ID * * @return string The plugin type * * @since 2.5 */ protected function getPluginType($id) { // Prepare the query $query = $this->db->getQuery(true); $query->select($this->db->quoteName('element')); $query->from($this->db->quoteName('#__extensions')); $query->where($this->db->quoteName('extension_id') . ' = ' . (int) $id); $this->db->setQuery($query); $type = $this->db->loadResult(); return $type; } /** * Method to get a SQL query to load the published and access states for * an article and category. * * @return JDatabaseQuery A database object. * * @since 2.5 */ protected function getStateQuery() { $sql = $this->db->getQuery(true); // Item ID $sql->select('a.id'); // Item and category published state $sql->select('a.' . $this->state_field . ' AS state, c.published AS cat_state'); // Item and category access levels $sql->select('a.access, c.access AS cat_access'); $sql->from($this->table . ' AS a'); $sql->join('LEFT', '#__categories AS c ON c.id = a.catid'); return $sql; } /** * Method to get the query clause for getting items to update by time. * * @param string $time The modified timestamp. * * @return JDatabaseQuery A database object. * * @since 2.5 */ protected function getUpdateQueryByTime($time) { JLog::add('FinderIndexerAdapter::getUpdateQueryByTime', JLog::INFO); // Build an SQL query based on the modified time. $sql = $this->db->getQuery(true); $sql->where('a.' . $this->db->quoteName('modified') . ' >= ' . $this->db->quote($time)); return $sql; } /** * Method to get the query clause for getting items to update by id. * * @param array $ids The ids to load. * * @return JDatabaseQuery A database object. * * @since 2.5 */ protected function getUpdateQueryByIds($ids) { JLog::add('FinderIndexerAdapter::getUpdateQueryByIds', JLog::INFO); // Build an SQL query based on the item ids. $sql = $this->db->getQuery(true); $sql->where('a.' . $this->db->quoteName('id') . ' IN(' . implode(',', $ids) . ')'); return $sql; } /** * Method to get the type id for the adapter content. * * @return integer The numeric type id for the content. * * @since 2.5 * @throws Exception on database error. */ protected function getTypeId() { JLog::add('FinderIndexerAdapter::getTypeId', JLog::INFO); // Get the type id from the database. $query = $this->db->getQuery(true); $query->select($this->db->quoteName('id')); $query->from($this->db->quoteName('#__finder_types')); $query->where($this->db->quoteName('title') . ' = ' . $this->db->quote($this->type_title)); $this->db->setQuery($query); $result = (int) $this->db->loadResult(); // Check for a database error. if ($this->db->getErrorNum()) { // Throw database error exception. throw new Exception($this->db->getErrorMsg(), 500); } return $result; } /** * Method to get the URL for the item. The URL is how we look up the link * in the Finder index. * * @param integer $id The id of the item. * @param string $extension The extension the category is in. * @param string $view The view for the URL. * * @return string The URL of the item. * * @since 2.5 */ protected function getURL($id, $extension, $view) { return 'index.php?option=' . $extension . '&view=' . $view . '&id=' . $id; } /** * Method to get the page title of any menu item that is linked to the * content item, if it exists and is set. * * @param string $url The url of the item. * * @return mixed The title on success, null if not found. * * @since 2.5 * @throws Exception on database error. */ protected function getItemMenuTitle($url) { JLog::add('FinderIndexerAdapter::getItemMenuTitle', JLog::INFO); $return = null; // Set variables $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); // Build a query to get the menu params. $sql = $this->db->getQuery(true); $sql->select($this->db->quoteName('params')); $sql->from($this->db->quoteName('#__menu')); $sql->where($this->db->quoteName('link') . ' = ' . $this->db->quote($url)); $sql->where($this->db->quoteName('published') . ' = 1'); $sql->where($this->db->quoteName('access') . ' IN (' . $groups . ')'); // Get the menu params from the database. $this->db->setQuery($sql); $params = $this->db->loadResult(); // Check for a database error. if ($this->db->getErrorNum()) { // Throw database error exception. throw new Exception($this->db->getErrorMsg(), 500); } // Check the results. if (empty($params)) { return $return; } // Instantiate the params. $params = json_decode($params); // Get the page title if it is set. if ($params->page_title) { $return = $params->page_title; } return $return; } /** * Method to update index data on access level changes * * @param JTable $row A JTable object * * @return void * * @since 2.5 */ protected function itemAccessChange($row) { $sql = clone($this->getStateQuery()); $sql->where('a.id = ' . (int) $row->id); // Get the access level. $this->db->setQuery($sql); $item = $this->db->loadObject(); // Set the access level. $temp = max($row->access, $item->cat_access); // Update the item. $this->change((int) $row->id, 'access', $temp); } /** * Method to update index data on published state changes * * @param array $pks A list of primary key ids of the content that has changed state. * @param integer $value The value of the state that the content has been changed to. * * @return void * * @since 2.5 */ protected function itemStateChange($pks, $value) { // The item's published state is tied to the category // published state so we need to look up all published states // before we change anything. foreach ($pks as $pk) { $sql = clone($this->getStateQuery()); $sql->where('a.id = ' . (int) $pk); // Get the published states. $this->db->setQuery($sql); $item = $this->db->loadObject(); // Translate the state. $temp = $this->translateState($value, $item->cat_state); // Update the item. $this->change($pk, 'state', $temp); // Reindex the item $this->reindex($pk); } } /** * Method to update index data when a plugin is disabled * * @param array $pks A list of primary key ids of the content that has changed state. * * @return void * * @since 2.5 */ protected function pluginDisable($pks) { // Since multiple plugins may be disabled at a time, we need to check first // that we're handling the appropriate one for the context foreach ($pks as $pk) { if ($this->getPluginType($pk) == strtolower($this->context)) { // Get all of the items to unindex them $sql = clone($this->getStateQuery()); $this->db->setQuery($sql); $items = $this->db->loadColumn(); // Remove each item foreach ($items as $item) { $this->remove($item); } } } } /** * Method to translate the native content states into states that the * indexer can use. * * @param integer $item The item state. * @param integer $category The category state. [optional] * * @return integer The translated indexer state. * * @since 2.5 */ protected function translateState($item, $category = null) { // If category is present, factor in its states as well if ($category !== null) { if ($category == 0) { $item = 0; } } // Translate the state switch ($item) { // Published and archived items only should return a published state case 1; case 2: return 1; // All other states should return a unpublished state default: case 0: return 0; } } } PK>\q2..helpers/indexer/taxonomy.phpnuW+Aid; } // Check to see if the branch is in the table. $db = JFactory::getDBO(); $query = $db->getQuery(true); $query->select('*'); $query->from($db->quoteName('#__finder_taxonomy')); $query->where($db->quoteName('parent_id') . ' = 1'); $query->where($db->quoteName('title') . ' = ' . $db->quote($title)); $db->setQuery($query); // Get the result. $result = $db->loadObject(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Check if the database matches the input data. if (!empty($result) && $result->state == $state && $result->access == $access) { // The data matches, add the item to the cache. self::$branches[$title] = $result; return self::$branches[$title]->id; } // The database did not match the input. This could be because the // state has changed or because the branch does not exist. Let's figure // out which case is true and deal with it. $branch = new JObject; if (empty($result)) { // Prepare the branch object. $branch->parent_id = 1; $branch->title = $title; $branch->state = (int) $state; $branch->access = (int) $access; } else { // Prepare the branch object. $branch->id = (int) $result->id; $branch->parent_id = (int) $result->parent_id; $branch->title = $result->title; $branch->state = (int) $result->title; $branch->access = (int) $result->access; $branch->ordering = (int) $result->ordering; } // Store the branch. self::storeNode($branch); // Add the branch to the cache. self::$branches[$title] = $branch; return self::$branches[$title]->id; } /** * Method to add a node to the taxonomy tree. * * @param string $branch The title of the branch to store the node in. * @param string $title The title of the node. * @param integer $state The published state of the node. [optional] * @param integer $access The access state of the node. [optional] * * @return integer The id of the node. * * @since 2.5 * @throws Exception on database error. */ public static function addNode($branch, $title, $state = 1, $access = 1) { // Check to see if the node is in the cache. if (isset(self::$nodes[$branch][$title])) { return self::$nodes[$branch][$title]->id; } // Get the branch id, inserted it if it does not exist. $branchId = self::addBranch($branch); // Check to see if the node is in the table. $db = JFactory::getDBO(); $query = $db->getQuery(true); $query->select('*'); $query->from($db->quoteName('#__finder_taxonomy')); $query->where($db->quoteName('parent_id') . ' = ' . $db->quote($branchId)); $query->where($db->quoteName('title') . ' = ' . $db->quote($title)); $db->setQuery($query); // Get the result. $result = $db->loadObject(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } // Check if the database matches the input data. if (!empty($result) && $result->state == $state && $result->access == $access) { // The data matches, add the item to the cache. self::$nodes[$branch][$title] = $result; return self::$nodes[$branch][$title]->id; } // The database did not match the input. This could be because the // state has changed or because the node does not exist. Let's figure // out which case is true and deal with it. $node = new JObject; if (empty($result)) { // Prepare the node object. $node->parent_id = (int) $branchId; $node->title = $title; $node->state = (int) $state; $node->access = (int) $access; } else { // Prepare the node object. $node->id = (int) $result->id; $node->parent_id = (int) $result->parent_id; $node->title = $result->title; $node->state = (int) $result->title; $node->access = (int) $result->access; $node->ordering = (int) $result->ordering; } // Store the node. self::storeNode($node); // Add the node to the cache. self::$nodes[$branch][$title] = $node; return self::$nodes[$branch][$title]->id; } /** * Method to add a map entry between a link and a taxonomy node. * * @param integer $linkId The link to map to. * @param integer $nodeId The node to map to. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ public static function addMap($linkId, $nodeId) { // Insert the map. $db = JFactory::getDBO(); $query = $db->getQuery(true); $query->select($db->quoteName('link_id')); $query->from($db->quoteName('#__finder_taxonomy_map')); $query->where($db->quoteName('link_id') . ' = ' . (int)$linkId); $query->where($db->quoteName('node_id') . ' = ' . (int)$nodeId); $db->setQuery($query); $db->query(); $id = (int) $db->loadResult(); $map = new JObject(); $map->link_id = (int) $linkId; $map->node_id = (int) $nodeId; if ($id) { $db->updateObject('#__finder_taxonomy_map', $map); } else { $db->insertObject('#__finder_taxonomy_map', $map); } // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } return true; } /** * Method to get the title of all taxonomy branches. * * @return array An array of branch titles. * * @since 2.5 * @throws Exception on database error. */ public static function getBranchTitles() { $db = JFactory::getDBO(); // Set user variables $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); // Create a query to get the taxonomy branch titles. $query = $db->getQuery(true); $query->select($db->quoteName('title')); $query->from($db->quoteName('#__finder_taxonomy')); $query->where($db->quoteName('parent_id') . ' = 1'); $query->where($db->quoteName('state') . ' = 1'); $query->where($db->quoteName('access') . ' IN (' . $groups . ')'); // Get the branch titles. $db->setQuery($query); $results = $db->loadColumn(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } return $results; } /** * Method to find a taxonomy node in a branch. * * @param string $branch The branch to search. * @param string $title The title of the node. * * @return mixed Integer id on success, null on no match. * * @since 2.5 * @throws Exception on database error. */ public static function getNodeByTitle($branch, $title) { $db = JFactory::getDBO(); // Set user variables $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); // Create a query to get the node. $query = $db->getQuery(true); $query->select('t1.*'); $query->from($db->quoteName('#__finder_taxonomy') . ' AS t1'); $query->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id'); $query->where('t1.' . $db->quoteName('access') . ' IN (' . $groups . ')'); $query->where('t1.' . $db->quoteName('state') . ' = 1'); $query->where('t1.' . $db->quoteName('title') . ' LIKE "' . $db->escape($title) . '%"'); $query->where('t2.' . $db->quoteName('access') . ' IN (' . $groups . ')'); $query->where('t2.' . $db->quoteName('state') . ' = 1'); $query->where('t2.' . $db->quoteName('title') . ' = ' . $db->quote($branch)); // Get the node. $db->setQuery($query, 0, 1); $result = $db->loadObject(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } return $result; } /** * Method to remove map entries for a link. * * @param integer $linkId The link to remove. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ public static function removeMaps($linkId) { // Delete the maps. $db = JFactory::getDBO(); $query = $db->getQuery(true); $query->delete(); $query->from($db->quoteName('#__finder_taxonomy_map')); $query->where($db->quoteName('link_id') . ' = ' . (int) $linkId); $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } return true; } /** * Method to remove orphaned taxonomy nodes and branches. * * @return integer The number of deleted rows. * * @since 2.5 * @throws Exception on database error. */ public static function removeOrphanNodes() { // Delete all orphaned nodes. $db = JFactory::getDBO(); /*$query = $db->getQuery(true); $query->delete(); $query->from($db->quoteName('#__finder_taxonomy') . ' AS t'); $query->join('LEFT', $db->quoteName('#__finder_taxonomy_map') . ' AS m ON m.node_id = t.id'); $query->where('t.' . $db->quoteName('parent_id') . ' > 1'); $query->where('m.' . $db->quoteName('link_id') . ' IS NULL');*/ //@TODO: Query does not work with JDatabaseQuery, does not support DELETE t.*, must be DELETE FROM ... $query = 'DELETE t.*' . ' FROM ' . $db->quoteName('#__finder_taxonomy') . ' AS t' . ' LEFT JOIN ' . $db->quoteName('#__finder_taxonomy_map') . ' AS m ON m.node_id = t.id' . ' WHERE t.' . $db->quoteName('parent_id') . ' > 1' . ' AND m.' . $db->quoteName('link_id') . ' IS NULL'; $db->setQuery($query); $db->query(); // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } return $db->getAffectedRows(); } /** * Method to store a node to the database. This method will accept either a branch or a node. * * @param object $item The item to store. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ protected static function storeNode($item) { $db = JFactory::getDBO(); // Check if we are updating or inserting the item. if (empty($item->id)) { // Insert the item. $db->insertObject('#__finder_taxonomy', $item, 'id'); } else { // Update the item. $db->updateObject('#__finder_taxonomy', $item, 'id'); } // Check for a database error. if ($db->getErrorNum()) { // Throw database error exception. throw new Exception($db->getErrorMsg(), 500); } return true; } } PK>\ddp[ [ helpers/indexer/result.phpnuW+A array('title', 'subtitle', 'id'), FinderIndexer::TEXT_CONTEXT => array('summary', 'body'), FinderIndexer::META_CONTEXT => array('meta', 'list_price', 'sale_price'), FinderIndexer::PATH_CONTEXT => array('path', 'alias'), FinderIndexer::MISC_CONTEXT => array('comments') ); /** * The indexer will use this data to create taxonomy mapping entries for * the item so that it can be filtered by type, label, category, * or whatever. * * @var array * @since 2.5 */ protected $taxonomy = array(); /** * The content URL. * * @var string * @since 2.5 */ public $url; /** * The content route. * * @var string * @since 2.5 */ public $route; /** * The content title. * * @var string * @since 2.5 */ public $title; /** * The content description. * * @var string * @since 2.5 */ public $description; /** * The published state of the result. * * @var integer * @since 2.5 */ public $published; /** * The content published state. * * @var integer * @since 2.5 */ public $state; /** * The content access level. * * @var integer * @since 2.5 */ public $access; /** * The content language. * * @var string * @since 2.5 */ public $language = '*'; /** * The publishing start date. * * @var string * @since 2.5 */ public $publish_start_date; /** * The publishing end date. * * @var string * @since 2.5 */ public $publish_end_date; /** * The generic start date. * * @var string * @since 2.5 */ public $start_date; /** * The generic end date. * * @var string * @since 2.5 */ public $end_date; /** * The item list price. * * @var mixed * @since 2.5 */ public $list_price; /** * The item sale price. * * @var mixed * @since 2.5 */ public $sale_price; /** * The content type id. This is set by the adapter. * * @var integer * @since 2.5 */ public $type_id; /** * The magic set method is used to push additional values into the elements * array in order to preserve the cleanliness of the object. * * @param string $name The name of the element. * @param mixed $value The value of the element. * * @return void * * @since 2.5 */ public function __set($name, $value) { $this->elements[$name] = $value; } /** * The magic get method is used to retrieve additional element values * from the elements array. * * @param string $name The name of the element. * * @return mixed The value of the element if set, null otherwise. * * @since 2.5 */ public function __get($name) { // Get the element value if set. if (array_key_exists($name, $this->elements)) { return $this->elements[$name]; } else { return null; } } /** * The magic isset method is used to check the state of additional element * values in the elements array. * * @param string $name The name of the element. * * @return boolean True if set, false otherwise. * * @since 2.5 */ public function __isset($name) { return isset($this->elements[$name]); } /** * The magic unset method is used to unset additional element values in the * elements array. * * @param string $name The name of the element. * * @return void * * @since 2.5 */ public function __unset($name) { unset($this->elements[$name]); } /** * Method to retrieve additional element values from the elements array. * * @param string $name The name of the element. * * @return mixed The value of the element if set, null otherwise. * * @since 2.5 */ public function getElement($name) { // Get the element value if set. if (array_key_exists($name, $this->elements)) { return $this->elements[$name]; } else { return null; } } /** * Method to set additional element values in the elements array. * * @param string $name The name of the element. * @param mixed $value The value of the element. * * @return void * * @since 2.5 */ public function setElement($name, $value) { $this->elements[$name] = $value; } /** * Method to get all processing instructions. * * @return array An array of processing instructions. * * @since 2.5 */ public function getInstructions() { return $this->instructions; } /** * Method to add a processing instruction for an item property. * * @param string $group The group to associate the property with. * @param string $property The property to process. * * @return void * * @since 2.5 */ public function addInstruction($group, $property) { // Check if the group exists. We can't add instructions for unknown groups. if (array_key_exists($group, $this->instructions)) { // Check if the property exists in the group. if (!in_array($property, $this->instructions[$group])) { // Add the property to the group. $this->instructions[$group][] = $property; } } } /** * Method to remove a processing instruction for an item property. * * @param string $group The group to associate the property with. * @param string $property The property to process. * * @return void * * @since 2.5 */ public function removeInstruction($group, $property) { // Check if the group exists. We can't remove instructions for unknown groups. if (array_key_exists($group, $this->instructions)) { // Search for the property in the group. $key = array_search($property, $this->instructions[$group]); // If the property was found, remove it. if ($key !== false) { unset($this->instructions[$group][$key]); } } } /** * Method to get the taxonomy maps for an item. * * @param string $branch The taxonomy branch to get. [optional] * * @return array An array of taxonomy maps. * * @since 2.5 */ public function getTaxonomy($branch = null) { // Get the taxonomy branch if available. if ($branch !== null && isset($this->taxonomy[$branch])) { // Filter the input. $branch = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,]+#mui', ' ', $branch); return $this->taxonomy[$branch]; } return $this->taxonomy; } /** * Method to add a taxonomy map for an item. * * @param string $branch The title of the taxonomy branch to add the node to. * @param string $title The title of the taxonomy node. * @param integer $state The published state of the taxonomy node. [optional] * @param integer $access The access level of the taxonomy node. [optional] * * @return void * * @since 2.5 */ public function addTaxonomy($branch, $title, $state = 1, $access = 1) { // Filter the input. $branch = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,]+#mui', ' ', $branch); // Create the taxonomy node. $node = new JObject; $node->title = $title; $node->state = (int) $state; $node->access = (int) $access; // Add the node to the taxonomy branch. $this->taxonomy[$branch][$node->title] = $node; } } PK>\֌QQhelpers/finder.phpnuW+Aset($action->name, $user->authorise($action->name, $assetName)); } return $result; } } PK>\ql l helpers/html/finder.phpnuW+AgetQuery(true); $query->select('DISTINCT t.title AS text, t.id AS value'); $query->from($db->quoteName('#__finder_types') . ' AS t'); $query->join('LEFT', $db->quoteName('#__finder_links') . ' AS l ON l.type_id = t.id'); $query->order('t.title ASC'); $db->setQuery($query); $rows = $db->loadObjectList(); // Check for database errors. if ($db->getErrorNum()) { return; } // Compile the options. $options = array(); foreach ($rows as $row) { $key = $lang->hasKey(FinderHelperLanguage::branchPlural($row->text)) ? FinderHelperLanguage::branchPlural($row->text) : $row->text; $string = JText::sprintf('COM_FINDER_ITEM_X_ONLY', JText::_($key)); $options[] = JHtml::_('select.option', $row->value, $string); } return $options; } /** * Creates a list of maps. * * @return array An array containing the maps that can be selected. * * @since 2.5 */ public static function mapslist() { $lang = JFactory::getLanguage(); // Load the finder types. $db = JFactory::getDBO(); $query = $db->getQuery(true); $query->select('title AS text, id AS value'); $query->from($db->quoteName('#__finder_taxonomy')); $query->where($db->quoteName('parent_id') . ' = 1'); $query->order('ordering, title ASC'); $db->setQuery($query); $rows = $db->loadObjectList(); // Check for database errors. if ($db->getErrorNum()) { return; } // Compile the options. $options = array(); $options[] = JHtml::_('select.option', '1', JText::_('COM_FINDER_MAPS_BRANCHES')); foreach ($rows as $row) { $key = $lang->hasKey(FinderHelperLanguage::branchPlural($row->text)) ? FinderHelperLanguage::branchPlural($row->text) : $row->text; $string = JText::sprintf('COM_FINDER_ITEM_X_ONLY', JText::_($key)); $options[] = JHtml::_('select.option', $row->value, $string); } return $options; } /** * Creates a list of published states. * * @return array An array containing the states that can be selected. * * @since 2.5 */ public static function statelist() { $options = array(); $options[] = JHtml::_('select.option', '1', JText::sprintf('COM_FINDER_ITEM_X_ONLY', JText::_('JPUBLISHED'))); $options[] = JHtml::_('select.option', '0', JText::sprintf('COM_FINDER_ITEM_X_ONLY', JText::_('JUNPUBLISHED'))); return $options; } } PK>\6helpers/html/index.htmlnuW+APK>\)helpers/html/.htaccessnuW+A Order allow,deny Deny from all PK>\/&^ config.xmlnuW+A
PK>\GHHcontroller.phpnuW+Ainput; $cachable = true; // Load plug-in language files. FinderHelperLanguage::loadPluginLanguage(); // Set the default view name and format from the Request. $viewName = $input->get('view', 'search', 'word'); $input->set('view', $viewName); // Don't cache view for search queries if ($input->get('q') || $input->get('f') || $input->get('t')) { $cachable = false; } $safeurlparams = array( 'f' => 'INT', 'lang' => 'CMD' ); return parent::display($cachable, $safeurlparams); } } PK>\ access.xmlnuW+A
PK>\`[ finder.xmlnuW+A com_finder Joomla! Project (C) 2005 - 2014 Open Source Matters. All rights reserved. August 2011 GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 2.5.0 COM_FINDER_XML_DESCRIPTION COM_FINDER controller.php index.html finder.php router.php controllers helpers models views js images css index.html sql/install.mysql.sql sql/install.postgresql.sql sql/uninstall.mysql.sql sql/uninstall.postgresql.sql en-GB/en-GB.com_finder.ini access.xml config.xml controller.php finder.php index.html controllers helpers models sql tables views en-GB/en-GB.com_finder.ini en-GB/en-GB.com_finder.sys.ini COM_FINDER PK>\1 finder.phpnuW+Aexecute(JFactory::getApplication()->input->get('task', '', 'word')); $controller->redirect(); PK2?\i ? views/search/view.opensearch.phpnuW+AsetShortName($params->get('opensearch_name', $app->getCfg('sitename'))); $doc->setDescription($params->get('opensearch_description', $app->getCfg('MetaDesc'))); // Add the URL for the search $searchUri = JURI::base() . 'index.php?option=com_finder&q={searchTerms}'; // Find the menu item for the search $menu = $app->getMenu(); $items = $menu->getItems('link', 'index.php?option=com_finder&view=search'); if (isset($items[0])) { $searchUri .= '&Itemid=' . $items[0]->id; } $htmlSearch = new JOpenSearchUrl; $htmlSearch->template = JRoute::_($searchUri); $doc->addUrl($htmlSearch); } } PK2?\ooviews/search/view.html.phpnuW+AgetParams(); // Get view data. $state = $this->get('State'); $query = $this->get('Query'); JDEBUG ? $GLOBALS['_PROFILER']->mark('afterFinderQuery') : null; $results = $this->get('Results'); JDEBUG ? $GLOBALS['_PROFILER']->mark('afterFinderResults') : null; $total = $this->get('Total'); JDEBUG ? $GLOBALS['_PROFILER']->mark('afterFinderTotal') : null; $pagination = $this->get('Pagination'); JDEBUG ? $GLOBALS['_PROFILER']->mark('afterFinderPagination') : null; // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } // Configure the pathway. if (!empty($query->input)) { $app->getPathWay()->addItem($this->escape($query->input)); } // Push out the view data. $this->assignRef('state', $state); $this->assignRef('params', $params); $this->assignRef('query', $query); $this->assignRef('results', $results); $this->assignRef('total', $total); $this->assignRef('pagination', $pagination); // Check for a double quote in the query string. if (strpos($this->query->input, '"')) { // Get the application router. $router =& $app->getRouter(); // Fix the q variable in the URL. if ($router->getVar('q') !== $this->query->input) { $router->setVar('q', $this->query->input); } } // Push out the query data. JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); $this->suggested = JHtml::_('query.suggested', $query); $this->explained = JHtml::_('query.explained', $query); // Escape strings for HTML output $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx')); // Check for layout override only if this is not the active menu item // If it is the active menu item, then the view and category id will match $active = $app->getMenu()->getActive(); if (isset($active->query['layout'])) { // We need to set the layout in case this is an alternative menu item (with an alternative layout) $this->setLayout($active->query['layout']); } $this->prepareDocument($query); JDEBUG ? $GLOBALS['_PROFILER']->mark('beforeFinderLayout') : null; parent::display($tpl); JDEBUG ? $GLOBALS['_PROFILER']->mark('afterFinderLayout') : null; } /** * Method to get hidden input fields for a get form so that control variables * are not lost upon form submission * * @return string A string of hidden input form fields * * @since 2.5 */ protected function getFields() { $fields = null; // Get the URI. $uri = JURI::getInstance(JRoute::_($this->query->toURI())); $uri->delVar('q'); $uri->delVar('o'); $uri->delVar('t'); $uri->delVar('d1'); $uri->delVar('d2'); $uri->delVar('w1'); $uri->delVar('w2'); // Create hidden input elements for each part of the URI. foreach ($uri->getQuery(true) as $n => $v) { if (is_scalar($v)) { $fields .= ''; } } return $fields; } /** * Method to get the layout file for a search result object. * * @param string $layout The layout file to check. [optional] * * @return string The layout file to use. * * @since 2.5 */ protected function getLayoutFile($layout = null) { // Create and sanitize the file name. $file = $this->_layout . '_' . preg_replace('/[^A-Z0-9_\.-]/i', '', $layout); // Check if the file exists. jimport('joomla.filesystem.path'); $filetofind = $this->_createFileName('template', array('name' => $file)); $exists = JPath::find($this->_path['template'], $filetofind); return ($exists ? $layout : 'result'); } /** * Prepares the document * * @param FinderIndexerQuery $query The search query * * @return void * * @since 2.5 */ protected function prepareDocument($query) { $app = JFactory::getApplication(); $menus = $app->getMenu(); $pathway = $app->getPathway(); $title = null; // Because the application sets a default page title, // we need to get it from the menu item itself $menu = $menus->getActive(); if ($menu) { $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); } else { $this->params->def('page_heading', JText::_('COM_FINDER_DEFAULT_PAGE_TITLE')); } $id = (int) @$menu->query['id']; $title = $this->params->get('page_title', ''); if (empty($title)) { $title = $app->getCfg('sitename'); } elseif ($app->getCfg('sitename_pagetitles', 0) == 1) { $title = JText::sprintf('JPAGETITLE', $app->getCfg('sitename'), $title); } elseif ($app->getCfg('sitename_pagetitles', 0) == 2) { $title = JText::sprintf('JPAGETITLE', $title, $app->getCfg('sitename')); } $this->document->setTitle($title); if ($layout = $this->params->get('article_layout')) { $this->setLayout($layout); } // Configure the document meta-description. if (!empty($this->explained)) { $explained = $this->escape(html_entity_decode(strip_tags($this->explained), ENT_QUOTES, 'UTF-8')); $this->document->setDescription($explained); } // Configure the document meta-keywords. if (!empty($query->highlight)) { $this->document->setMetadata('keywords', implode(', ', $query->highlight)); } if ($this->params->get('robots')) { $this->document->setMetadata('robots', $this->params->get('robots')); } // Add feed link to the document head. if ($this->params->get('show_feed_link', 1) == 1) { // Add the RSS link. $props = array('type' => 'application/rss+xml', 'title' => 'RSS 2.0'); $route = JRoute::_($this->query->toURI() . '&format=feed&type=rss'); $this->document->addHeadLink($route, 'alternate', 'rel', $props); // Add the ATOM link. $props = array('type' => 'application/atom+xml', 'title' => 'Atom 1.0'); $route = JRoute::_($this->query->toURI() . '&format=feed&type=atom'); $this->document->addHeadLink($route, 'alternate', 'rel', $props); } } } PK2?\En n %views/search/tmpl/default_results.phpnuW+Aquery->highlight) && $this->params->get('highlight_terms', 1)) { JHtml::_('behavior.highlighter', $this->query->highlight); } // Get the application object. $app = JFactory::getApplication(); // Display the suggested search if it is different from the current search. if (($this->suggested && $this->params->get('show_suggested_query', 1)) || ($this->explained && $this->params->get('show_explained_query', 1))): ?>
suggested && $this->params->get('show_suggested_query', 1)) { // Replace the base query string with the suggested query string. $uri = JUri::getInstance($this->query->toURI()); $uri->setVar('q', $this->suggested); // Compile the suggested query link. $link = '' . $this->escape($this->suggested) . ''; echo JText::sprintf('COM_FINDER_SEARCH_SIMILAR', $link); } // Display the explained search query. elseif ($this->explained && $this->params->get('show_explained_query', 1)) { echo $this->explained; } ?>
total == 0): ?>

getLanguageFilter()) : ?>

escape($this->query->input)); ?>

escape($this->query->input)); ?>

pagination->get('limitstart')+1; $total = (int) $this->pagination->get('total'); $limit = (int) $this->pagination->get('limit') * $this->pagination->get('pages.current'); $limit = (int) ($limit > $total ? $total : $limit); $pages = JText::sprintf('COM_FINDER_SEARCH_RESULTS_OF', $start, $limit, $total); ?>
results); $i < $n; $i++): $this->result = &$this->results[$i]; $layout = $this->getLayoutFile($this->result->layout); ?> loadTemplate($layout); ?>

PK2?\)views/search/tmpl/.htaccessnuW+A Order allow,deny Deny from all PK2?\v "views/search/tmpl/default_form.phpnuW+A PK2?\Izz$views/search/tmpl/default_result.phpnuW+Aresult->mime) ? 'mime-' . $this->result->mime : null; // Get the base url. $base = JURI::getInstance()->toString(array('scheme', 'host', 'port')); // Get the route with highlighting information. if (!empty($this->query->highlight) && empty($this->result->mime) && $this->params->get('highlight_terms', 1) && JPluginHelper::isEnabled('system', 'highlight')) { $route = $this->result->route . '&highlight=' . base64_encode(json_encode($this->query->highlight)); } else { $route = $this->result->route; } ?>
result->title; ?>
params->get('show_description', 1)): ?>
result->description, $this->params->get('description_length', 255)); ?>
params->get('show_url', 1)): ?>
result->route); ?>
params->get('show_page_heading')) : ?>

escape($this->params->get('page_heading'))) : ?> escape($this->params->get('page_heading')); ?> escape($this->params->get('page_title')); ?>

params->get('show_search_form', 1)): ?>
loadTemplate('form'); ?>
query->search === true): ?>
loadTemplate('results'); ?>
PK2?\ܔ; views/search/tmpl/default.xmlnuW+A
PK2?\ views/search/view.feed.phpnuW+Ainput->set('limit', $app->getCfg('feed_limit')); // Get view data. $state = $this->get('State'); $params = $state->get('params'); $query = $this->get('Query'); $results = $this->get('Results'); // Push out the query data. JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); $suggested = JHtml::_('query.suggested', $query); $explained = JHtml::_('query.explained', $query); // Set the document title. $title = $params->get('page_title', ''); if (empty($title)) { $title = $app->getCfg('sitename'); } elseif ($app->getCfg('sitename_pagetitles', 0) == 1) { $title = JText::sprintf('JPAGETITLE', $app->getCfg('sitename'), $title); } elseif ($app->getCfg('sitename_pagetitles', 0) == 2) { $title = JText::sprintf('JPAGETITLE', $title, $app->getCfg('sitename')); } $this->document->setTitle($title); // Configure the document description. if (!empty($explained)) { $this->document->setDescription(html_entity_decode(strip_tags($explained), ENT_QUOTES, 'UTF-8')); } // Set the document link. $this->document->link = JRoute::_($query->toURI()); // If we don't have any results, we are done. if (empty($results)) { return; } // Convert the results to feed entries. foreach ($results as $result) { // Convert the result to a feed entry. $item = new JFeedItem; $item->title = $result->title; $item->link = JRoute::_($result->route); $item->description = $result->description; $item->date = intval($result->start_date) ? JHtml::date($result->start_date, 'l d F Y') : $result->indexdate; // Get the taxonomy data. $taxonomy = $result->getTaxonomy(); // Add the category to the feed if available. if (isset($taxonomy['Category'])) { $node = array_pop($taxonomy['Category']); $item->category = $node->title; } // Loads item info into rss array. $this->document->addItem($item); } } } PK2?\)views/search/.htaccessnuW+A Order allow,deny Deny from all PK2?\6views/search/index.htmlnuW+APK2?\views/search/metadata.xmlnuW+A PK2?\;; controllers/suggestions.json.phpnuW+Aget('show_autosuggest', 1)) { // Get the suggestions. $model = $this->getModel('Suggestions', 'FinderModel'); $return = $model->getItems(); } // Check the data. if (empty($return)) { $return = array(); } // Use the correct json mime-type header('Content-Type: application/json'); // Send the response. echo json_encode($return); JFactory::getApplication()->close(); } } PK2?\&  router.phpnuW+AgetMenu(); } /* * First, handle menu item routes first. When the menu system builds a * route, it only provides the option and the menu item id. We don't have * to do anything to these routes. */ if (count($query) === 2 && isset($query['Itemid']) && isset($query['option'])) { return $segments; } /* * Next, handle a route with a supplied menu item id. All system generated * routes should fall into this group. We can assume that the menu item id * is the best possible match for the query but we need to go through and * see which variables we can eliminate from the route query string because * they are present in the menu item route already. */ if (!empty($query['Itemid'])) { // Get the menu item. $item = $menu->getItem($query['Itemid']); // Check if the view matches. if ($item && @$item->query['view'] === @$query['view']) { unset($query['view']); } // Check if the search query filter matches. if ($item && @$item->query['f'] === @$query['f']) { unset($query['f']); } // Check if the search query string matches. if ($item && @$item->query['q'] === @$query['q']) { unset($query['q']); } return $segments; } /* * Lastly, handle a route with no menu item id. Fortunately, we only need * to deal with the view as the other route variables are supposed to stay * in the query string. */ if (isset($query['view'])) { // Add the view to the segments. $segments[] = $query['view']; unset($query['view']); } return $segments; } /** * Method to parse a SEF route. * * @param array $segments An array of route segments. * * @return array An array of route variables. * * @since 2.5 */ function FinderParseRoute($segments) { $vars = array(); // Check if the view segment is set and it equals search or advanced. if (@$segments[0] === 'search' || @$segments[0] === 'advanced') { $vars['view'] = $segments[0]; } return $vars; } PK2?\AOOmodels/search.phpnuW+Aquery->search)) { return null; } // Check if we should return results. if (empty($this->includedTerms) && (empty($this->query->filters) || !$this->query->empty)) { return null; } // Get the store id. $store = $this->getStoreId('getResults'); // Use the cached data if possible. if ($this->retrieve($store)) { return $this->retrieve($store); } // Get the row data. $items = $this->getResultsData(); // Check the data. if (empty($items)) { return null; } // Create the query to get the search results. $db = $this->getDbo(); $query = $db->getQuery(true); $query->select($db->quoteName('link_id') . ', ' . $db->quoteName('object')); $query->from($db->quoteName('#__finder_links')); $query->where($db->quoteName('link_id') . ' IN (' . implode(',', array_keys($items)) . ')'); // Load the results from the database. $db->setQuery($query); $rows = $db->loadObjectList('link_id'); // Check for a database error. if ($db->getErrorNum()) { throw new Exception($db->getErrorMsg(), 500); } // Set up our results container. $results = $items; // Convert the rows to result objects. foreach ($rows as $rk => $row) { // Build the result object. $result = unserialize($row->object); $result->weight = $results[$rk]; $result->link_id = $rk; // Add the result back to the stack. $results[$rk] = $result; } // Switch to a non-associative array. $results = array_values($results); // Push the results into cache. $this->store($store, $results); // Return the results. return $this->retrieve($store); } /** * Method to get the total number of results. * * @return integer The total number of results. * * @since 2.5 * @throws Exception on database error. */ public function getTotal() { // Check if the search query is valid. if (empty($this->query->search)) { return null; } // Check if we should return results. if (empty($this->includedTerms) && (empty($this->query->filters) || !$this->query->empty)) { return null; } // Get the store id. $store = $this->getStoreId('getTotal'); // Use the cached data if possible. if ($this->retrieve($store)) { return $this->retrieve($store); } // Get the results total. $total = $this->getResultsTotal(); // Push the total into cache. $this->store($store, $total); // Return the total. return $this->retrieve($store); } /** * Method to get the query object. * * @return FinderIndexerQuery A query object. * * @since 2.5 */ public function getQuery() { // Get the state in case it isn't loaded. $state = $this->getState(); // Return the query object. return $this->query; } /** * Method to build a database query to load the list data. * * @return JDatabaseQuery A database query. * * @since 2.5 */ protected function getListQuery() { // Get the store id. $store = $this->getStoreId('getListQuery'); // Use the cached data if possible. if ($this->retrieve($store, false)) { return clone($this->retrieve($store, false)); } // Set variables $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); $query->select('l.link_id'); $query->from($db->quoteName('#__finder_links') . ' AS l'); $query->where($db->quoteName('l.access') . ' IN (' . $groups . ')'); $query->where($db->quoteName('l.state') . ' = 1'); // Get the null date and the current date, minus seconds. $nullDate = $db->quote($db->getNullDate()); $nowDate = $db->quote(substr_replace(JFactory::getDate()->toSQL(), '00', -2)); // Add the publish up and publish down filters. $query->where('(' . $db->quoteName('l.publish_start_date') . ' = ' . $nullDate . ' OR ' . $db->quoteName('l.publish_start_date') . ' <= ' . $nowDate . ')'); $query->where('(' . $db->quoteName('l.publish_end_date') . ' = ' . $nullDate . ' OR ' . $db->quoteName('l.publish_end_date') . ' >= ' . $nowDate . ')'); /* * Add the taxonomy filters to the query. We have to join the taxonomy * map table for each group so that we can use AND clauses across * groups. Within each group there can be an array of values that will * use OR clauses. */ if (!empty($this->query->filters)) { // Convert the associative array to a numerically indexed array. $groups = array_values($this->query->filters); // Iterate through each taxonomy group and add the join and where. for ($i = 0, $c = count($groups); $i < $c; $i++) { // We use the offset because each join needs a unique alias. $query->join('INNER', $db->quoteName('#__finder_taxonomy_map') . ' AS t' . $i . ' ON t' . $i . '.link_id = l.link_id'); $query->where('t' . $i . '.node_id IN (' . implode(',', $groups[$i]) . ')'); } } // Add the start date filter to the query. if (!empty($this->query->date1)) { // Escape the date. $date1 = $db->quote($this->query->date1); // Add the appropriate WHERE condition. if ($this->query->when1 == 'before') { $query->where($db->quoteName('l.start_date') . ' <= ' . $date1); } elseif ($this->query->when1 == 'after') { $query->where($db->quoteName('l.start_date') . ' >= ' . $date1); } else { $query->where($db->quoteName('l.start_date') . ' = ' . $date1); } } // Add the end date filter to the query. if (!empty($this->query->date2)) { // Escape the date. $date2 = $db->quote($this->query->date2); // Add the appropriate WHERE condition. if ($this->query->when2 == 'before') { $query->where($db->quoteName('l.start_date') . ' <= ' . $date2); } elseif ($this->query->when2 == 'after') { $query->where($db->quoteName('l.start_date') . ' >= ' . $date2); } else { $query->where($db->quoteName('l.start_date') . ' = ' . $date2); } } // Filter by language if ($this->getState('filter.language')) { $query->where('l.language in ('.$db->quote(JFactory::getLanguage()->getTag()).','.$db->quote('*').')'); } // Push the data into cache. $this->store($store, $query, false); // Return a copy of the query object. return clone($this->retrieve($store, false)); } /** * Method to get the total number of results for the search query. * * @return integer The results total. * * @since 2.5 * @throws Exception on database error. */ protected function getResultsTotal() { // Get the store id. $store = $this->getStoreId('getResultsTotal', false); // Use the cached data if possible. if ($this->retrieve($store)) { return $this->retrieve($store); } // Get the base query and add the ordering information. $base = $this->getListQuery(); $base->select('0 AS ordering'); // Get the maximum number of results. $limit = (int) $this->getState('match.limit'); /* * If there are no optional or required search terms in the query, * we can get the result total in one relatively simple database query. */ if (empty($this->includedTerms)) { // Adjust the query to join on the appropriate mapping table. $sql = clone($base); $sql->clear('select'); $sql->select('COUNT(DISTINCT l.link_id)'); // Get the total from the database. $this->_db->setQuery($sql); $total = $this->_db->loadResult(); // Check for a database error. if ($this->_db->getErrorNum()) { throw new Exception($this->_db->getErrorMsg(), 500); } // Push the total into cache. $this->store($store, min($total, $limit)); // Return the total. return $this->retrieve($store); } /* * If there are optional or required search terms in the query, the * process of getting the result total is more complicated. */ $start = 0; $total = 0; $more = false; $items = array(); $sorted = array(); $maps = array(); $excluded = $this->getExcludedLinkIds(); /* * Iterate through the included search terms and group them by mapping * table suffix. This ensures that we never have to do more than 16 * queries to get a batch. This may seem like a lot but it is rarely * anywhere near 16 because of the improved mapping algorithm. */ foreach ($this->includedTerms as $token => $ids) { // Get the mapping table suffix. $suffix = JString::substr(md5(JString::substr($token, 0, 1)), 0, 1); // Initialize the mapping group. if (!array_key_exists($suffix, $maps)) { $maps[$suffix] = array(); } // Add the terms to the mapping group. $maps[$suffix] = array_merge($maps[$suffix], $ids); } /* * When the query contains search terms we need to find and process the * result total iteratively using a do-while loop. */ do { // Create a container for the fetched results. $results = array(); $more = false; /* * Iterate through the mapping groups and load the total from each * mapping table. */ foreach ($maps as $suffix => $ids) { // Create a storage key for this set. $setId = $this->getStoreId('getResultsTotal:' . serialize(array_values($ids)) . ':' . $start . ':' . $limit); // Use the cached data if possible. if ($this->retrieve($setId)) { $temp = $this->retrieve($setId); } // Load the data from the database. else { // Adjust the query to join on the appropriate mapping table. $sql = clone($base); $sql->join('INNER', '#__finder_links_terms' . $suffix . ' AS m ON m.link_id = l.link_id'); $sql->where('m.term_id IN (' . implode(',', $ids) . ')'); // Load the results from the database. $this->_db->setQuery($sql, $start, $limit); $temp = $this->_db->loadObjectList(); // Check for a database error. if ($this->_db->getErrorNum()) { throw new Exception($this->_db->getErrorMsg(), 500); } // Set the more flag to true if any of the sets equal the limit. $more = (count($temp) === $limit) ? true : false; // We loaded the data unkeyed but we need it to be keyed for later. $junk = $temp; $temp = array(); // Convert to an associative array. for ($i = 0, $c = count($junk); $i < $c; $i++) { $temp[$junk[$i]->link_id] = $junk[$i]; } // Store this set in cache. $this->store($setId, $temp); } // Merge the results. $results = array_merge($results, $temp); } // Check if there are any excluded terms to deal with. if (count($excluded)) { // Remove any results that match excluded terms. for ($i = 0, $c = count($results); $i < $c; $i++) { if (in_array($results[$i]->link_id, $excluded)) { unset($results[$i]); } } // Reset the array keys. $results = array_values($results); } // Iterate through the set to extract the unique items. for ($i = 0, $c = count($results); $i < $c; $i++) { if (!isset($sorted[$results[$i]->link_id])) { $sorted[$results[$i]->link_id] = $results[$i]->ordering; } } /* * If the query contains just optional search terms and we have * enough items for the page, we can stop here. */ if (empty($this->requiredTerms)) { // If we need more items and they're available, make another pass. if ($more && count($sorted) < $limit) { // Increment the batch starting point and continue. $start += $limit; continue; } // Push the total into cache. $this->store($store, min(count($sorted), $limit)); // Return the total. return $this->retrieve($store); } /* * The query contains required search terms so we have to iterate * over the items and remove any items that do not match all of the * required search terms. This is one of the most expensive steps * because a required token could theoretically eliminate all of * current terms which means we would have to loop through all of * the possibilities. */ foreach ($this->requiredTerms as $token => $required) { // Create a storage key for this set. $setId = $this->getStoreId('getResultsTotal:required:' . serialize(array_values($required)) . ':' . $start . ':' . $limit); // Use the cached data if possible. if ($this->retrieve($setId)) { $reqTemp = $this->retrieve($setId); } // Check if the token was matched. elseif (empty($required)) { return null; } // Load the data from the database. else { // Setup containers in case we have to make multiple passes. $reqMore = false; $reqStart = 0; $reqTemp = array(); do { // Get the map table suffix. $suffix = JString::substr(md5(JString::substr($token, 0, 1)), 0, 1); // Adjust the query to join on the appropriate mapping table. $sql = clone($base); $sql->join('INNER', '#__finder_links_terms' . $suffix . ' AS m ON m.link_id = l.link_id'); $sql->where('m.term_id IN (' . implode(',', $required) . ')'); // Load the results from the database. $this->_db->setQuery($sql, $reqStart, $limit); $temp = $this->_db->loadObjectList('link_id'); // Check for a database error. if ($this->_db->getErrorNum()) { throw new Exception($this->_db->getErrorMsg(), 500); } // Set the required token more flag to true if the set equal the limit. $reqMore = (count($temp) === $limit) ? true : false; // Merge the matching set for this token. $reqTemp = $reqTemp + $temp; // Increment the term offset. $reqStart += $limit; } while ($reqMore == true); // Store this set in cache. $this->store($setId, $reqTemp); } // Remove any items that do not match the required term. $sorted = array_intersect_key($sorted, $reqTemp); } // If we need more items and they're available, make another pass. if ($more && count($sorted) < $limit) { // Increment the batch starting point. $start += $limit; // Merge the found items. $items = $items + $sorted; continue; } // Otherwise, end the loop. { // Merge the found items. $items = $items + $sorted; $more = false; } // End do-while loop. } while ($more === true); // Set the total. $total = count($items); $total = min($total, $limit); // Push the total into cache. $this->store($store, $total); // Return the total. return $this->retrieve($store); } /** * Method to get the results for the search query. * * @return array An array of result data objects. * * @since 2.5 * @throws Exception on database error. */ protected function getResultsData() { // Get the store id. $store = $this->getStoreId('getResultsData', false); // Use the cached data if possible. if ($this->retrieve($store)) { return $this->retrieve($store); } // Get the result ordering and direction. $ordering = $this->getState('list.ordering', 'l.start_date'); $direction = $this->getState('list.direction', 'DESC'); // Get the base query and add the ordering information. $base = $this->getListQuery(); $base->select($this->_db->escape($ordering) . ' AS ordering'); $base->order($this->_db->escape($ordering) . ' ' . $this->_db->escape($direction)); /* * If there are no optional or required search terms in the query, we * can get the results in one relatively simple database query. */ if (empty($this->includedTerms)) { // Get the results from the database. $this->_db->setQuery($base, (int) $this->getState('list.start'), (int) $this->getState('list.limit')); $return = $this->_db->loadObjectList('link_id'); // Check for a database error. if ($this->_db->getErrorNum()) { throw new Exception($this->_db->getErrorMsg(), 500); } // Get a new store id because this data is page specific. $store = $this->getStoreId('getResultsData', true); // Push the results into cache. $this->store($store, $return); // Return the results. return $this->retrieve($store); } /* * If there are optional or required search terms in the query, the * process of getting the results is more complicated. */ $start = 0; $limit = (int) $this->getState('match.limit'); $more = false; $items = array(); $sorted = array(); $maps = array(); $excluded = $this->getExcludedLinkIds(); /* * Iterate through the included search terms and group them by mapping * table suffix. This ensures that we never have to do more than 16 * queries to get a batch. This may seem like a lot but it is rarely * anywhere near 16 because of the improved mapping algorithm. */ foreach ($this->includedTerms as $token => $ids) { // Get the mapping table suffix. $suffix = JString::substr(md5(JString::substr($token, 0, 1)), 0, 1); // Initialize the mapping group. if (!array_key_exists($suffix, $maps)) { $maps[$suffix] = array(); } // Add the terms to the mapping group. $maps[$suffix] = array_merge($maps[$suffix], $ids); } /* * When the query contains search terms we need to find and process the * results iteratively using a do-while loop. */ do { // Create a container for the fetched results. $results = array(); $more = false; /* * Iterate through the mapping groups and load the results from each * mapping table. */ foreach ($maps as $suffix => $ids) { // Create a storage key for this set. $setId = $this->getStoreId('getResultsData:' . serialize(array_values($ids)) . ':' . $start . ':' . $limit); // Use the cached data if possible. if ($this->retrieve($setId)) { $temp = $this->retrieve($setId); } // Load the data from the database. else { // Adjust the query to join on the appropriate mapping table. $sql = clone($base); $sql->join('INNER', $this->_db->quoteName('#__finder_links_terms' . $suffix) . ' AS m ON m.link_id = l.link_id'); $sql->where('m.term_id IN (' . implode(',', $ids) . ')'); // Load the results from the database. $this->_db->setQuery($sql, $start, $limit); $temp = $this->_db->loadObjectList('link_id'); // Check for a database error. if ($this->_db->getErrorNum()) { throw new Exception($this->_db->getErrorMsg(), 500); } // Store this set in cache. $this->store($setId, $temp); // The data is keyed by link_id to ease caching, we don't need it till later. $temp = array_values($temp); } // Set the more flag to true if any of the sets equal the limit. $more = (count($temp) === $limit) ? true : false; // Merge the results. $results = array_merge($results, $temp); } // Check if there are any excluded terms to deal with. if (count($excluded)) { // Remove any results that match excluded terms. for ($i = 0, $c = count($results); $i < $c; $i++) { if (in_array($results[$i]->link_id, $excluded)) { unset($results[$i]); } } // Reset the array keys. $results = array_values($results); } /* * If we are ordering by relevance we have to add up the relevance * scores that are contained in the ordering field. */ if ($ordering === 'm.weight') { // Iterate through the set to extract the unique items. for ($i = 0, $c = count($results); $i < $c; $i++) { // Add the total weights for all included search terms. if (isset($sorted[$results[$i]->link_id])) { $sorted[$results[$i]->link_id] += (float) $results[$i]->ordering; } else { $sorted[$results[$i]->link_id] = (float) $results[$i]->ordering; } } } /* * If we are ordering by start date we have to add convert the * dates to unix timestamps. */ elseif ($ordering === 'l.start_date') { // Iterate through the set to extract the unique items. for ($i = 0, $c = count($results); $i < $c; $i++) { if (!isset($sorted[$results[$i]->link_id])) { $sorted[$results[$i]->link_id] = strtotime($results[$i]->ordering); } } } /* * If we are not ordering by relevance or date, we just have to add * the unique items to the set. */ else { // Iterate through the set to extract the unique items. for ($i = 0, $c = count($results); $i < $c; $i++) { if (!isset($sorted[$results[$i]->link_id])) { $sorted[$results[$i]->link_id] = $results[$i]->ordering; } } } // Sort the results. if ($direction === 'ASC') { natcasesort($items); } else { natcasesort($items); $items = array_reverse($items, true); } /* * If the query contains just optional search terms and we have * enough items for the page, we can stop here. */ if (empty($this->requiredTerms)) { // If we need more items and they're available, make another pass. if ($more && count($sorted) < ($this->getState('list.start') + $this->getState('list.limit'))) { // Increment the batch starting point and continue. $start += $limit; continue; } // Push the results into cache. $this->store($store, $sorted); // Return the requested set. return array_slice($this->retrieve($store), (int) $this->getState('list.start'), (int) $this->getState('list.limit'), true); } /* * The query contains required search terms so we have to iterate * over the items and remove any items that do not match all of the * required search terms. This is one of the most expensive steps * because a required token could theoretically eliminate all of * current terms which means we would have to loop through all of * the possibilities. */ foreach ($this->requiredTerms as $token => $required) { // Create a storage key for this set. $setId = $this->getStoreId('getResultsData:required:' . serialize(array_values($required)) . ':' . $start . ':' . $limit); // Use the cached data if possible. if ($this->retrieve($setId)) { $reqTemp = $this->retrieve($setId); } // Check if the token was matched. elseif (empty($required)) { return null; } // Load the data from the database. else { // Setup containers in case we have to make multiple passes. $reqMore = false; $reqStart = 0; $reqTemp = array(); do { // Get the map table suffix. $suffix = JString::substr(md5(JString::substr($token, 0, 1)), 0, 1); // Adjust the query to join on the appropriate mapping table. $sql = clone($base); $sql->join('INNER', $this->_db->quoteName('#__finder_links_terms' . $suffix) . ' AS m ON m.link_id = l.link_id'); $sql->where('m.term_id IN (' . implode(',', $required) . ')'); // Load the results from the database. $this->_db->setQuery($sql, $reqStart, $limit); $temp = $this->_db->loadObjectList('link_id'); // Check for a database error. if ($this->_db->getErrorNum()) { throw new Exception($this->_db->getErrorMsg(), 500); } // Set the required token more flag to true if the set equal the limit. $reqMore = (count($temp) === $limit) ? true : false; // Merge the matching set for this token. $reqTemp = $reqTemp + $temp; // Increment the term offset. $reqStart += $limit; } while ($reqMore == true); // Store this set in cache. $this->store($setId, $reqTemp); } // Remove any items that do not match the required term. $sorted = array_intersect_key($sorted, $reqTemp); } // If we need more items and they're available, make another pass. if ($more && count($sorted) < ($this->getState('list.start') + $this->getState('list.limit'))) { // Increment the batch starting point. $start += $limit; // Merge the found items. $items = array_merge($items, $sorted); continue; } // Otherwise, end the loop. else { // Set the found items. $items = $sorted; $more = false; } // End do-while loop. } while ($more === true); // Push the results into cache. $this->store($store, $items); // Return the requested set. return array_slice($this->retrieve($store), (int) $this->getState('list.start'), (int) $this->getState('list.limit'), true); } /** * Method to get an array of link ids that match excluded terms. * * @return array An array of links ids. * * @since 2.5 * @throws Exception on database error. */ protected function getExcludedLinkIds() { // Check if the search query has excluded terms. if (empty($this->excludedTerms)) { return array(); } // Get the store id. $store = $this->getStoreId('getExcludedLinkIds', false); // Use the cached data if possible. if ($this->retrieve($store)) { return $this->retrieve($store); } // Initialize containers. $links = array(); $maps = array(); /* * Iterate through the excluded search terms and group them by mapping * table suffix. This ensures that we never have to do more than 16 * queries to get a batch. This may seem like a lot but it is rarely * anywhere near 16 because of the improved mapping algorithm. */ foreach ($this->excludedTerms as $token => $id) { // Get the mapping table suffix. $suffix = JString::substr(md5(JString::substr($token, 0, 1)), 0, 1); // Initialize the mapping group. if (!array_key_exists($suffix, $maps)) { $maps[$suffix] = array(); } // Add the terms to the mapping group. $maps[$suffix][] = (int) $id; } /* * Iterate through the mapping groups and load the excluded links ids * from each mapping table. */ foreach ($maps as $suffix => $ids) { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Create the query to get the links ids. $query->select('link_id'); $query->from($db->quoteName('#__finder_links_terms' . $suffix)); $query->where($db->quoteName('term_id') . ' IN (' . implode(',', $ids) . ')'); $query->group($db->quoteName('link_id')); // Load the link ids from the database. $db->setQuery($query); $temp = $db->loadColumn(); // Check for a database error. if ($db->getErrorNum()) { throw new Exception($db->getErrorMsg(), 500); } // Merge the link ids. $links = array_merge($links, $temp); } // Sanitize the link ids. $links = array_unique($links); JArrayHelper::toInteger($links); // Push the link ids into cache. $this->store($store, $links); return $links; } /** * Method to get a subquery for filtering link ids mapped to specific * terms ids. * * @param array $terms An array of search term ids. * * @return JDatabaseQuery A database object. * * @since 2.5 */ protected function getTermsQuery($terms) { // Create the SQL query to get the matching link ids. //@TODO: Impact of removing SQL_NO_CACHE? $db = $this->getDbo(); $query = $db->getQuery(true); $query->select('SQL_NO_CACHE link_id'); $query->from('#__finder_links_terms'); $query->where('term_id IN (' . implode(',', $terms) . ')'); return $query; } /** * Method to get a store id based on model the configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id An identifier string to generate the store id. [optional] * @param boolean $page True to store the data paged, false to store all data. [optional] * * @return string A store id. * * @since 2.5 */ protected function getStoreId($id = '', $page = true) { // Get the query object. $query = $this->getQuery(); // Add the search query state. $id .= ':' . $query->input; $id .= ':' . $query->language; $id .= ':' . $query->filter; $id .= ':' . serialize($query->filters); $id .= ':' . $query->date1; $id .= ':' . $query->date2; $id .= ':' . $query->when1; $id .= ':' . $query->when2; if ($page) { // Add the list state for page specific data. $id .= ':' . $this->getState('list.start'); $id .= ':' . $this->getState('list.limit'); $id .= ':' . $this->getState('list.ordering'); $id .= ':' . $this->getState('list.direction'); } return parent::getStoreId($id); } /** * Method to auto-populate the model state. Calling getState in this method will result in recursion. * * @param string $ordering An optional ordering field. [optional] * @param string $direction An optional direction. [optional] * * @return void * * @since 2.5 */ protected function populateState($ordering = null, $direction = null) { // Get the configuration options. $app = JFactory::getApplication(); $input = $app->input; $params = $app->getParams(); $user = JFactory::getUser(); $filter = JFilterInput::getInstance(); $this->setState('filter.language', $app->getLanguageFilter()); // Setup the stemmer. if ($params->get('stem', 1) && $params->get('stemmer', 'porter_en')) { FinderIndexerHelper::$stemmer = FinderIndexerStemmer::getInstance($params->get('stemmer', 'porter_en')); } // Initialize variables. $request = $input->request; $options = array(); // Get the query string. $options['input'] = !is_null($request->get('q')) ? $request->get('q', '', 'string') : $params->get('q'); $options['input'] = $filter->clean($options['input'], 'string'); // Get the empty query setting. $options['empty'] = $params->get('allow_empty_query', 0); // Get the query language. $options['language'] = !is_null($request->get('l')) ? $request->get('l', '', 'cmd') : $params->get('l'); $options['language'] = $filter->clean($options['language'], 'cmd'); // Get the static taxonomy filters. $options['filter'] = !is_null($request->get('f')) ? $request->get('f', '', 'int') : $params->get('f'); $options['filter'] = $filter->clean($options['filter'], 'int'); // Get the dynamic taxonomy filters. $options['filters'] = !is_null($request->get('t')) ? $request->get('t', '', 'array') : $params->get('t'); $options['filters'] = $filter->clean($options['filters'], 'array'); JArrayHelper::toInteger($options['filters']); // Get the start date and start date modifier filters. $options['date1'] = !is_null($request->get('d1')) ? $request->get('d1', '', 'string') : $params->get('d1'); $options['date1'] = $filter->clean($options['date1'], 'string'); $options['when1'] = !is_null($request->get('w1')) ? $request->get('w1', '', 'string') : $params->get('w1'); $options['when1'] = $filter->clean($options['when1'], 'string'); // Get the end date and end date modifier filters. $options['date2'] = !is_null($request->get('d2')) ? $request->get('d2', '', 'string') : $params->get('d2'); $options['date2'] = $filter->clean($options['date2'], 'string'); $options['when2'] = !is_null($request->get('w2')) ? $request->get('w2', '', 'string') : $params->get('w2'); $options['when2'] = $filter->clean($options['when2'], 'string'); // Load the query object. $this->query = new FinderIndexerQuery($options); // Load the query token data. $this->excludedTerms = $this->query->getExcludedTermIds(); $this->includedTerms = $this->query->getIncludedTermIds(); $this->requiredTerms = $this->query->getRequiredTermIds(); // Load the list state. $this->setState('list.start', $input->get('limitstart', 0, 'uint')); $this->setState('list.limit', $input->get('limit', $app->getCfg('list_limit', 20), 'uint')); // Load the sort ordering. $order = $params->get('sort_order', 'relevance'); switch ($order) { case 'date': $this->setState('list.ordering', 'l.start_date'); break; case 'price': $this->setState('list.ordering', 'l.list_price'); break; case ($order == 'relevance' && !empty($this->includedTerms)): $this->setState('list.ordering', 'm.weight'); break; default: $this->setState('list.ordering', 'l.link_id'); break; } // Load the sort direction. $dirn = $params->get('sort_direction', 'desc'); switch ($dirn) { case 'asc': $this->setState('list.direction', 'ASC'); break; default: case 'desc': $this->setState('list.direction', 'DESC'); break; } // Set the match limit. $this->setState('match.limit', 1000); // Load the parameters. $this->setState('params', $params); // Load the user state. $this->setState('user.id', (int) $user->get('id')); $this->setState('user.groups', $user->getAuthorisedViewLevels()); } /** * Method to retrieve data from cache. * * @param string $id The cache store id. * @param boolean $persistent Flag to enable the use of external cache. [optional] * * @return mixed The cached data if found, null otherwise. * * @since 2.5 */ protected function retrieve($id, $persistent = true) { $data = null; // Use the internal cache if possible. if (isset($this->cache[$id])) { return $this->cache[$id]; } // Use the external cache if data is persistent. if ($persistent) { $data = JFactory::getCache($this->context, 'output')->get($id); $data = $data ? unserialize($data) : null; } // Store the data in internal cache. if ($data) { $this->cache[$id] = $data; } return $data; } /** * Method to store data in cache. * * @param string $id The cache store id. * @param mixed $data The data to cache. * @param boolean $persistent Flag to enable the use of external cache. [optional] * * @return boolean True on success, false on failure. * * @since 2.5 */ protected function store($id, $data, $persistent = true) { // Store the data in internal cache. $this->cache[$id] = $data; // Store the data in external cache if data is persistent. if ($persistent) { return JFactory::getCache($this->context, 'output')->store(serialize($data), $id); } return true; } } PK2?\+   models/suggestions.phpnuW+A $v) { $items[$k] = $v->term; } return $items; } /** * Method to build a database query to load the list data. * * @return JDatabaseQuery A database query * * @since 2.5 */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select required fields $query->select('t.term'); $query->from($db->quoteName('#__finder_terms') . ' AS t'); $query->where('t.term LIKE ' . $db->quote($db->escape($this->getState('input'), true) . '%')); $query->where('t.common = 0'); $query->order('t.links DESC'); $query->order('t.weight DESC'); return $query; } /** * Method to get a store id based on model the configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id An identifier string to generate the store id. [optional] * * @return string A store id. * * @since 2.5 */ protected function getStoreId($id = '') { // Add the search query state. $id .= ':' . $this->getState('input'); $id .= ':' . $this->getState('language'); // Add the list state. $id .= ':' . $this->getState('list.start'); $id .= ':' . $this->getState('list.limit'); return parent::getStoreId($id); } /** * Method to auto-populate the model state. Calling getState in this method will result in recursion. * * @return void * * @since 2.5 */ protected function populateState() { // Get the configuration options. $app = JFactory::getApplication(); $input = $app->input; $params = JComponentHelper::getParams('com_finder'); $user = JFactory::getUser(); // Get the query input. $this->setState('input', $input->request->get('q', '', 'string')); $this->setState('language', $input->request->get('l', '', 'string')); // Load the list state. $this->setState('list.start', 0); $this->setState('list.limit', 10); // Load the parameters. $this->setState('params', $params); // Load the user state. $this->setState('user.id', (int) $user->get('id')); } } PK2?\M/helpers/route.phpnuW+A 'search', 'q' => $q, 'f' => $f); $item = self::getItemid($query); // Get the base route. $uri = clone(JUri::getInstance('index.php?option=com_finder&view=search')); // Add the pre-defined search filter if present. if ($f !== null) { $uri->setVar('f', $f); } // Add the search query string if present. if ($q !== null) { $uri->setVar('q', $q); } // Add the menu item id if present. if ($item !== null) { $uri->setVar('Itemid', $item); } return $uri->toString(array('path', 'query')); } /** * Method to get the route for an advanced search page. * * @param integer $f The search filter id. [optional] * @param string $q The search query string. [optional] * * @return string The advanced search route. * * @since 2.5 */ public static function getAdvancedRoute($f = null, $q = null) { // Get the menu item id. $query = array('view' => 'advanced', 'q' => $q, 'f' => $f); $item = self::getItemid($query); // Get the base route. $uri = clone(JUri::getInstance('index.php?option=com_finder&view=advanced')); // Add the pre-defined search filter if present. if ($q !== null) { $uri->setVar('f', $f); } // Add the search query string if present. if ($q !== null) { $uri->setVar('q', $q); } // Add the menu item id if present. if ($item !== null) { $uri->setVar('Itemid', $item); } return $uri->toString(array('path', 'query')); } /** * Method to get the most appropriate menu item for the route based on the * supplied query needles. * * @param array $query An array of URL parameters. * * @return mixed An integer on success, null otherwise. * * @since 2.5 */ public static function getItemid($query) { static $items, $active; // Get the menu items for com_finder. if (!$items || !$active) { $app = JFactory::getApplication('site'); $com = JComponentHelper::getComponent('com_finder'); $menu = $app->getMenu(); $active = $menu->getActive(); $items = $menu->getItems('component_id', $com->id); $items = is_array($items) ? $items : array(); } // Try to match the active view and filter. if ($active && @$active->query['view'] == @$query['view'] && @$active->query['f'] == @$query['f']) { return $active->id; } // Try to match the view, query, and filter. foreach ($items as $item) { if (@$item->query['view'] == @$query['view'] && @$item->query['q'] == @$query['q'] && @$item->query['f'] == @$query['f']) { return $item->id; } } // Try to match the view and filter. foreach ($items as $item) { if (@$item->query['view'] == @$query['view'] && @$item->query['f'] == @$query['f']) { return $item->id; } } // Try to match the view. foreach ($items as $item) { if (@$item->query['view'] == @$query['view']) { return $item->id; } } return null; } } PK2?\==helpers/html/filter.phpnuW+AgetQuery(true); $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); $html = ''; $in = ''; $filter = null; // Get the configuration options. $filterId = array_key_exists('filter_id', $options) ? $options['filter_id'] : null; $activeNodes = array_key_exists('selected_nodes', $options) ? $options['selected_nodes'] : array(); $activeDates = array_key_exists('selected_dates', $options) ? $options['selected_dates'] : array(); $classSuffix = array_key_exists('class_suffix', $options) ? $options['class_suffix'] : ''; $loadMedia = array_key_exists('load_media', $options) ? $options['load_media'] : true; $showDates = array_key_exists('show_date_filters', $options) ? $options['show_date_filters'] : false; // Load the predefined filter if specified. if (!empty($filterId)) { $query->select('f.' . $db->quoteName('data') . ', f.' . $db->quoteName('params')); $query->from($db->quoteName('#__finder_filters') . ' AS f'); $query->where($db->quoteName('f').'.' . $db->quoteName('filter_id') . ' = ' . (int) $filterId); // Load the filter data. $db->setQuery($query); $filter = $db->loadObject(); // Check for an error. if ($db->getErrorNum()) { return null; } // Initialize the filter parameters. if ($filter) { $registry = new JRegistry; $registry->loadString($filter->params); $filter->params = $registry; } } // Build the query to get the branch data and the number of child nodes. $query->clear(); $query->select('t.*, count(c.id) AS children'); $query->from($db->quoteName('#__finder_taxonomy') . ' AS t'); $query->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS c ON c.parent_id = t.id'); $query->where($db->quoteName('t.parent_id') . ' = 1'); $query->where($db->quoteName('t.state') . ' = 1'); $query->where($db->quoteName('t.access') . ' IN (' . $groups . ')'); $query->where($db->quoteName('c.state') . ' = 1'); $query->where($db->quoteName('c.access') . ' IN (' . $groups . ')'); $query->group('t.id, t.parent_id, t.state, t.access, t.ordering, t.title, c.parent_id'); $query->order('t.ordering, t.title'); // Limit the branch children to a predefined filter. if ($filter) { $query->where('c.id IN(' . $filter->data . ')'); } // Load the branches. $db->setQuery($query); $branches = $db->loadObjectList('id'); // Check for an error. if ($db->getErrorNum()) { return null; } // Check that we have at least one branch. if (count($branches) === 0) { return null; } // Load the CSS/JS resources. if ($loadMedia) { JHtml::stylesheet('com_finder/sliderfilter.css', false, true, false); JHtml::script('com_finder/sliderfilter.js', false, true); } // Load plug-in language files. FinderHelperLanguage::loadPluginLanguage(); // Start the widget. $html .= '
'; $html .= '
'; $html .= '
'; $html .= ''; $html .= '
'; // Iterate through the branches to build the branch selector. foreach ($branches as $bk => $bv) { // If the multi-lang plug-in is enabled then drop the language branch. if ($bv->title == 'Language' && JLanguageMultilang::isEnabled()) { continue; } $html .= '
'; $html .= ''; $html .= '
'; } $html .= '
'; $html .= '
'; // Iterate through the branches and build the branch groups. foreach ($branches as $bk => $bv) { // If the multi-lang plug-in is enabled then drop the language branch. if ($bv->title == 'Language' && JLanguageMultilang::isEnabled()) { continue; } // Build the query to get the child nodes for this branch. $query->clear(); $query->select('t.*'); $query->from($db->quoteName('#__finder_taxonomy') . ' AS t'); $query->where($db->quoteName('t.parent_id') . ' = ' . (int) $bk); $query->where($db->quoteName('t.state') . ' = 1'); $query->where($db->quoteName('t.access') . ' IN (' . $groups . ')'); $query->order('t.ordering, t.title'); // Load the branches. $db->setQuery($query); $nodes = $db->loadObjectList('id'); // Check for an error. if ($db->getErrorNum()) { return null; } // Translate node titles if possible. $lang = JFactory::getLanguage(); foreach ($nodes as $nk => $nv) { $key = FinderHelperLanguage::branchPlural($nv->title); if ($lang->hasKey($key)) { $nodes[$nk]->title = JText::_($key); } } // Start the group. $html .= '
'; $html .= '
'; $html .= ''; $html .= '
'; // Populate the group with nodes. foreach ($nodes as $nk => $nv) { // Determine if the node should be checked. $checked = in_array($nk, $activeNodes) ? ' checked="checked"' : ''; // Build a node. $html .= '
'; $html .= ''; $html .= '
'; } // Close the group. $html .= '
'; } // Close the widget. $html .= '
'; $html .= '
'; $html .= '
'; return $html; } /** * Method to generate filters using select box drop down controls. * * @param FinderIndexerQuery $query A FinderIndexerQuery object. * @param array $options An array of options. * * @return mixed A rendered HTML widget on success, null otherwise. * * @since 2.5 */ public static function select($query, $options) { $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); $filter = null; // Get the configuration options. $classSuffix = $options->get('class_suffix', null); $loadMedia = $options->get('load_media', true); $showDates = $options->get('show_date_filters', false); // Try to load the results from cache. $cache = JFactory::getCache('com_finder', ''); $cacheId = 'filter_select_' . serialize(array($query->filter, $options, $groups, JFactory::getLanguage()->getTag())); // Check the cached results. if (!($branches = $cache->get($cacheId))) { $db = JFactory::getDBO(); $sql = $db->getQuery(true); // Load the predefined filter if specified. if (!empty($query->filter)) { $sql->select($db->quoteName('f') . '.' . $db->quoteName('data') . ', '. $db->quoteName('f') . '.' . $db->quoteName('params')); $sql->from($db->quoteName('#__finder_filters') . ' AS f'); $sql->where($db->quoteName('f') . '.' . $db->quoteName('filter_id') . ' = ' . (int) $query->filter); // Load the filter data. $db->setQuery($sql); $filter = $db->loadObject(); // Check for an error. if ($db->getErrorNum()) { return null; } // Initialize the filter parameters. if ($filter) { $registry = new JRegistry; $registry->loadString($filter->params); $filter->params = $registry; } } // Build the query to get the branch data and the number of child nodes. $sql->clear(); $sql->select('t.*, count(c.id) AS children'); $sql->from($db->quoteName('#__finder_taxonomy') . ' AS t'); $sql->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS c ON c.parent_id = t.id'); $sql->where($db->quoteName('t') . '.' . $db->quoteName('parent_id') . ' = 1'); $sql->where($db->quoteName('t') . '.' . $db->quoteName('state') . ' = 1'); $sql->where($db->quoteName('t') . '.' . $db->quoteName('access') . ' IN (' . $groups . ')'); $sql->where($db->quoteName('c') . '.' . $db->quoteName('state') . ' = 1'); $sql->where($db->quoteName('t') . '.' . $db->quoteName('access') . ' IN (' . $groups . ')'); $sql->group($db->quoteName('t') . '.' . $db->quoteName('id')); $sql->order('t.ordering, t.title'); // Limit the branch children to a predefined filter. if (!empty($filter->data)) { $sql->where('c.id IN(' . $filter->data . ')'); } // Load the branches. $db->setQuery($sql); $branches = $db->loadObjectList('id'); // Check for an error. if ($db->getErrorNum()) { return null; } // Check that we have at least one branch. if (count($branches) === 0) { return null; } // Iterate through the branches and build the branch groups. foreach ($branches as $bk => $bv) { // If the multi-lang plug-in is enabled then drop the language branch. if ($bv->title == 'Language' && JLanguageMultilang::isEnabled()) { continue; } // Build the query to get the child nodes for this branch. $sql->clear(); $sql->select('t.*'); $sql->from($db->quoteName('#__finder_taxonomy') . ' AS t'); $sql->where($db->quoteName('t') . '.' . $db->quoteName('parent_id') . ' = ' . (int) $bk); $sql->where($db->quoteName('t') . '.' . $db->quoteName('state') . ' = 1'); $sql->where($db->quoteName('t') . '.' . $db->quoteName('access') . ' IN (' . $groups . ')'); $sql->order('t.ordering, t.title'); // Limit the nodes to a predefined filter. if (!empty($filter->data)) { $sql->where('t.id IN(' . $filter->data . ')'); } // Load the branches. $db->setQuery($sql); $branches[$bk]->nodes = $db->loadObjectList('id'); // Check for an error. if ($db->getErrorNum()) { return null; } // Translate branch nodes if possible. $language = JFactory::getLanguage(); foreach($branches[$bk]->nodes as $node_id => $node) { $key = FinderHelperLanguage::branchPlural($node->title); if ($language->hasKey($key)) { $branches[$bk]->nodes[$node_id]->title = JText::_($key); } } // Add the Search All option to the branch. array_unshift($branches[$bk]->nodes, array('id' => null, 'title' => JText::_('COM_FINDER_FILTER_SELECT_ALL_LABEL'))); } // Store the data in cache. $cache->store($branches, $cacheId); } $html = ''; // Add the dates if enabled. if ($showDates) { $html .= JHtml::_('filter.dates', $query, $options); } $html .= '
    '; // Iterate through all branches and build code. foreach ($branches as $bk => $bv) { // If the multi-lang plug-in is enabled then drop the language branch. if ($bv->title == 'Language' && JLanguageMultilang::isEnabled()) { continue; } $active = null; // Check if the branch is in the filter. if (array_key_exists($bv->title, $query->filters)) { // Get the request filters. $temp = JFactory::getApplication()->input->request->get('t', array(), 'array'); // Search for active nodes in the branch and get the active node. $active = array_intersect($temp, $query->filters[$bv->title]); $active = count($active) === 1 ? array_shift($active) : null; } $html .= '
  • '; $html .= ''; $html .= JHtml::_('select.genericlist', $branches[$bk]->nodes, 't[]', 'class="inputbox"', 'id', 'title', $active, 'tax-' . JFilterOutput::stringUrlSafe($bv->title)); $html .= '
  • '; } // Close the widget. $html .= '
'; // Load the CSS/JS resources. if ($loadMedia) { JHtml::stylesheet('com_finder/sliderfilter.css', false, true, false); } return $html; } /** * Method to generate fields for filtering dates * * @param FinderIndexerQuery $query A FinderIndexerQuery object. * @param array $options An array of options. * * @return mixed A rendered HTML widget on success, null otherwise. * * @since 2.5 */ public static function dates($query, $options) { $html = ''; // Get the configuration options. $classSuffix = $options->get('class_suffix', null); $loadMedia = $options->get('load_media', true); $showDates = $options->get('show_date_filters', false); if (!empty($showDates)) { // Build the date operators options. $operators = array(); $operators[] = JHtml::_('select.option', 'before', JText::_('COM_FINDER_FILTER_DATE_BEFORE')); $operators[] = JHtml::_('select.option', 'exact', JText::_('COM_FINDER_FILTER_DATE_EXACTLY')); $operators[] = JHtml::_('select.option', 'after', JText::_('COM_FINDER_FILTER_DATE_AFTER')); // Load the CSS/JS resources. if ($loadMedia) { JHtml::stylesheet('com_finder/dates.css', false, true, false); } // Open the widget. $html .= '
    '; // Start date filter. $html .= '
  • '; $html .= ''; $html .= '
    '; $html .= JHtml::_('select.genericlist', $operators, 'w1', 'class="inputbox filter-date-operator"', 'value', 'text', $query->when1, 'finder-filter-w1'); $html .= JHtml::calendar($query->date1, 'd1', 'filter_date1', '%Y-%m-%d', 'title="' . JText::_('COM_FINDER_FILTER_DATE1_DESC') . '"'); $html .= '
  • '; // End date filter. $html .= '
  • '; $html .= ''; $html .= '
    '; $html .= JHtml::_('select.genericlist', $operators, 'w2', 'class="inputbox filter-date-operator"', 'value', 'text', $query->when2, 'finder-filter-w2'); $html .= JHtml::calendar($query->date2, 'd2', 'filter_date2', '%Y-%m-%d', 'title="' . JText::_('COM_FINDER_FILTER_DATE2_DESC') . '"'); $html .= '
  • '; // Close the widget. $html .= '
'; } return $html; } } PK2?\i֯helpers/html/query.phpnuW+Aincluded as $token) { if ($token->required && (!isset($token->derived) || $token->derived == false)) { $parts[] = '' . JText::sprintf('COM_FINDER_QUERY_TOKEN_REQUIRED', $token->term) . ''; } } // Process the optional tokens. foreach ($query->included as $token) { if (!$token->required && (!isset($token->derived) || $token->derived == false)) { $parts[] = '' . JText::sprintf('COM_FINDER_QUERY_TOKEN_OPTIONAL', $token->term) . ''; } } // Process the excluded tokens. foreach ($query->excluded as $token) { if (!isset($token->derived) || $token->derived == false) { $parts[] = '' . JText::sprintf('COM_FINDER_QUERY_TOKEN_EXCLUDED', $token->term) . ''; } } // Process the start date. if ($query->date1) { $date = JFactory::getDate($query->date1)->format(JText::_('DATE_FORMAT_LC')); $parts[] = '' . JText::sprintf('COM_FINDER_QUERY_START_DATE', $query->when1, $date) . ''; } // Process the end date. if ($query->date2) { $date = JFactory::getDate($query->date2)->format(JText::_('DATE_FORMAT_LC')); $parts[] = '' . JText::sprintf('COM_FINDER_QUERY_END_DATE', $query->when2, $date) . ''; } // Process the taxonomy filters. if (!empty($query->filters)) { // Get the filters in the request. $t = JFactory::getApplication()->input->request->get('t', array(), 'array'); // Process the taxonomy branches. foreach ($query->filters as $branch => $nodes) { // Process the taxonomy nodes. $lang = JFactory::getLanguage(); foreach ($nodes as $title => $id) { // Translate the title for Types $key = FinderHelperLanguage::branchPlural($title); if ($lang->hasKey($key)) { $title = JText::_($key); } // Don't include the node if it is not in the request. if (!in_array($id, $t)) { continue; } // Add the node to the explanation. $bv = JString::strtolower($branch); $nv = JString::strtolower($title); $parts[] = '' . JText::sprintf('COM_FINDER_QUERY_TAXONOMY_NODE', $title, JText::_(FinderHelperLanguage::branchSingular($branch))) . ''; } } } // Build the interpreted query. return count($parts) ? JText::sprintf('COM_FINDER_QUERY_TOKEN_INTERPRETED', implode(JText::_('COM_FINDER_QUERY_TOKEN_GLUE'), $parts)) : null; } /** * Method to get the suggested search query. * * @param FinderIndexerQuery $query A FinderIndexerQuery object. * * @return mixed String if there is a suggestion, false otherwise. * * @since 2.5 */ public static function suggested(FinderIndexerQuery $query) { $suggested = false; // Check if the query input is empty. if (empty($query->input)) { return $suggested; } // Check if there were any ignored or included keywords. if (count($query->ignored) || count($query->included)) { $suggested = $query->input; // Replace the ignored keyword suggestions. foreach (array_reverse($query->ignored) as $token) { if (isset($token->suggestion)) { $suggested = str_replace($token->term, $token->suggestion, $suggested); } } // Replace the included keyword suggestions. foreach (array_reverse($query->included) as $token) { if (isset($token->suggestion)) { $suggested = str_replace($token->term, $token->suggestion, $suggested); } } // Check if we made any changes. if ($suggested == $query->input) { $suggested = false; } } return $suggested; } } PKj>\6 index.htmlnuW+APKj>\6Xmaps/index.htmlnuW+APKj>\)maps/.htaccessnuW+APKj>\8rmaps/default.phpnuW+APKj>\) .htaccessnuW+APKj>\6statistics/index.htmlnuW+APKj>\)statistics/.htaccessnuW+APKj>\)index/.htaccessnuW+APKj>\6iindex/index.htmlnuW+APKj>\6ǚ--index/default.phpnuW+APKj>\)52filters/.htaccessnuW+APKj>\62filters/index.htmlnuW+APKj>\DWWU3filters/default.phpnuW+APKj>\)Jfilter/.htaccessnuW+APKj>\6Kfilter/index.htmlnuW+APKx>\s  Ljs/highlighter.jsnuW+APKx>\ȇ**Xjs/sliderfilter.jsnuW+APKx>\I4o??kjs/autocompleter.jsnuW+APKx>\) Fjs/.htaccessnuW+APKx>\6 js/index.htmlnuW+APKx>\y;C88 \js/indexer.jsnuW+APKx>\WU js/finder.jsnuW+APKx>\mc$_DDcss/sliderfilter.cssnuW+APKx>\) <css/.htaccessnuW+APKx>\6css/index.htmlnuW+APKx>\jTcss/selectfilter.cssnuW+APKx>\ہ++fcss/indexer.cssnuW+APKx>\JbW css/dates.cssnuW+APKx>\iwWxxcss/finder.cssnuW+APK>\)tcontrollers/.htaccessnuW+APK>\68controllers/index.htmlnuW+APK>\Mcontrollers/filters.phpnuW+APK>\YZ$$controllers/indexer.json.phpnuW+APK>\h̀controllers/filter.phpnuW+APK>\G;controllers/maps.phpnuW+APK>\e.$controllers/index.phpnuW+APK>\BTZZ+tables/filter.phpnuW+APK>\] 8&Etables/link.phpnuW+APK>\ H H Gtables/map.phpnuW+APK>\)uRtables/.htaccessnuW+APK>\64Stables/index.htmlnuW+APK>\6Sviews/index.htmlnuW+APK>\VSviews/filter/index.htmlnuW+APK>\)WTviews/filter/tmpl/.htaccessnuW+APK>\y !Uviews/filter/tmpl/edit.phpnuW+APK>\V4bviews/filter/tmpl/index.htmlnuW+APK>\ 0+ + bviews/filter/view.html.phpnuW+APK>\)nviews/filter/.htaccessnuW+APK>\6 nviews/statistics/tmpl/index.htmlnuW+APK>\g/!Goviews/statistics/tmpl/default.phpnuW+APK>\)}wviews/statistics/tmpl/.htaccessnuW+APK>\)Kxviews/statistics/.htaccessnuW+APK>\6yviews/statistics/index.htmlnuW+APK>\ʫ}yviews/statistics/view.html.phpnuW+APK>\Vv}views/indexer/index.htmlnuW+APK>\ʩ]$!!}views/indexer/tmpl/default.phpnuW+APK>\)Lviews/indexer/tmpl/.htaccessnuW+APK>\Vviews/indexer/tmpl/index.htmlnuW+APK>\)6 88views/indexer/view.html.phpnuW+APK>\)views/indexer/.htaccessnuW+APK>\U/  ̆views/filters/view.html.phpnuW+APK>\Vviews/filters/tmpl/index.htmlnuW+APK>\N4yfviews/filters/tmpl/default.phpnuW+APK>\)views/filters/tmpl/.htaccessnuW+APK>\Vdviews/filters/index.htmlnuW+APK>\)˨views/filters/.htaccessnuW+APK>\5*= views/index/view.html.phpnuW+APK>\zU}rviews/index/tmpl/default.phpnuW+APK>\)bviews/index/tmpl/.htaccessnuW+APK>\V+views/index/tmpl/index.htmlnuW+APK>\)views/index/.htaccessnuW+APK>\VYviews/index/index.htmlnuW+APK>\)views/.htaccessnuW+APK>\V|views/maps/index.htmlnuW+APK>\Vviews/maps/tmpl/index.htmlnuW+APK>\)Iviews/maps/tmpl/.htaccessnuW+APK>\U{l}}views/maps/tmpl/default.phpnuW+APK>\ݴi views/maps/view.html.phpnuW+APK>\)views/maps/.htaccessnuW+APK>\9`Ofmodels/statistics.phpnuW+APK>\Sn ;models/forms/filter.xmlnuW+APK>\)Zmodels/forms/.htaccessnuW+APK>\6models/forms/index.htmlnuW+APK>\JFaamodels/fields/searchfilter.phpnuW+APK>\63 models/fields/index.htmlnuW+APK>\1  models/fields/directories.phpnuW+APK>\)models/fields/.htaccessnuW+APK>\3}F F models/filter.phpnuW+APK>\)&%models/.htaccessnuW+APK>\dIj--%models/index.phpnuW+APK>\6Smodels/index.htmlnuW+APK>\_XTmodels/indexer.phpnuW+APK>\K%%_Vmodels/maps.phpnuW+APK>\@{models/filters.phpnuW+APK>\aY<<sql/install.mysql.sqlnuW+APK>\) sql/.htaccessnuW+APK>\6sql/index.htmlnuW+APK>\)3sql/install.postgresql.sqlnuW+APK>\1iww^osql/uninstall.mysql.sqlnuW+APK>\|wwtsql/uninstall.postgresql.sqlnuW+APK>\)xhelpers/.htaccessnuW+APK>\6yhelpers/index.htmlnuW+APK>\/ yhelpers/language.phpnuW+APK>\eâ77̅helpers/indexer/helper.phpnuW+APK>\6helpers/indexer/index.htmlnuW+APK>\) helpers/indexer/.htaccessnuW+APK>\}lW W helpers/indexer/parser.phpnuW+APK>\>YYhelpers/indexer/indexer.phpnuW+APK>\߶ɥ-hhelpers/indexer/parser/txt.phpnuW+APK>\6!Zkhelpers/indexer/parser/index.htmlnuW+APK>\) khelpers/indexer/parser/.htaccessnuW+APK>\J\ ,VEE qhelpers/indexer/parser/html.phpnuW+APK>\8\#'#'%vhelpers/indexer/stemmer/porter_en.phpnuW+APK>\6"helpers/indexer/stemmer/index.htmlnuW+APK>\ $helpers/indexer/stemmer/snowball.phpnuW+APK>\)!helpers/indexer/stemmer/.htaccessnuW+APK>\vhelpers/indexer/stemmer.phpnuW+APK>\HV helpers/indexer/token.phpnuW+APK>\ehelpers/indexer/query.phpnuW+APK>\|/^/^Rhelpers/indexer/adapter.phpnuW+APK>\q2..6helpers/indexer/taxonomy.phpnuW+APK>\ddp[ [ helpers/indexer/result.phpnuW+APK>\֌QQDhelpers/finder.phpnuW+APK>\ql l helpers/html/finder.phpnuW+APK>\6helpers/html/index.htmlnuW+APK>\)helpers/html/.htaccessnuW+APK>\/&^ config.xmlnuW+APK>\GHH0controller.phpnuW+APK>\ 7access.xmlnuW+APK>\`[ :finder.xmlnuW+APK>\1 Bfinder.phpnuW+APK2?\i ? Eviews/search/view.opensearch.phpnuW+APK2?\ooKviews/search/view.html.phpnuW+APK2?\En n %eviews/search/tmpl/default_results.phpnuW+APK2?\6qviews/search/tmpl/index.htmlnuW+APK2?\)qviews/search/tmpl/.htaccessnuW+APK2?\v "rviews/search/tmpl/default_form.phpnuW+APK2?\Izz$views/search/tmpl/default_result.phpnuW+APK2?\Uȁtviews/search/tmpl/default.phpnuW+APK2?\ܔ; Bviews/search/tmpl/default.xmlnuW+APK2?\ cviews/search/view.feed.phpnuW+APK2?\)Qviews/search/.htaccessnuW+APK2?\6views/search/index.htmlnuW+APK2?\{views/search/metadata.xmlnuW+APK2?\;; ~controllers/suggestions.json.phpnuW+APK2?\&   router.phpnuW+APK2?\AOOXmodels/search.phpnuW+APK2?\+   Kmodels/suggestions.phpnuW+APK2?\M/@Xhelpers/route.phpnuW+APK2?\==ghelpers/html/filter.phpnuW+APK2?\i֯jhelpers/html/query.phpnuW+APKF3_