- Make sure we don't get query errors when there are no deletes
[isso.git] / printer_css.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # Iris Studios Shared Object Framework [#]issoversion[#]
5 || # Copyright ©2002-[#]year[#] Iris Studios, Inc.
6 || #
7 || # This program is free software; you can redistribute it and/or modify
8 || # it under the terms of the GNU General Public License as published by
9 || # the Free Software Foundation; version [#]gpl[#] of the License.
10 || #
11 || # This program is distributed in the hope that it will be useful, but
12 || # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 || # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 || # more details.
15 || #
16 || # You should have received a copy of the GNU General Public License along
17 || # with this program; if not, write to the Free Software Foundation, Inc.,
18 || # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 || ###################################################################
20 \*=====================================================================*/
21
22 /**
23 * Printer - CSS Blocks
24 * printer_css.php
25 *
26 * @package ISSO
27 */
28
29 /**
30 * Printer - CSS Blocks
31 *
32 * This framework works in conjunction with ISSO.Printer to create a unique
33 * CSS editor enviornment.
34 *
35 * @author Iris Studios, Inc.
36 * @copyright Copyright ©2002 - [#]year[#], Iris Studios, Inc.
37 * @version $Revision$
38 * @package ISSO
39 *
40 */
41 class Printer_CSS
42 {
43 /**
44 * Framework registry object
45 * @var object
46 * @access private
47 */
48 var $registry = null;
49
50 /**
51 * CSS block list
52 * @var array
53 * @access private
54 */
55 var $descriptors = array();
56
57 /**
58 * Master data set
59 * @var array
60 * @access private
61 */
62 var $masterdata = array();
63
64 /**
65 * Cutomized data set
66 * @var array
67 * @access private
68 */
69 var $customdata = array();
70
71 // ###################################################################
72 /**
73 * Constructor
74 */
75 function __construct(&$registry)
76 {
77 $this->registry =& $registry;
78 }
79
80 // ###################################################################
81 /**
82 * (PHP 4) Constructor
83 */
84 function Printer_CSS(&$registry)
85 {
86 $this->__construct($registry);
87 }
88
89 // ###################################################################
90 /**
91 * Adds a CSS information block to the array for later use
92 *
93 * @access public
94 *
95 * @param string Block title to display in thead
96 * @param string CSS class/descriptor/element name
97 * @param bool Show the link CSS information
98 */
99 function add_block($title, $descriptor, $dolink)
100 {
101 if (isset($this->descriptors["$descriptor"]))
102 {
103 trigger_error('The descriptor `' . $descriptor . '` already exists', E_USER_WARNING);
104 return;
105 }
106
107 $this->descriptors["$descriptor"] = array(
108 'title' => $title,
109 'descriptor' => $descriptor,
110 'dolink' => $dolink
111 );
112 }
113
114 // ###################################################################
115 /**
116 * Sets a master data key for a given descriptor and property
117 *
118 * @access public
119 *
120 * @param string Descriptor
121 * @param string Property
122 * @param string Value
123 */
124 function set_master_data($descriptor, $property, $value)
125 {
126 $this->masterdata["$descriptor"]["$property"] = $value;
127 }
128
129 // ###################################################################
130 /**
131 * Sets a custom data key for a given descriptor and property
132 *
133 * @access public
134 *
135 * @param string Descriptor
136 * @param string Property
137 * @param string Value
138 */
139 function set_custom_data($descriptor, $property, $value)
140 {
141 $this->customdata["$descriptor"]["$property"] = $value;
142 }
143
144 // ###################################################################
145 /**
146 * Generates the HTML needed to output the CSS editing blocks; this is
147 * done in the form of using ISSO.Printer
148 *
149 * @access public
150 */
151 function generate_blocks()
152 {
153 $print =& $this->registry->modules['printer'];
154
155 $lang = array(
156 'standard_css_attributes' => $this->registry->modules['localize']->string('Standard CSS Attributes'),
157 'extra_css_attributes' => $this->registry->modules['localize']->string('Extra CSS Attributes'),
158
159 'links_normal' => $this->registry->modules['localize']->string('Normal CSS Links'),
160 'links_visited' => $this->registry->modules['localize']->string('Visited CSS Links'),
161 'links_hover' => $this->registry->modules['localize']->string('Hover CSS Links'),
162
163 'background' => $this->registry->modules['localize']->string('Background'),
164 'font_color' => $this->registry->modules['localize']->string('Font Color'),
165 'font_style' => $this->registry->modules['localize']->string('Font Style'),
166 'font_size' => $this->registry->modules['localize']->string('Font Size'),
167 'font_family' => $this->registry->modules['localize']->string('Font Family'),
168
169 'text_decoration' => $this->registry->modules['localize']->string('Text Decoration'),
170
171 'css_selector' => $this->registry->modules['localize']->string('CSS Selector'),
172 'save_css' => $this->registry->modules['localize']->string('Save CSS')
173 );
174
175 foreach ($this->descriptors AS $descriptor)
176 {
177 $value = array();
178
179 $print->table_start();
180 $print->table_head($descriptor['title']);
181
182 $value['background'] = $this->fetch_value($descriptor['descriptor'], 'background');
183 $value['color'] = $this->fetch_value($descriptor['descriptor'], 'color');
184 $value['font_style'] = $this->fetch_value($descriptor['descriptor'], 'font-style');
185 $value['font_size'] = $this->fetch_value($descriptor['descriptor'], 'font-size');
186 $value['font_family'] = $this->fetch_value($descriptor['descriptor'], 'font-family');
187 $value['extra'] = $this->fetch_value($descriptor['descriptor'], 'extra');
188
189 $html = <<<HTML
190 <table cellspacing="0" cellpadding="4" border="0" width="100%">
191 <tr valign="top">
192 <td width="50%">
193 <fieldset>
194 <legend><strong>$lang[standard_css_attributes]</strong></legend>
195
196 <table cellspacing="0" cellpadding="2" border="0" width="100%">
197 <tr>
198 <td width="45%">$lang[background]</td>
199 <td><input name="css[$descriptor[descriptor]][background]" class="input" style="width: 100%" value="$value[background]" /></td>
200 </tr>
201 <tr>
202 <td width="45%">$lang[font_color]</td>
203 <td><input name="css[$descriptor[descriptor]][color]" class="input" style="width: 100%" value="$value[color]" /></td>
204 </tr>
205 <tr>
206 <td width="45%">$lang[font_style]</td>
207 <td><input name="css[$descriptor[descriptor]][font-style]" class="input" style="width: 100%" value="$value[font_style]" /></td>
208 </tr>
209 <tr>
210 <td width="45%">$lang[font_size]</td>
211 <td><input name="css[$descriptor[descriptor]][font-size]" class="input" style="width: 100%" value="$value[font_size]" /></td>
212 </tr>
213 <tr>
214 <td width="45%">$lang[font_family]</td>
215 <td><input name="css[$descriptor[descriptor]][font-family]" class="input" style="width: 100%" value="$value[font_family]" /></td>
216 </tr>
217 </table>
218 </fieldset>
219 </td>
220
221 <td>
222 <fieldset style="height: 115px">
223 <legend><strong>$lang[extra_css_attributes]</strong></legend>
224 <textarea name="css[$descriptor[descriptor]][extra]" style="width: 100%; height: 90%">$value[extra]</textarea>
225 </fieldset>
226 </td>
227 </tr>
228 </table>
229 HTML;
230 if ($descriptor['dolink'])
231 {
232 foreach (array('a:link' => 'a_link', 'a:visited' => 'a_visited', 'a:hover' => 'a_hover') AS $sel => $selname)
233 {
234 $value[$selname . '_background'] = $this->fetch_value($descriptor['descriptor'] . ' ' . $sel, 'background');
235 $value[$selname . '_color'] = $this->fetch_value($descriptor['descriptor'] . ' ' . $sel, 'color');
236 $value[$selname . '_text_decoration'] = $this->fetch_value($descriptor['descriptor'] . ' ' . $sel, 'text-decoration');
237 }
238
239 $html .= <<<HTML
240
241 <table cellspacing="0" cellpadding="4" border="0" width="100%">
242 <tr valign="top">
243 <td width="33%">
244 <fieldset>
245 <legend><strong>$lang[links_normal]</strong></legend>
246
247 <table cellspacing="0" cellpadding="2" border="0" width="100%">
248 <tr>
249 <td width="45%">$lang[background]</td>
250 <td><input name="css[$descriptor[descriptor] a:link][background]" class="input" style="width: 100%" value="$value[a_link_background]" /></td>
251 </tr>
252 <tr>
253 <td width="45%">$lang[font_color]</td>
254 <td><input name="css[$descriptor[descriptor] a:link][color]" class="input" style="width: 100%" value="$value[a_link_color]" /></td>
255 </tr>
256 <tr>
257 <td width="45%">$lang[text_decoration]</td>
258 <td><input name="css[$descriptor[descriptor] a:link][text-decoration]" class="input" style="width: 100%" value="$value[a_link_text_decoration]" /></td>
259 </tr>
260 </table>
261 </fieldset>
262 </td>
263
264 <td width="33%">
265 <fieldset>
266 <legend><strong>$lang[links_visited]</strong></legend>
267
268 <table cellspacing="0" cellpadding="2" border="0" width="100%">
269 <tr>
270 <td width="45%">$lang[background]</td>
271 <td><input name="css[$descriptor[descriptor] a:visited][background]" class="input" style="width: 100%" value="$value[a_visited_background]" /></td>
272 </tr>
273 <tr>
274 <td width="45%">$lang[font_color]</td>
275 <td><input name="css[$descriptor[descriptor] a:visited][color]" class="input" style="width: 100%" value="$value[a_visited_color]" /></td>
276 </tr>
277 <tr>
278 <td width="45%">$lang[text_decoration]</td>
279 <td><input name="css[$descriptor[descriptor] a:visited][text-decoration]" class="input" style="width: 100%" value="$value[a_visited_text_decoration]" /></td>
280 </tr>
281 </table>
282 </fieldset>
283 </td>
284
285 <td width="33%">
286 <fieldset>
287 <legend><strong>$lang[links_hover]</strong></legend>
288
289 <table cellspacing="0" cellpadding="2" border="0" width="100%">
290 <tr>
291 <td width="45%">$lang[background]</td>
292 <td><input name="css[$descriptor[descriptor] a:hover][background]" class="input" style="width: 100%" value="$value[a_hover_background]" /></td>
293 </tr>
294 <tr>
295 <td width="45%">$lang[font_color]</td>
296 <td><input name="css[$descriptor[descriptor] a:hover][color]" class="input" style="width: 100%" value="$value[a_hover_color]" /></td>
297 </tr>
298 <tr>
299 <td width="45%">$lang[text_decoration]</td>
300 <td><input name="css[$descriptor[descriptor] a:hover][text-decoration]" class="input" style="width: 100%" value="$value[a_hover_text_decoration]" /></td>
301 </tr>
302 </table>
303 </fieldset>
304 </td>
305 </tr>
306 </table>
307 HTML;
308 }
309
310 $print->row_span($html, 'alt2', 'left', 1);
311
312 $print->row_span('
313 <div class="alt1" style="border: inset 1px; padding: 2px 5px 2px 5px; float: left">' . $lang['css_selector'] . ': <code>' . $descriptor['descriptor'] . '</code></div>
314 <input type="submit" name="submit" value="' . $lang['save_css'] . '" class="button" />', 'tfoot', 'right', 1);
315
316 $print->table_end();
317 }
318 }
319
320 // ###################################################################
321 /**
322 * Returns the value of a given descriptor and property by comparing
323 * the mater set and custom set then returning the right one
324 *
325 * @access private
326 *
327 * @param string Descriptor
328 * @param string Property
329 *
330 * @return string Value of the given property
331 */
332 function fetch_value($descriptor, $property)
333 {
334 if ($this->customdata["$descriptor"]["$property"] == '')
335 {
336 return $this->masterdata["$descriptor"]["$property"];
337 }
338 else
339 {
340 return $this->customdata["$descriptor"]["$property"];
341 }
342 }
343
344 // ###################################################################
345 /**
346 * Generates an array of queries that should be run on your database to
347 * update CSS changes. All of the queries have sprintf() markers that
348 * need to be evaluated:
349 *
350 * %1$s - Database table
351 * %2$s - styleid field
352 * %3$s - descriptor field
353 * %4$s - property field
354 * %5$s - value field
355 * %6%d - Styleid value
356 *
357 * @access public
358 *
359 * @param array Array of user-inputted information to be transformed into queries
360 *
361 * @return array Queries that need to be evaluated then ran
362 */
363 function generate_change_query($data)
364 {
365 $queries[0] = '--- RESERVED FOR LATER USE ---';
366
367 $deletes = array();
368
369 foreach ($this->descriptors AS $descriptor => $opts)
370 {
371 $dolink = $opts['dolink'];
372
373 if ($dolink)
374 {
375 $loops = array('', ' a:link', ' a:visited', ' a:hover');
376 }
377 else
378 {
379 $loops = array('');
380 }
381
382 foreach ($loops AS $sel)
383 {
384 foreach ($data["$descriptor$sel"] AS $prop => $value)
385 {
386 // the given value matches the master -- no change
387 if ($this->masterdata["$descriptor$sel"]["$prop"] == $value)
388 {
389 continue;
390 }
391 // the given matches the custom -- no change
392 else if ($this->customdata["$descriptor$sel"]["$prop"] == $value)
393 {
394 continue;
395 }
396 // no matching, it's new
397 else
398 {
399 $deletes[] = "%3\$s = '" . $this->escape($descriptor . $sel) . "' AND %4\$s = '" . $this->escape($prop) . "'";
400 $queries[] = "INSERT INTO %1\$s (%2\$s, %3\$s, %4\$s, %5\$s) VALUES (%6\$d, '" . $this->escape($descriptor . $sel) . "', '" . $this->escape($prop) . "', '" . $this->escape($value) . "')";
401 }
402 }
403 }
404 }
405
406 if (sizeof($deletes) < 1)
407 {
408 $queries[0] = '##';
409 }
410 else
411 {
412 $queries[0] = "DELETE FROM %1\$s WHERE styleid = %6\$d AND ((" . implode(') OR (', $deletes) . "))";
413 }
414
415 return $queries;
416 }
417
418 // ###################################################################
419 /**
420 * Wrapper for $this->registry->modules[ISSO_DB_LAYER]->escape_string()
421 *
422 * @access private
423 *
424 * @param string Unprotected string
425 *
426 * @return string Sanitized string
427 */
428 function escape($string)
429 {
430 return $this->registry->modules[ISSO_DB_LAYER]->escape_string($string);
431 }
432
433 // ###################################################################
434 /**
435 * Generates a linkable/usable CSS stylehseet content file; this can
436 * be outputted to the browser
437 *
438 * @access public
439 *
440 * @return string CSS output
441 */
442 function generate_css_output()
443 {
444 $data = array();
445
446 foreach ($this->descriptors AS $descriptor => $opts)
447 {
448 $dolink = $opts['dolink'];
449
450 if ($dolink)
451 {
452 $loops = array('', ' a:link', ' a:visited', ' a:hover');
453 }
454 else
455 {
456 $loops = array('');
457 }
458
459 foreach ($loops AS $sel)
460 {
461 foreach ($this->masterdata["$descriptor$sel"] AS $prop => $value)
462 {
463 $data["$descriptor$sel"]["$prop"] = $value;
464 }
465 if (is_array($this->customdata["$descriptor$sel"]))
466 {
467 foreach ($this->customdata["$descriptor$sel"] AS $prop => $value)
468 {
469 $data["$descriptor$sel"]["$prop"] = $value;
470 }
471 }
472 }
473 }
474
475 $output = '/* CSS Style Sheet (generated by ISSO.Printer.CSS $Revision$) */';
476
477 foreach ($data AS $selector => $props)
478 {
479 $output .= "\n\n$selector\n{";
480 foreach ($props AS $name => $value)
481 {
482 if ($name != 'extra')
483 {
484 $output .= "\n\t$name: $value;";
485 }
486 }
487
488 if ($props['extra'])
489 {
490 $extra = explode("\n", $this->registry->modules['functions']->convert_line_breaks($props['extra']));
491
492 foreach ($extra AS $prop)
493 {
494 $output .= "\n\t$prop";
495 }
496 }
497
498 $output .= "\n}";
499 }
500
501 return $output;
502 }
503 }
504
505 /*=====================================================================*\
506 || ###################################################################
507 || # $HeadURL$
508 || # $Id$
509 || ###################################################################
510 \*=====================================================================*/
511 ?>