categories.php
10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
<?php
/**
* @package Joomla.Plugin
* @subpackage Finder.Categories
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\Registry\Registry;
JLoader::register('FinderIndexerAdapter', JPATH_ADMINISTRATOR . '/components/com_finder/helpers/indexer/adapter.php');
/**
* Smart Search adapter for Joomla Categories.
*
* @since 2.5
*/
class PlgFinderCategories extends FinderIndexerAdapter
{
/**
* The plugin identifier.
*
* @var string
* @since 2.5
*/
protected $context = 'Categories';
/**
* The extension name.
*
* @var string
* @since 2.5
*/
protected $extension = 'com_categories';
/**
* The sublayout to use when rendering the results.
*
* @var string
* @since 2.5
*/
protected $layout = 'category';
/**
* The type of content that the adapter indexes.
*
* @var string
* @since 2.5
*/
protected $type_title = 'Category';
/**
* The table name.
*
* @var string
* @since 2.5
*/
protected $table = '#__categories';
/**
* The field the published state is stored in.
*
* @var string
* @since 2.5
*/
protected $state_field = 'published';
/**
* Load the language file on instantiation.
*
* @var boolean
* @since 3.1
*/
protected $autoloadLanguage = true;
/**
* Method to remove the link information for items that have been deleted.
*
* @param string $context The context of the action being performed.
* @param JTable $table A JTable object containing the record to be deleted
*
* @return boolean True on success.
*
* @since 2.5
* @throws Exception on database error.
*/
public function onFinderDelete($context, $table)
{
if ($context === 'com_categories.category')
{
$id = $table->id;
}
elseif ($context === 'com_finder.index')
{
$id = $table->link_id;
}
else
{
return true;
}
// Remove item from the index.
return $this->remove($id);
}
/**
* Smart Search after save content method.
* Reindexes the link information for a category that has been saved.
* It also makes adjustments if the access level of the category has changed.
*
* @param string $context The context of the category passed to the plugin.
* @param JTable $row A JTable object.
* @param boolean $isNew True if the category has just been created.
*
* @return boolean True on success.
*
* @since 2.5
* @throws Exception on database error.
*/
public function onFinderAfterSave($context, $row, $isNew)
{
// We only want to handle categories here.
if ($context === 'com_categories.category')
{
// Check if the access levels are different.
if (!$isNew && $this->old_access != $row->access)
{
// Process the change.
$this->itemAccessChange($row);
}
// Reindex the category item.
$this->reindex($row->id);
// Check if the parent access level is different.
if (!$isNew && $this->old_cataccess != $row->access)
{
$this->categoryAccessChange($row);
}
}
return true;
}
/**
* Smart Search before content save method.
* This event is fired before the data is actually saved.
*
* @param string $context The context of the category passed to the plugin.
* @param JTable $row A JTable object.
* @param boolean $isNew True if the category is just about to be created.
*
* @return boolean True on success.
*
* @since 2.5
* @throws Exception on database error.
*/
public function onFinderBeforeSave($context, $row, $isNew)
{
// We only want to handle categories here.
if ($context === 'com_categories.category')
{
// Query the database for the old access level and the parent if the item isn't new.
if (!$isNew)
{
$this->checkItemAccess($row);
$this->checkCategoryAccess($row);
}
}
return true;
}
/**
* Method to update the link information for items that have been changed
* from outside the edit screen. This is fired when the item is published,
* unpublished, archived, or unarchived from the list view.
*
* @param string $context The context for the category passed to the plugin.
* @param array $pks An array of primary key ids of the category that has changed state.
* @param integer $value The value of the state that the category has been changed to.
*
* @return void
*
* @since 2.5
*/
public function onFinderChangeState($context, $pks, $value)
{
// We only want to handle categories here.
if ($context === 'com_categories.category')
{
/*
* The category published state is tied to the parent category
* published state so we need to look up all published states
* before we change anything.
*/
foreach ($pks as $pk)
{
$query = clone $this->getStateQuery();
$query->where('a.id = ' . (int) $pk);
$this->db->setQuery($query);
$item = $this->db->loadObject();
// Translate the state.
$state = null;
if ($item->parent_id != 1)
{
$state = $item->cat_state;
}
$temp = $this->translateState($value, $state);
// Update the item.
$this->change($pk, 'state', $temp);
// Reindex the item.
$this->reindex($pk);
}
}
// Handle when the plugin is disabled.
if ($context === 'com_plugins.plugin' && $value === 0)
{
$this->pluginDisable($pks);
}
}
/**
* Method to index an item. The item must be a FinderIndexerResult object.
*
* @param FinderIndexerResult $item The item to index as a FinderIndexerResult object.
* @param string $format The item format. Not used.
*
* @return void
*
* @since 2.5
* @throws Exception on database error.
*/
protected function index(FinderIndexerResult $item, $format = 'html')
{
// Check if the extension is enabled.
if (JComponentHelper::isEnabled($this->extension) === false)
{
return;
}
// Check if the extension that owns the category is also enabled.
if (JComponentHelper::isEnabled($item->extension) === false)
{
return;
}
$item->setLanguage();
$extension = ucfirst(substr($item->extension, 4));
// Initialize the item parameters.
$item->params = new Registry($item->params);
$item->metadata = new Registry($item->metadata);
/*
* Add the metadata processing instructions based on the category's
* configuration parameters.
*/
// Add the meta author.
$item->metaauthor = $item->metadata->get('author');
// Handle the link to the metadata.
$item->addInstruction(FinderIndexer::META_CONTEXT, 'link');
$item->addInstruction(FinderIndexer::META_CONTEXT, 'metakey');
$item->addInstruction(FinderIndexer::META_CONTEXT, 'metadesc');
$item->addInstruction(FinderIndexer::META_CONTEXT, 'metaauthor');
$item->addInstruction(FinderIndexer::META_CONTEXT, 'author');
// Deactivated Methods
// $item->addInstruction(FinderIndexer::META_CONTEXT, 'created_by_alias');
// Trigger the onContentPrepare event.
$item->summary = FinderIndexerHelper::prepareContent($item->summary, $item->params);
// Build the necessary route and path information.
$item->url = $this->getUrl($item->id, $item->extension, $this->layout);
$class = $extension . 'HelperRoute';
// Need to import component route helpers dynamically, hence the reason it's handled here.
JLoader::register($class, JPATH_SITE . '/components/' . $item->extension . '/helpers/route.php');
if (class_exists($class) && method_exists($class, 'getCategoryRoute'))
{
$item->route = $class::getCategoryRoute($item->id, $item->language);
}
else
{
$item->route = ContentHelperRoute::getCategoryRoute($item->id, $item->language);
}
$item->path = FinderIndexerHelper::getContentPath($item->route);
// Get the menu title if it exists.
$title = $this->getItemMenuTitle($item->url);
// Adjust the title if necessary.
if (!empty($title) && $this->params->get('use_menu_title', true))
{
$item->title = $title;
}
// Translate the state. Categories should only be published if the parent category is published.
$item->state = $this->translateState($item->state);
// Add the type taxonomy data.
$item->addTaxonomy('Type', 'Category');
// Add the language taxonomy data.
$item->addTaxonomy('Language', $item->language);
// Get content extras.
FinderIndexerHelper::getContentExtras($item);
// Index the item.
$this->indexer->index($item);
}
/**
* Method to setup the indexer to be run.
*
* @return boolean True on success.
*
* @since 2.5
*/
protected function setup()
{
// Load com_content route helper as it is the fallback for routing in the indexer in this instance.
JLoader::register('ContentHelperRoute', JPATH_SITE . '/components/com_content/helpers/route.php');
return true;
}
/**
* Method to get the SQL query used to retrieve the list of content items.
*
* @param mixed $query A JDatabaseQuery object or null.
*
* @return JDatabaseQuery A database object.
*
* @since 2.5
*/
protected function getListQuery($query = null)
{
$db = JFactory::getDbo();
// Check if we can use the supplied SQL query.
$query = $query instanceof JDatabaseQuery ? $query : $db->getQuery(true)
->select('a.id, a.title, a.alias, a.description AS summary, a.extension')
->select('a.created_user_id AS created_by, a.modified_time AS modified, a.modified_user_id AS modified_by')
->select('a.metakey, a.metadesc, a.metadata, a.language, a.lft, a.parent_id, a.level')
->select('a.created_time AS start_date, a.published AS state, a.access, a.params');
// Handle the alias CASE WHEN portion of the query.
$case_when_item_alias = ' CASE WHEN ';
$case_when_item_alias .= $query->charLength('a.alias', '!=', '0');
$case_when_item_alias .= ' THEN ';
$a_id = $query->castAsChar('a.id');
$case_when_item_alias .= $query->concatenate(array($a_id, 'a.alias'), ':');
$case_when_item_alias .= ' ELSE ';
$case_when_item_alias .= $a_id . ' END as slug';
$query->select($case_when_item_alias)
->from('#__categories AS a')
->where($db->quoteName('a.id') . ' > 1');
return $query;
}
/**
* Method to get a SQL query to load the published and access states for
* a category and its parents.
*
* @return JDatabaseQuery A database object.
*
* @since 2.5
*/
protected function getStateQuery()
{
$query = $this->db->getQuery(true)
->select($this->db->quoteName('a.id'))
->select($this->db->quoteName('a.parent_id'))
->select('a.' . $this->state_field . ' AS state, c.published AS cat_state')
->select('a.access, c.access AS cat_access')
->from($this->db->quoteName('#__categories') . ' AS a')
->join('LEFT', '#__categories AS c ON c.id = a.parent_id');
return $query;
}
}