Merge lp:~quam-plures-core/quam-plures/bug-523401 into lp:quam-plures
- bug-523401
- Merge into trunk
Proposed by
Tilman Blumenbach
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~quam-plures-core/quam-plures/bug-523401 |
Merge into: | lp:quam-plures |
Diff against target: |
763 lines (+335/-220) 5 files modified
inc/_core/_misc.funcs.php (+27/-2) inc/collections/model/_category.funcs.php (+1/-80) inc/items/items.ctrl.php (+8/-1) inc/items/model/_item.class.php (+132/-111) inc/items/model/_itemlight.class.php (+167/-26) |
To merge this branch: | bzr merge lp:~quam-plures-core/quam-plures/bug-523401 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
EdB | Approve | ||
Review via email: mp+19812@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 7436. By Tilman Blumenbach
-
Correctly commit DB changes
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'inc/_core/_misc.funcs.php' |
2 | --- inc/_core/_misc.funcs.php 2010-02-17 18:59:03 +0000 |
3 | +++ inc/_core/_misc.funcs.php 2010-02-21 13:58:12 +0000 |
4 | @@ -72,9 +72,12 @@ |
5 | } |
6 | |
7 | /** |
8 | + * Get a cache reference. |
9 | + * |
10 | * @todo fp> split into 1 function per case. (typed @return values) |
11 | - * |
12 | - * @return DataObjectCache |
13 | + * |
14 | + * @param string The cache to get (see source code for possible names). |
15 | + * @return mixed The requested cache (debug_die()s on invalid cache name). |
16 | */ |
17 | function & get_Cache( $objectName ) |
18 | { |
19 | @@ -138,6 +141,10 @@ |
20 | $ItemTagsCache = array(); |
21 | return $ItemTagsCache; |
22 | |
23 | + case 'ItemCatsCache': |
24 | + $ItemCatsCache = array(); |
25 | + return $ItemCatsCache; |
26 | + |
27 | case 'ItemStatusCache': |
28 | $Plugins->get_object_from_cacheplugin_or_create( 'ItemStatusCache', 'new GenericCache( \'GenericElement\', true, \'T_items__status\', \'pst_\', \'pst_ID\', NULL, \'\', T_(\'No status\') )' ); |
29 | return $ItemStatusCache; |
30 | @@ -3325,4 +3332,22 @@ |
31 | } |
32 | |
33 | |
34 | +/** |
35 | + * Check if two arrays contain the same elements. |
36 | + * |
37 | + * @param array The first array. |
38 | + * @param array The second array. |
39 | + * @return boolean True if both arrays contain the same elements, false |
40 | + * otherwise. |
41 | + */ |
42 | +function array_equal( $one, $two ) |
43 | +{ |
44 | + $one_count = count( $one ); |
45 | + |
46 | + /* We consider the arrays to be equal if they have the same number of |
47 | + * elements and all elements of $one are present in $two. |
48 | + */ |
49 | + return $one_count == count( $two ) && |
50 | + count( array_intersect( $one, $two ) ) == $one_count; |
51 | +} |
52 | ?> |
53 | |
54 | === modified file 'inc/collections/model/_category.funcs.php' |
55 | --- inc/collections/model/_category.funcs.php 2009-12-19 19:51:52 +0000 |
56 | +++ inc/collections/model/_category.funcs.php 2010-02-21 13:58:12 +0000 |
57 | @@ -78,36 +78,6 @@ |
58 | |
59 | |
60 | /** |
61 | - * Get category name+blog_id for specified cat ID |
62 | - * |
63 | - * fplanque: reused "R. U. Serious" optimization here |
64 | - * fplanque: added blog ID stuff |
65 | - * |
66 | - * @deprecated since 3.1.0-alpha. Use ChapterCache instead. |
67 | - * @param integer category ID |
68 | - * @param boolean die() if category does not exist? (default: true) |
69 | - * |
70 | - */ |
71 | -function get_the_category_by_ID( $cat_ID, $die = true ) |
72 | -{ |
73 | - global $cache_categories; |
74 | - if( empty($cache_categories[$cat_ID]) ) |
75 | - { |
76 | - cat_load_cache( 'none' ); |
77 | - } |
78 | - if( !isset( $cache_categories[$cat_ID] ) ) |
79 | - { |
80 | - if( $die ) |
81 | - { |
82 | - debug_die( sprintf( T_('Requested category %s does not exist!'), $cat_ID ) ); |
83 | - } |
84 | - else return false; |
85 | - } |
86 | - return $cache_categories[$cat_ID]; |
87 | -} |
88 | - |
89 | - |
90 | -/** |
91 | * Get blog ID for a given cat. |
92 | * This halts on error. |
93 | * @return integer |
94 | @@ -194,55 +164,6 @@ |
95 | |
96 | |
97 | /** |
98 | - * Load cache for category associations with current posts |
99 | - * |
100 | - * @todo put this into main post query when MySQL 4.0 commonly available |
101 | - * @todo dh> why is this limited to the _global_ $postIDlist?! |
102 | - * Really ridiculous, trying to get a list of category names for an Item (which is not in $postIDlist for example.. :/) |
103 | - * fp> This is legacy from a quick b2/cafelog hack. This will de deprecated. |
104 | - * dh> Only used in ItemLight::get_Chapters now - move it there for now? fp> no it should stay close to $cache_postcats handling until teh whole thing dies. |
105 | - */ |
106 | -function cat_load_postcats_cache() |
107 | -{ |
108 | - global $DB, $cache_postcats, $postIDlist, $preview; |
109 | - |
110 | - if( isset($cache_postcats) ) |
111 | - { // already done! |
112 | - return; |
113 | - } |
114 | - |
115 | - if( $preview ) |
116 | - { // Preview mode |
117 | - global $extracats, $post_category; |
118 | - param( 'extracats', 'array', array() ); |
119 | - if( !in_array( $post_category, $extracats ) ) |
120 | - $extracats[] = $post_category; |
121 | - $cache_postcats[0] = $extracats; |
122 | - return; |
123 | - } |
124 | - |
125 | - if( !empty($postIDlist) ) |
126 | - { |
127 | - $sql = "SELECT postcat_post_ID, postcat_cat_ID |
128 | - FROM T_postcats |
129 | - WHERE postcat_post_ID IN ($postIDlist) |
130 | - ORDER BY postcat_post_ID, postcat_cat_ID"; |
131 | - |
132 | - foreach( $DB->get_results( $sql, ARRAY_A ) as $myrow ) |
133 | - { |
134 | - $postcat_post_ID = $myrow["postcat_post_ID"]; |
135 | - if( ! isset( $cache_postcats[$postcat_post_ID] ) ) |
136 | - { |
137 | - $cache_postcats[$postcat_post_ID] = array(); |
138 | - } |
139 | - $cache_postcats[$postcat_post_ID][] = $myrow["postcat_cat_ID"]; |
140 | - // echo "just cached: post=$postcat_post_ID cat=".$myrow["postcat_cat_ID"]."<br />"; |
141 | - } |
142 | - } |
143 | -} |
144 | - |
145 | - |
146 | -/** |
147 | * Get category associations with given post |
148 | */ |
149 | function postcats_get_byID( $post_ID ) |
150 | @@ -471,4 +392,4 @@ |
151 | { |
152 | } |
153 | |
154 | -?> |
155 | \ No newline at end of file |
156 | +?> |
157 | |
158 | === modified file 'inc/items/items.ctrl.php' |
159 | --- inc/items/items.ctrl.php 2010-02-02 02:56:23 +0000 |
160 | +++ inc/items/items.ctrl.php 2010-02-21 13:58:12 +0000 |
161 | @@ -302,7 +302,7 @@ |
162 | $current_User->check_perm( 'item_post!CURSTATUS', 'edit', true, $edited_Item ); |
163 | |
164 | $post_comment_status = $edited_Item->get( 'comment_status' ); |
165 | - $post_extracats = postcats_get_byID( $p ); // NOTE: dh> using $edited_Item->get_Chapters here instead fails (empty list, since no postIDlist). |
166 | + $post_extracats = $edited_Item->get_Chapter_IDs(); |
167 | |
168 | $item_tags = implode( ', ', $edited_Item->get_tags() ); |
169 | $trackback_url = ''; |
170 | @@ -456,6 +456,13 @@ |
171 | // Is this post already published? |
172 | $was_published = $edited_Item->status == 'published'; |
173 | |
174 | + // Load tags and extra categories to allow the system to check |
175 | + // whether they have been changed. While this could look like |
176 | + // "yet another unnecessary SQL query", it prevents deleting all |
177 | + // the tags/categories just to insert the same all over data again. |
178 | + $edited_Item->get_tags(); |
179 | + $edited_Item->get_Chapter_IDs(); |
180 | + |
181 | // UPDATE POST: |
182 | // Set the params we already got: |
183 | $edited_Item->set( 'status', $post_status ); |
184 | |
185 | === modified file 'inc/items/model/_item.class.php' |
186 | --- inc/items/model/_item.class.php 2010-02-21 05:04:49 +0000 |
187 | +++ inc/items/model/_item.class.php 2010-02-21 13:58:12 +0000 |
188 | @@ -183,13 +183,6 @@ |
189 | var $notifications_ctsk_ID; |
190 | |
191 | /** |
192 | - * array of IDs or NULL if we don't know... |
193 | - * |
194 | - * @var array |
195 | - */ |
196 | - var $extra_cat_IDs = NULL; |
197 | - |
198 | - /** |
199 | * Array of tags (strings) |
200 | * |
201 | * Lazy loaded. |
202 | @@ -199,6 +192,13 @@ |
203 | var $tags = NULL; |
204 | |
205 | /** |
206 | + * Records whether $tags differs from the value stored in the DB. |
207 | + * |
208 | + * @var boolean |
209 | + */ |
210 | + var $tags_changed = false; |
211 | + |
212 | + /** |
213 | * Array of Links attached to this item. |
214 | * |
215 | * NULL when not initialized. |
216 | @@ -1538,28 +1538,52 @@ |
217 | /** |
218 | * Split tags by comma or semicolon |
219 | * |
220 | + * @todo Tblue> Check whether a change should invalidate the ItemTagsCache |
221 | + * for this Item. |
222 | + * |
223 | * @param string The tags, separated by comma or semicolon |
224 | + * @return boolean True if the tags have been changed, false otherwise. |
225 | */ |
226 | function set_tags_from_string( $tags ) |
227 | { |
228 | - if( $tags === '' ) |
229 | - { |
230 | - $this->tags = array(); |
231 | - return; |
232 | - } |
233 | - $this->tags = preg_split( '/\s*[;,]+\s*/', $tags, -1, PREG_SPLIT_NO_EMPTY ); |
234 | - |
235 | + $tags_arr = preg_split( '/\s*[;,]+\s*/', $tags, -1, PREG_SPLIT_NO_EMPTY ); |
236 | + |
237 | if( function_exists( 'mb_strtolower' ) ) |
238 | - { // fp> TODO: instead of those "when used" ifs, it would make more sense to redefine mb_strtolower beforehand if it doesn"t exist (it would then just be a fallback to the strtolower + a Debuglog->add() ) |
239 | - // Tblue> Note on charset: param() should have converted the tag string from $io_charset to $evo_charset. |
240 | - array_walk( $this->tags, create_function( '& $tag', '$tag = mb_strtolower( $tag, $GLOBALS[\'evo_charset\'] );' ) ); |
241 | + { // fp> TODO: instead of those "when used" ifs, it would make |
242 | + // more sense to redefine mb_strtolower beforehand |
243 | + // if it doesn't exist (it would then just be a |
244 | + // fallback to the strtolower + a Debuglog->add() ) |
245 | + // Tblue> Note on charset: param() should have converted the |
246 | + // tag string from $io_charset to $evo_charset. |
247 | + array_walk( $tags_arr, create_function( '& $tag', |
248 | + '$tag = mb_strtolower( $tag, $GLOBALS[\'evo_charset\'] );' ) ); |
249 | } |
250 | else |
251 | { |
252 | - array_walk( $this->tags, create_function( '& $tag', '$tag = strtolower( $tag );' ) ); |
253 | - } |
254 | - $this->tags = array_unique( $this->tags ); |
255 | - // pre_dump( $this->tags ); |
256 | + array_walk( $tags_arr, create_function( '& $tag', '$tag = strtolower( $tag );' ) ); |
257 | + } |
258 | + |
259 | + $tags_arr = array_unique( $tags_arr ); |
260 | + |
261 | + /* If there are no previous tags defined (Item::tags equals NULL), |
262 | + * we do not check for changes and just set the new tags. |
263 | + * Otherwise, if $tags contains the same elements as Item::tags, |
264 | + * no update is necessary. |
265 | + */ |
266 | + if( $this->tags !== NULL && array_equal( $tags_arr, $this->tags ) ) |
267 | + { // No changes. |
268 | + /* Note: We do not update Item::tags_changed here because it |
269 | + * could be set to true by a previous call to this method. |
270 | + */ |
271 | + return false; |
272 | + } |
273 | + |
274 | + // Only set Item::tags_changed to true if there were no previous |
275 | + // tags defined: |
276 | + $this->tags_changed = $this->tags !== NULL; |
277 | + $this->tags = $tags_arr; |
278 | + |
279 | + return true; |
280 | } |
281 | |
282 | |
283 | @@ -3307,18 +3331,19 @@ |
284 | |
285 | if( ( $result = parent::dbupdate( $auto_track_modification ) ) !== false ) |
286 | { // We could update the item object: |
287 | - |
288 | // Let's handle the extracats: |
289 | - $this->insert_update_extracats( 'update' ); |
290 | - |
291 | + $excats_updated = $this->insert_update_extracats( 'update' ); |
292 | // Let's handle the tags: |
293 | - $this->insert_update_tags( 'update' ); |
294 | + $tags_updated = $this->insert_update_tags( 'update' ); |
295 | |
296 | - $this->delete_prerendered_content(); |
297 | + if( $result !== NULL || $excats_updated || $tags_updated ) |
298 | + { // We need to delete the prerendered content: |
299 | + $this->delete_prerendered_content(); |
300 | + } |
301 | |
302 | $DB->commit(); |
303 | |
304 | - $Plugins->trigger_event( 'AfterItemUpdate', $params = array( 'Item' => & $this, 'dbchanges' => $dbchanges ) ); |
305 | + $Plugins->trigger_event( 'AfterItemUpdate', array( 'Item' => & $this, 'dbchanges' => $dbchanges ) ); |
306 | } |
307 | else |
308 | { |
309 | @@ -3405,29 +3430,39 @@ |
310 | { |
311 | global $DB; |
312 | |
313 | + if( $this->extra_cat_IDs === NULL ) |
314 | + { // Cannot insert/update non-defined tags: |
315 | + return false; |
316 | + } |
317 | + |
318 | $DB->begin(); |
319 | |
320 | - if( ! is_null( $this->extra_cat_IDs ) ) |
321 | - { // Okay the extra cats are defined: |
322 | - |
323 | - if( $mode == 'update' ) |
324 | - { |
325 | - // delete previous extracats: |
326 | - $DB->query( 'DELETE FROM T_postcats WHERE postcat_post_ID = '.$this->ID, 'delete previous extracats' ); |
327 | - } |
328 | - |
329 | - // insert new extracats: |
330 | - $query = "INSERT INTO T_postcats( postcat_post_ID, postcat_cat_ID ) VALUES "; |
331 | - foreach( $this->extra_cat_IDs as $extra_cat_ID ) |
332 | - { |
333 | - //echo "extracat: $extracat_ID <br />"; |
334 | - $query .= "( $this->ID, $extra_cat_ID ),"; |
335 | - } |
336 | - $query = substr( $query, 0, strlen( $query ) - 1 ); |
337 | - $DB->query( $query, 'insert new extracats' ); |
338 | - } |
339 | + if( $mode == 'update' ) |
340 | + { |
341 | + if( ! $this->extra_cat_IDs_changed ) |
342 | + { // No update necessary: |
343 | + $DB->commit(); |
344 | + return false; |
345 | + } |
346 | + |
347 | + $this->extra_cat_IDs_changed = false; |
348 | + |
349 | + // delete previous extracats: |
350 | + $DB->query( 'DELETE FROM T_postcats WHERE postcat_post_ID = '.$this->ID, 'delete previous extracats' ); |
351 | + } |
352 | + |
353 | + // insert new extracats: |
354 | + $query = "INSERT INTO T_postcats( postcat_post_ID, postcat_cat_ID ) VALUES "; |
355 | + foreach( $this->extra_cat_IDs as $extra_cat_ID ) |
356 | + { |
357 | + //echo "extracat: $extracat_ID <br />"; |
358 | + $query .= "( $this->ID, $extra_cat_ID ),"; |
359 | + } |
360 | + $query = substr( $query, 0, strlen( $query ) - 1 ); |
361 | + $DB->query( $query, 'insert new extracats' ); |
362 | |
363 | $DB->commit(); |
364 | + return true; |
365 | } |
366 | |
367 | |
368 | @@ -3440,50 +3475,63 @@ |
369 | { |
370 | global $DB; |
371 | |
372 | - if( isset( $this->tags ) ) |
373 | - { // Okay the tags are defined: |
374 | - |
375 | - $DB->begin(); |
376 | - |
377 | - if( $mode == 'update' ) |
378 | - { // delete previous tag associations: |
379 | - // Note: actual tags never get deleted |
380 | - $DB->query( 'DELETE FROM T_items__itemtag |
381 | - WHERE itag_itm_ID = '.$this->ID, 'delete previous tags' ); |
382 | + if( $this->tags === NULL ) |
383 | + { // Cannot update/insert non-defined tags. |
384 | + return false; |
385 | + } |
386 | + |
387 | + $DB->begin(); |
388 | + |
389 | + if( $mode == 'update' ) |
390 | + { |
391 | + if( ! $this->tags_changed ) |
392 | + { // Tags have not been changed, no update necessary. |
393 | + $DB->commit(); |
394 | + return false; |
395 | } |
396 | |
397 | - if( !empty($this->tags) ) |
398 | - { |
399 | - // Find the tags that are already in the DB |
400 | - $query = 'SELECT LOWER( tag_name ) |
401 | - FROM T_items__tag |
402 | - WHERE tag_name IN ('.$DB->quote($this->tags).')'; |
403 | - $existing_tags = $DB->get_col( $query, 0, 'Find existing tags' ); |
404 | - |
405 | - $new_tags = array_diff( $this->tags, $existing_tags ); |
406 | - //pre_dump($new_tags); |
407 | - |
408 | - if( !empty( $new_tags ) ) |
409 | - { // insert new tags: |
410 | - $query = "INSERT INTO T_items__tag( tag_name ) VALUES "; |
411 | - foreach( $new_tags as $tag ) |
412 | - { |
413 | - $query .= '( '.$DB->quote($tag).' ),'; |
414 | - } |
415 | - $query = substr( $query, 0, strlen( $query ) - 1 ); |
416 | - $DB->query( $query, 'insert new tags' ); |
417 | + $this->tags_changed = false; |
418 | + |
419 | + // delete previous tag associations: |
420 | + // Note: actual tags never get deleted |
421 | + // Tblue> TODO: We should probably provide some mechanism to |
422 | + // delete old (unused) tags. |
423 | + $DB->query( 'DELETE FROM T_items__itemtag |
424 | + WHERE itag_itm_ID = '.$this->ID, 'delete previous tags' ); |
425 | + } |
426 | + |
427 | + if( !empty($this->tags) ) |
428 | + { |
429 | + // Find the tags that are already in the DB |
430 | + $query = 'SELECT LOWER( tag_name ) |
431 | + FROM T_items__tag |
432 | + WHERE tag_name IN ('.$DB->quote($this->tags).')'; |
433 | + $existing_tags = $DB->get_col( $query, 0, 'Find existing tags' ); |
434 | + |
435 | + $new_tags = array_diff( $this->tags, $existing_tags ); |
436 | + //pre_dump($new_tags); |
437 | + |
438 | + if( !empty( $new_tags ) ) |
439 | + { // insert new tags: |
440 | + $query = "INSERT INTO T_items__tag( tag_name ) VALUES "; |
441 | + foreach( $new_tags as $tag ) |
442 | + { |
443 | + $query .= '( '.$DB->quote($tag).' ),'; |
444 | } |
445 | - |
446 | - // ASSOC: |
447 | - $query = 'INSERT INTO T_items__itemtag( itag_itm_ID, itag_tag_ID ) |
448 | - SELECT '.$this->ID.', tag_ID |
449 | - FROM T_items__tag |
450 | - WHERE tag_name IN ('.$DB->quote($this->tags).')'; |
451 | - $DB->query( $query, 'Make tag associations!' ); |
452 | + $query = substr( $query, 0, strlen( $query ) - 1 ); |
453 | + $DB->query( $query, 'insert new tags' ); |
454 | } |
455 | |
456 | - $DB->commit(); |
457 | + // ASSOC: |
458 | + $query = 'INSERT INTO T_items__itemtag( itag_itm_ID, itag_tag_ID ) |
459 | + SELECT '.$this->ID.', tag_ID |
460 | + FROM T_items__tag |
461 | + WHERE tag_name IN ('.$DB->quote($this->tags).')'; |
462 | + $DB->query( $query, 'Make tag associations!' ); |
463 | } |
464 | + |
465 | + $DB->commit(); |
466 | + return true; |
467 | } |
468 | |
469 | |
470 | @@ -3992,32 +4040,5 @@ |
471 | } |
472 | return $r; |
473 | } |
474 | - |
475 | - |
476 | - /** |
477 | - * Get a list of item IDs from $MainList and $ItemList, if they are loaded. |
478 | - * This is used for prefetching item related data for the whole list(s). |
479 | - * This will at least return the item's ID itself. |
480 | - * @return array |
481 | - */ |
482 | - function get_prefetch_itemlist_IDs() |
483 | - { |
484 | - global $MainList, $ItemList; |
485 | - |
486 | - // Add the current ID to the list to prefetch, if it's not in the MainList/ItemList (e.g. featured item). |
487 | - $r = array($this->ID); |
488 | - |
489 | - if( $MainList ) |
490 | - { |
491 | - $r = array_merge($r, $MainList->get_page_ID_array()); |
492 | - } |
493 | - if( $ItemList ) |
494 | - { |
495 | - $r = array_merge($r, $ItemList->get_page_ID_array()); |
496 | - } |
497 | - return $r; |
498 | - } |
499 | } |
500 | - |
501 | - |
502 | ?> |
503 | |
504 | === modified file 'inc/items/model/_itemlight.class.php' |
505 | --- inc/items/model/_itemlight.class.php 2010-02-17 18:34:51 +0000 |
506 | +++ inc/items/model/_itemlight.class.php 2010-02-21 13:58:12 +0000 |
507 | @@ -75,6 +75,7 @@ |
508 | * @var integer |
509 | */ |
510 | var $main_cat_ID = 0; |
511 | + |
512 | /** |
513 | * @var Chapter |
514 | * @access protected |
515 | @@ -83,6 +84,21 @@ |
516 | var $main_Chapter; |
517 | |
518 | /** |
519 | + * array of IDs or NULL if we don't know... |
520 | + * |
521 | + * @var array |
522 | + */ |
523 | + var $extra_cat_IDs = NULL; |
524 | + |
525 | + /** |
526 | + * Records whether $extra_cat_IDs differs from the value stored in the |
527 | + * DB. |
528 | + * |
529 | + * @var boolean |
530 | + */ |
531 | + var $extra_cat_IDs_changed = false; |
532 | + |
533 | + /** |
534 | * Derived from $main_cat_ID. |
535 | * |
536 | * @var integer |
537 | @@ -150,6 +166,8 @@ |
538 | $this->issue_date = $db_row->post_datestart; |
539 | $this->datestart = $db_row->post_datestart; |
540 | $this->mod_date = $db_row->post_datemodified; |
541 | + // Note: DO NOT use ItemLight::set() to set the main category |
542 | + // ID here, it will confuse ItemLight::set_extracats(). |
543 | $this->main_cat_ID = $db_row->post_main_cat_ID; |
544 | $this->urltitle = $db_row->post_urltitle; |
545 | $this->title = $db_row->post_title; |
546 | @@ -458,28 +476,60 @@ |
547 | |
548 | |
549 | /** |
550 | + * Get the chapter (category) IDs for this item. |
551 | + * |
552 | + * Loads the extra categories and populates ItemLight::extra_cat_IDs |
553 | + * if necessary. |
554 | + * This method automatically populates the ItemCatsCache for other |
555 | + * posts in the item list. |
556 | + * |
557 | + * @return array The category IDs. |
558 | + */ |
559 | + function get_Chapter_IDs() |
560 | + { |
561 | + global $DB; |
562 | + |
563 | + if( $this->extra_cat_IDs === NULL ) |
564 | + { |
565 | + $ItemCatsCache = & get_Cache( 'ItemCatsCache' ); |
566 | + |
567 | + if( ! isset( $ItemCatsCache[$this->ID] ) ) |
568 | + { // Load this post's categories and fetch category associations |
569 | + // for other posts in the item list. |
570 | + // Only prefetch data for the IDs which are not yet in the cache: |
571 | + $prefetch_IDs = array_diff( $this->get_prefetch_itemlist_IDs(), |
572 | + array_keys( $ItemCatsCache ) ); |
573 | + |
574 | + // This *should* return at least the main category for each post. |
575 | + foreach( $DB->get_results( ' |
576 | + SELECT postcat_post_ID, postcat_cat_ID |
577 | + FROM T_postcats |
578 | + WHERE postcat_post_ID IN ('.$DB->quote( $prefetch_IDs ).') |
579 | + ORDER BY postcat_post_ID, postcat_cat_ID', OBJECT, |
580 | + 'Get category associations' ) as $row ) |
581 | + { |
582 | + $ItemCatsCache[$row->postcat_post_ID][] = $row->postcat_cat_ID; |
583 | + } |
584 | + } |
585 | + |
586 | + $this->extra_cat_IDs = $ItemCatsCache[$this->ID]; |
587 | + } |
588 | + |
589 | + return $this->extra_cat_IDs; |
590 | + } |
591 | + |
592 | + |
593 | + /** |
594 | * Get list of Chapter objects. |
595 | * |
596 | * @return array of {@link Chapter chapters} (references) |
597 | */ |
598 | function get_Chapters() |
599 | { |
600 | - global $cache_postcats; |
601 | - |
602 | $ChapterCache = & get_Cache( 'ChapterCache' ); |
603 | |
604 | - // Load cache for category associations with current posts |
605 | - // TODO: dh> This fails, if $postIDlist is not set! (e.g. in admin) |
606 | - cat_load_postcats_cache(); |
607 | - |
608 | - if( isset($cache_postcats[$this->ID]) ) |
609 | - { // dh> may not be set! (demo logs) |
610 | - $categoryIDs = $cache_postcats[$this->ID]; |
611 | - } |
612 | - else $categoryIDs = array(); |
613 | - |
614 | $chapters = array(); |
615 | - foreach( $categoryIDs as $cat_ID ) |
616 | + foreach( $this->get_Chapter_IDs() as $cat_ID ) |
617 | { |
618 | $chapters[] = & $ChapterCache->get_by_ID( $cat_ID ); |
619 | } |
620 | @@ -924,6 +974,73 @@ |
621 | |
622 | |
623 | /** |
624 | + * Set the extra categories for this item. |
625 | + * |
626 | + * NOTE: Use ItemLight::set( 'extra_cat_IDs', ... ) to set the extra |
627 | + * categories. |
628 | + * |
629 | + * @todo Tblue> Check whether a change should invalidate the ItemCatsCache |
630 | + * for this Item. |
631 | + * |
632 | + * @param array An array containing the extra category IDs. |
633 | + * @param boolean Whether to add the new categories to the existing |
634 | + * ones. |
635 | + * @return boolean True if the extra categories have changed. |
636 | + */ |
637 | + function set_extracats( $cats, $add = false ) |
638 | + { |
639 | + global $Debuglog; |
640 | + |
641 | + $cats = array_unique( $cats ); |
642 | + |
643 | +/* |
644 | + $Debuglog->add( 'set_extracats(): Old cats = '.var_export( $this->extra_cat_IDs, true ) |
645 | + .'; new cats = '.var_export( $cats, true ).'; $add = '.(int)$add, |
646 | + 'dataobjects' ); |
647 | +*/ |
648 | + |
649 | + /* If there are no previous categories(ItemLight::extra_cat_IDs |
650 | + * equals NULL), we don't check whether there were changes, but |
651 | + * simply set the supplied categories (see below). |
652 | + * Otherwise, if $add is false, we check whether the $cats array |
653 | + * contains the same elements as ItemLight::extra_cat_IDs; if $add |
654 | + * is true, we check whether there are no new elements in $cats. |
655 | + * If one of the two conditions above is true, the extra categories |
656 | + * do not need to be updated. |
657 | + */ |
658 | + if( $this->extra_cat_IDs !== NULL && ( |
659 | + ( ! $add && array_equal( $cats, $this->extra_cat_IDs ) ) || |
660 | + ( $add && ! ( $added = array_diff( $cats, $this->extra_cat_IDs ) ) ) |
661 | + ) ) |
662 | + { // No update necessary. |
663 | + /* Note: We do not update ItemLight::extra_cat_IDs_changed here |
664 | + * because it could be set to true by a previous call to this |
665 | + * method. |
666 | + */ |
667 | + //$Debuglog->add( 'set_extracats(): Not updating.', 'dataobjects' ); |
668 | + return false; // no changes |
669 | + } |
670 | + |
671 | + // Only set ItemLight::extra_cat_IDs_changed to true if there |
672 | + // were no previous extra categories defined: |
673 | + $this->extra_cat_IDs_changed = $this->extra_cat_IDs !== NULL; |
674 | + |
675 | + // If there were no previous categories or we do not want to add |
676 | + // the supplied categories to the existing ones: |
677 | + if( $this->extra_cat_IDs === NULL || ! $add ) |
678 | + { // Simply override the old cats: |
679 | + $this->extra_cat_IDs = $cats; |
680 | + } |
681 | + else |
682 | + { // Add the new categories: |
683 | + $this->extra_cat_IDs = array_merge( $this->extra_cat_IDs, $added ); |
684 | + } |
685 | + |
686 | + return true; // There were changes. |
687 | + } |
688 | + |
689 | + |
690 | + /** |
691 | * Set param value |
692 | * |
693 | * By default, all values will be considered strings |
694 | @@ -941,24 +1058,25 @@ |
695 | { |
696 | case 'main_cat_ID': |
697 | $r = $this->set_param( 'main_cat_ID', 'number', $parvalue, false ); |
698 | - // make sure main cat is in extracat list and there are no duplicates |
699 | - $this->extra_cat_IDs[] = $this->main_cat_ID; |
700 | - $this->extra_cat_IDs = array_unique( $this->extra_cat_IDs ); |
701 | + |
702 | + // Make sure main cat is in extracat list: |
703 | + $this->set_extracats( array( $this->main_cat_ID ), true ); |
704 | + |
705 | // Invalidate derived property: |
706 | $this->blog_ID = NULL; |
707 | - unset($this->main_Chapter); // dereference |
708 | + |
709 | + unset($this->main_Chapter); // remove reference |
710 | $this->main_Chapter = NULL; |
711 | - unset($this->Blog); |
712 | + |
713 | + unset($this->Blog); // remove reference |
714 | $this->Blog = NULL; |
715 | + |
716 | return $r; |
717 | |
718 | case 'extra_cat_IDs': |
719 | - // ARRAY! We do not record this change (yet) |
720 | - $this->extra_cat_IDs = $parvalue; |
721 | - // make sure main cat is in extracat list and there are no duplicates |
722 | - $this->extra_cat_IDs[] = $this->main_cat_ID; |
723 | - $this->extra_cat_IDs = array_unique( $this->extra_cat_IDs ); |
724 | - break; |
725 | + // ARRAY. Make sure main cat is in extracat list: |
726 | + $parvalue[] = $this->main_cat_ID; |
727 | + return $this->set_extracats( $parvalue ); |
728 | |
729 | case 'issue_date': |
730 | case 'datestart': |
731 | @@ -1004,7 +1122,30 @@ |
732 | } |
733 | } |
734 | |
735 | + |
736 | + /** |
737 | + * Get a list of item IDs from $MainList and $ItemList, if they are loaded. |
738 | + * This is used for prefetching item related data for the whole list(s). |
739 | + * This will at least return the item's ID itself. |
740 | + * @return array |
741 | + */ |
742 | + function get_prefetch_itemlist_IDs() |
743 | + { |
744 | + global $MainList, $ItemList; |
745 | + |
746 | + // Add the current ID to the list to prefetch, if it's not in the MainList/ItemList (e.g. featured item). |
747 | + $r = array($this->ID); |
748 | + |
749 | + if( $MainList ) |
750 | + { |
751 | + $r = array_merge($r, $MainList->get_page_ID_array()); |
752 | + } |
753 | + if( $ItemList ) |
754 | + { |
755 | + $r = array_merge($r, $ItemList->get_page_ID_array()); |
756 | + } |
757 | + |
758 | + return array_unique( $r ); |
759 | + } |
760 | } |
761 | - |
762 | - |
763 | ?> |
Tested without issue, assuming one accepts the smilies bug as not an issue due to it has been fixed. Which I do. Accept that condition I mean. Hey look: they give me this big giant textarea so what am I gonna do with it?
Approve it in one line?