/[drupal]/contributions/modules/nodequeue/smartqueue.module
ViewVC logotype

Contents of /contributions/modules/nodequeue/smartqueue.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.6 - (show annotations) (download) (as text)
Wed Jun 10 22:19:30 2009 UTC (5 months, 2 weeks ago) by ezrag
Branch: MAIN
CVS Tags: DRUPAL-6--2-5, DRUPAL-6--2-4, DRUPAL-6--2-3, DRUPAL-6--2-2, HEAD
Changes since 1.5: +2 -2 lines
File MIME type: text/x-php
488092 SA-CONTRIB-2009-038 - Nodequeue - Multiple vulnerabilities
1 <?php
2 // $Id: smartqueue.module,v 1.5 2009/04/30 02:35:33 ezrag Exp $
3
4 /**
5 * Implementation of hook_nodequeue_info()
6 */
7 function smartqueue_nodequeue_info() {
8 return array('smartqueue_taxonomy' => array(
9 'title' => t('Taxonomy queue'),
10 'description' => t('Each particular grouping of taxonomy terms from the selected vocabularies have their own unique subqueue. You can place nodes into any of these subqueues based on which terms that node has been tagged with. Using this with large or too many taxonomies may degrade performance.'),
11 ));
12 }
13
14 /**
15 * Implementation of hook_nodequeue_form()
16 */
17 function smartqueue_taxonomy_nodequeue_form($queue, &$form) {
18 foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) {
19 $options[$vid] = check_plain($vocabulary->name);
20 }
21 $form['placeholder']['vocabularies'] = array(
22 '#type' => 'checkboxes',
23 '#title' => t('Vocabularies'),
24 '#description' => t('Select which vocabularies to use; each unique combination of terms from all of these vocabularies will have a subqueue.'),
25 '#options' => $options,
26 );
27
28 $form['subqueue_title'] = array(
29 '#type' => 'textfield',
30 '#title' => t('Subqueue title'),
31 '#default_value' => $queue->subqueue_title,
32 '#size' => 50,
33 '#maxlength' => 64,
34 '#description' => t('What to display for the subqueue title; use %subqueue to embed the actual subqueue title. This is used to distinguish multiple nodequeues with subqueues from each other, as internal subqueue title is filled automatically.'),
35 );
36
37
38 if ($queue->qid) {
39 $form['placeholder']['vocabularies']['#disabled'] = TRUE;
40 $form['placeholder']['vocabularies']['#default_value'] = explode('-', $queue->reference);
41 }
42 }
43
44 /**
45 * Implementation of hook_nodequeue_form_validate()
46 */
47 function smartqueue_taxonomy_nodequeue_form_validate($queue, &$form_state, &$form) {
48 if (!isset($queue->qid)) {
49 $vids = array_keys(array_filter($form_state['values']['vocabularies']));
50 if (empty($vids)) {
51 form_error($form['placeholder']['vocabularies'], t('You must select at least one vocabulary.'));
52 }
53
54 // Convert this to our reference.
55 form_set_value($form['reference'], implode('-', $vids), $form_state);
56 }
57 }
58
59
60 /**
61 * Implementation of hook_nodequeue_subqueues()
62 */
63 function smartqueue_taxonomy_nodequeue_subqueues(&$queue, $node) {
64 foreach (explode('-', $queue->reference) as $vid) {
65 $vids[$vid] = array();
66 }
67
68 foreach ($node->taxonomy as $key => $value) {
69 // This unfortunate scar is needed because $node->taxonomy looks different when saving a node versus loading.
70 if (!is_object($value)) {
71 // $node comes from a node form submission
72 foreach ((array)$value as $tid) {
73 if (isset($vids[$key])) {
74 $vids[$key][] = $tid;
75 }
76 }
77 }
78 else {
79 // $node comes from node_load()
80 if (isset($vids[$value->vid])) {
81 $vids[$value->vid][] = $value->tid;
82 }
83 }
84 }
85
86 // Forbid NO terms being set, but allow
87 // various non-terms to be set.
88
89 $empty = TRUE;
90 foreach ($vids as $vid => $tids) {
91 if (!empty($tids)) {
92 $empty = FALSE;
93 }
94 if (!count($vids[$vid])) {
95 $vids[$vid][] = 0;
96 }
97 }
98
99 if ($empty) {
100 return;
101 }
102
103 $references = smartqueue_build_string(array_filter($vids));
104 // Because of how we built this, the last one will always be all zeros. Lose it.
105 //array_pop($references);
106
107 // We're returning an array of references for efficiency, but we also have
108 // to check to see if the references we've generated exist. If they don't,
109 // we have to create them.
110 $exists = array();
111 $subqueues = nodequeue_load_subqueues_by_reference(array($queue->qid => $references));
112 foreach ($subqueues as $subqueue) {
113 $exists[$subqueue->reference] = TRUE;
114 }
115
116 foreach ($references as $reference) {
117 if (empty($exists[$reference])) {
118 nodequeue_add_subqueue($queue, smartqueue_taxonomy_nodequeue_subqueue_title($queue, $reference), $reference);
119 }
120 }
121 return $references;
122 }
123
124 /**
125 * Build an array of strings that represents all of the possible term
126 * combinations
127 */
128 function smartqueue_build_string($arrays) {
129 $array = array_shift($arrays);
130 $term = '';
131 if (empty($arrays)) {
132 return $array;
133 }
134
135 $substrings = smartqueue_build_string($arrays);
136 $strings = array();
137
138 foreach ($array as $term) {
139 foreach ($substrings as $string) {
140 $strings[] = "$term-$string";
141 }
142 }
143
144 return $strings;
145 }
146
147 function smartqueue_taxonomy_nodequeue_subqueue_title($queue, $reference) {
148 $vids = explode('-', $queue->reference);
149 $tids = explode('-', $reference);
150 foreach ($vids as $vid) {
151 $tid = array_shift($tids);
152 // $tid can be 0, specifically meaning this term is unset.
153 if ($tid) {
154 $terms = smartqueue_taxonomy_get_terms($vid);
155 $titles[$tid] = $terms[$tid];
156 }
157 }
158 return implode('-', $titles);
159 }
160
161 /**
162 * Get a list of terms
163 */
164 function smartqueue_taxonomy_get_terms($vid) {
165 static $cache = array();
166 if (!isset($cache[$vid])) {
167 $cache[$vid] = array();
168 $result = db_query("SELECT tid, name FROM {term_data} WHERE vid = %d", $vid);
169 while ($term = db_fetch_object($result)) {
170 $cache[$vid][$term->tid] = $term->name;
171 }
172 }
173 return $cache[$vid];
174 }
175
176
177 // TODO:
178 // * Automatically add subqueues when terms are created.
179 // * Handle vocabulary changes (maybe?)
180 /**
181 * Implementation of hook_taxonomy.
182 */
183 function smartqueue_taxonomy($op, $type, $array = NULL) {
184 switch ($type) {
185 case 'term':
186 switch ($op){
187 // If a term was updated, we need to update any relevant nodequeue titles.
188 case 'update':
189 $tid = $array['tid'];
190 // Find subqueues that contain this term.
191 $result = db_query(
192 "SELECT nq.reference AS reference, sq.reference AS sqref, sq.sqid
193 FROM {nodequeue_queue} nq
194 INNER JOIN {nodequeue_subqueue} sq ON nq.qid = sq.qid
195 WHERE nq.owner = 'smartqueue_taxonomy'
196 AND (sq.reference = '%d'
197 OR sq.reference LIKE '%%-%d'
198 OR sq.reference LIKE '%d-%%'
199 OR sq.reference LIKE '%%-%d-%%')",
200 $tid, $tid, $tid, $tid
201 );
202 while ($row = db_fetch_object($result)) {
203 // Note that $row already contains the needed $row->reference.
204 $title = smartqueue_taxonomy_nodequeue_subqueue_title($row, $row->sqref);
205 nodequeue_subqueue_update_title($row->sqid, $title);
206 }
207 break;
208
209 // If a term was deleted, we need to delete any subqueues containing it.
210 case 'delete':
211 $tid = $array['tid'];
212 // Find subqueues that contain this term.
213 $result = db_query(
214 "SELECT sq.sqid FROM {nodequeue_subqueue} sq
215 INNER JOIN {nodequeue_queue} nq ON sq.qid = nq.qid
216 WHERE nq.owner = 'smartqueue_taxonomy'
217 AND (sq.reference = '%d'
218 OR sq.reference LIKE '%%-%d'
219 OR sq.reference LIKE '%d-%%'
220 OR sq.reference LIKE '%%-%d-%%')",
221 $tid, $tid, $tid, $tid
222 );
223 while ($row = db_fetch_object($result)) {
224 nodequeue_remove_subqueue($row->sqid);
225 }
226 break;
227 }
228 case 'vocabulary':
229 break;
230 }
231 }

  ViewVC Help
Powered by ViewVC 1.1.2