root/releases/0.9/lib/templates.php

Revision 1453, 49.0 kB (checked in by misja, 1 year ago)

Misja Hoebe <misja@curverider.co.uk> Merge r1447, r1448, r1449, r1450, r1451 into 0.9 branch

  • Property svn:eol-style set to native
Line 
1 <?php
2
3 /*** NZVLE TODO
4  ***
5  *** + Break the html/css bits of the Default_Template into separate files
6  ***   they mess up the code layout and indentation, and generally don't
7  ***   belong here.
8  *** + Clean up and document the calling conventions -- get rid of $parameter
9  *** + the callbacks to template_variables_substitute are *evil* -- rework
10  ***
11  ***/
12
13 /***
14  *** Takes in the short name of a template and returns the comparable version
15  *** from the file system
16  *** @param string $shortname short name of template to convert to file version
17  ***/
18 function templates_shortname_to_file($shortname) {
19     $shortname = str_replace(" ","_",$shortname);
20     return $shortname;
21 }
22
23 /***
24  *** Takes in the directory name of a template and returns the comparable version
25  *** for use as a shortname to display
26  *** @param string $foldername folder name of template to convert to internal version
27  ***/
28  function templates_file_to_shortname($foldername) {
29      $foldername = str_replace("_"," ",$foldername);
30      return $foldername;
31  }
32  
33 function templates_main () {
34
35     global $PAGE;
36
37     $run_result = '';
38
39     /*
40     *    Templates unit
41     */
42
43     // Load default values
44         $function['init'][] = path . "units/templates/default_template.php";
45         
46     // Actions
47         $function['templates:init'][] = path . "units/templates/template_actions.php";
48
49     // Draw template (returns HTML as opposed to echoing it straight to the screen)
50         $function['templates:draw'][] = path . "units/templates/template_draw.php";
51         
52     // Function to substitute variables within a template, used in templates:draw
53         $function['templates:variables:substitute'][] = path . "units/templates/variables_substitute.php";
54
55     // Function to draw the page, once supplied with a main body and title
56         $function['templates:draw:page'][] = path . "units/templates/page_draw.php";
57         
58     // Function to display a list of templates
59         $function['templates:view'][] = path . "units/templates/templates_view.php";
60         $function['templates:preview'][] = path . "units/templates/templates_preview.php";
61                 
62     // Function to display input fields for template editing
63         $function['templates:edit'][] = path . "units/templates/templates_edit.php";
64         
65     // Function to allow the user to create a new template
66         $function['templates:add'][] = path . "units/templates/templates_add.php";
67         
68     if ($context == "account") {
69         $PAGE->menu_sub[] = array( 'name' => 'template:edit',
70                                    'html' => templates_draw(array( 'context' => 'submenuitem',
71                                                                    'name' => __gettext("Change theme"),
72                                                                    'location' => url . 'mod/template/')));
73     }
74
75     return $run_result;
76 }
77
78 function templates_page_setup (){
79
80     global $PAGE;
81     global $CFG;
82
83     if (!empty($PAGE->setupdone)) {
84         return false; // don't run twice
85     }
86
87     $PAGE->setupdone = true; // leave your mark
88
89     //
90     // Populate $PAGE with links for non-module core code
91     //
92
93     if (isadmin()) {
94         $PAGE->menu_top [] = array( 'name' => 'admin',
95                                     //'html' => a_href("{$CFG->wwwroot}_admin/",
96                                     //                "Administration"));
97                                     'html' => "<li><a href=\"" . $CFG->wwwroot . "mod/admin/\">" . __gettext("Administration") . "</a></li>");
98     }
99     
100     if (logged_on) {
101         $PAGE->menu_top[] = array(
102                                   'name' => 'userdetails',
103                                   //'html' => a_href("{$CFG->wwwroot}_userdetails/",
104                                   //                  "Account settings"));
105                                   'html' => "<li><a href=\"" . $CFG->wwwroot . "_userdetails/\">" . __gettext("Account settings") . "</a></li>");
106     
107         $PAGE->menu_top[] = array(
108                                   'name' => 'logoff',
109                                   //'html' => a_href("{$CFG->wwwroot}login/logout.php",
110                                   //                 "Log off"));
111                                   'html' => "<li><a href=\"" . $CFG->wwwroot . "login/logout.php\">" . __gettext("Log off") . "</a></li>");
112     };
113
114
115     //
116     // Give a chance to all registered modules
117     //
118     if ($allmods = get_list_of_plugins('mod') ) {
119         foreach ($allmods as $mod) {
120             $mod_pagesetup = $mod . '_pagesetup';
121             if (function_exists($mod_pagesetup)) {
122                 $mod_pagesetup();
123             }
124         }
125     }
126 }
127
128 function templates_page_draw ($param) {
129     // Draws the page, given a title and a main body (parameters[0] and [1]).
130     $title = $param[0];
131     $mainbody = $param[1];
132
133     $run_result = '';
134
135     global $messages;
136
137     ////
138     //// Prepare things for the module run
139     //// populating $PAGE as required
140     ////
141     if (empty($PAGE->setupdone)) {
142         templates_page_setup();
143     }
144
145     $messageshell = "";
146     if (isset($messages) && sizeof($messages) > 0) {
147         foreach($messages as $message) {
148             $messageshell .=templates_draw(array(
149                                                  'context' => 'messages',
150                                                  'message' => $message
151                                                  )
152                                            );
153         }
154         $messageshell =templates_draw(array(
155                                             'context' => 'messageshell',
156                                             'messages' => $messageshell
157                                             )
158                                       );
159     }
160
161     // If $parameter[2] is set, we'll substitute it for the
162     // sidebar
163     if (isset($param[2])) {
164         $sidebarhtml = $param[2];
165     } else {
166         $sidebarhtml = run("display:sidebar");
167     }   
168     
169     $run_result .=  templates_draw(array(
170                             'context'      => 'pageshell',
171                             'title'        => htmlspecialchars($title, ENT_COMPAT, 'utf-8'),
172                             'menu'         => displaymenu(),
173                             'submenu'      => displaymenu_sub(),
174                             'top'          => displaymenu_top(),
175                             'sidebar'      => $sidebarhtml,
176                             'mainbody'     => $mainbody,
177                             'messageshell' => $messageshell
178                             ));
179             
180     return $run_result;
181 }
182
183 function templates_actions() {
184
185     global $CFG,$USER,$db;
186
187     // Actions
188
189     global $template, $messages, $CFG;
190     
191     $action = optional_param('action');
192     if (!logged_on) {
193         return false;
194     }
195
196     $run_result = '';
197     
198     switch ($action) {
199         case "templates:select":
200             $id = optional_param('selected_template');
201             if (substr($id, 0, 2) == "db") {
202                 $template_id = (int) substr($id,2);
203                 $exists = record_exists_sql('SELECT ident, shortname FROM '.$CFG->prefix.'templates WHERE ident = '.$template_id.' AND (owner = '.$USER->ident ." OR public='yes')");
204             } else {
205                 $exists = file_exists($CFG->templatesroot . templates_shortname_to_file($id));
206             }
207             if ($exists) {
208                 $affected_areas = optional_param('affected_areas',0,PARAM_INT);
209                 if(is_array($affected_areas)) {
210                     foreach($affected_areas as $index => $value) {
211                         //TODO - check security
212                         set_field('users','template_name',$id,'ident',$value);
213                     }
214                     $messages[] = __gettext("The templates have been changed according to your choices.");
215                 } else {
216                     $messages[] = __gettext("No changes made as no area of change was selected!");
217                 }
218             }
219             break;
220             
221
222         case "templates:save":
223             $templatearray = optional_param('template','','');
224             $id = optional_param('save_template_id',0,PARAM_INT);
225             $templatetitle = trim(optional_param('templatetitle'));
226             if (!empty($templatearray) && !empty($id) && !empty($templatetitle)) {
227                 unset($_SESSION['template_element_cache'][$id]);
228                 $exists = record_exists('templates','ident',$id,'owner',$USER->ident);
229                 if ($exists) {
230                     set_field('templates','name',$templatetitle,'ident',$id);
231                     delete_records('template_elements','template_id',$id);
232                     foreach($templatearray as $name => $content) {
233                         //TODO Fix this with PARAM_CLEANHTML or similar
234                         $cleanname = trim($name);
235                         $cleancontent = trim($content);
236                         if ($content != "" && $content != $template[$name]) {
237                             $te = new StdClass;
238                             $te->name = $cleanname;
239                             $te->content = $cleancontent;
240                             $te->template_id = $id;
241                             insert_record('template_elements',$te);
242                         }
243                     }
244                     $messages[] = __gettext("Your template has been updated.");
245                 }
246             }
247             break;
248             
249             
250         case "deletetemplate":
251             $id = optional_param('delete_template_id',0,PARAM_INT);
252             unset($_SESSION['template_element_cache'][$id]);
253             $exists = record_exists('templates','ident',$id,'owner',$USER->ident);
254             if ($exists) {
255                 //$db->execute('UPDATE '.$CFG->prefix.'users SET template_id = -1 WHERE template_id = '.$id);
256                 set_field('users', 'template_id', -1, 'template_id', $id);
257                 delete_records('template_elements','template_id',$id);
258                 delete_records('templates','ident',$id);
259                 $messages[] = __gettext("Your template was deleted.");
260             }
261             break;
262             
263             
264         case "templates:create":
265             $based_on = optional_param('template_based_on');
266             $name = trim(optional_param('new_template_name'));
267             if (empty($CFG->disable_usertemplates) && !empty($name)) {
268                 $t = new StdClass;
269                 $t->name = $name;
270                 $t->public = 'no';
271                 $t->owner = $USER->ident;
272                 $new_template_id = insert_record('templates',$t);
273                 $t->shortname = 'db'.$new_template_id;
274                 $t->ident = $new_template_id;
275                 update_record('templates',$t);
276                 foreach(array('pageshell','css') as $template_element) {
277                     if ($result = get_template_element($based_on, $template_element)) {
278                         $element = new stdClass;
279                         $element->template_id = $new_template_id;
280                         $element->content = $result->content;
281                         $element->name = $template_element;
282                         insert_record('template_elements',$element);
283                     }
284                 }
285             }
286             break;
287     }
288     return $run_result;
289 }
290     
291 /// NOTE: this function takes a named array as single parameter
292 function templates_draw ($parameter) {
293
294     // Draw a page element using a specified template (or, if the template is -1, the default)
295     // $parameter['template'] = the template ID, $parameter['element'] = the template element,
296     // all other $parameter[n] = template elements
297
298     // Initialise global template variable, which contains the Default_Template
299         global $template;
300         
301     // Initialise global template ID variable, which contains the template ID we're using
302         global $template_name;
303         global $page_owner;
304         global $CFG;
305         
306         global $page_template_cache;
307         
308         $run_result = '';
309
310         if ($parameter['context'] === 'topmenuitem') {
311             // error_log("templates_draw pcontext " . print_r($parameter,1));
312         }
313     // Get template details
314         if (!isset($template_name)) {
315             if (!isset($page_owner) || $page_owner == -1) {
316                 $template_name = "Default_Template";
317             } else {
318                 if (!$template_name = user_info('template_name',$page_owner)) {
319                     $template_name = "Default_Template";
320                 }
321             }
322         }
323         
324     // Template ID override
325         $t = optional_param('template_preview');
326         if (!empty($t)) {
327             $template_name = $t;
328         }
329
330         // TODO: Load templates on demand with backward compatibility
331         templates_load_context($parameter['context']);
332
333     // Grab the template content
334         if ($template_name == "Default_Template" || ($parameter['context'] != "css" && $parameter['context'] != "pageshell")) {
335             $template_element = $template[$parameter['context']];
336         } else {
337             if (!isset($page_template_cache[$parameter['context']])) {
338                 if ($result = get_template_element($template_name, $parameter['context'])) {
339                     $page_template_cache[$parameter['context']] = $result;
340                 } else {
341                     $page_template_cache[$parameter['context']] = $template[$parameter['context']];
342                 }
343             } else {
344                 $result = $page_template_cache[$parameter['context']];
345             }
346             if (!empty($result)) {
347                 $template_element = $result->content;
348             } else {
349                 $template_element = $template[$parameter['context']];
350             }
351         }
352         
353         if (!empty($CFG->templates->variables_substitute) && !empty($CFG->templates->variables_substitute[$parameter['context']])) {
354             if (is_array($CFG->templates->variables_substitute[$parameter['context']])) {
355                 foreach ($CFG->templates->variables_substitute[$parameter['context']] as $sub_function) {
356                     $template_element .= $sub_function($vars);
357                 }
358             } elseif (is_callable($CFG->templates->variables_substitute[$parameter['context']])) {
359                 $template_element .= $CFG->templates->variables_substitute[$parameter['context']]($vars);
360             }
361         }
362
363         if ($parameter['context'] === 'topmenuitem') {
364             // error_log("templates_draw pcontext " . print_r($template_element));
365         }
366
367     // Substitute elements
368
369         $functionbody = "
370             \$passed = array(".var_export($parameter,true).",\$matches[1], '" . $template_name . "');
371             return templates_variables_substitute(\$passed);
372         ";
373         
374         // $template_element = templates_variables_substitute(array($parameter,$template_element));
375         $body = preg_replace_callback("/\{\{([A-Za-z_0-9: ]*)\}\}/i",create_function('$matches',$functionbody),$template_element);
376         
377         $run_result = $body;
378         return $run_result;
379 }
380
381 /***
382  *** Draws a form to create a new template based on one of the existing choices.
383  ***/
384 function templates_add () {
385     global $USER;
386
387
388     // Create a new template
389         $header = __gettext("Create theme"); // gettext variable
390         $desc = __gettext("Here you can create your own themes based on one of the existing public themes. Just select which public theme you would like to alter and then create your own. You will now have edit privilages."); // gettext variable
391
392         $panel = <<< END
393         
394         <h2>$header</h2>
395         <p>$desc</p>
396         <form action="index.php" method="post">
397         
398 END;
399
400         $panel .= <<< END
401         
402 END;
403
404         $panel .=templates_draw(array(
405                                                 'context' => 'databox1',
406                                                 'name' => __gettext("Theme name"),
407                                                 'column1' => display_input_field(array("new_template_name","","text"))
408                                             )
409                                             );
410         
411         $default = __gettext("Default Template"); // gettext variable
412         $templates_list = templates_list();
413         $column1 = "<select name=\"template_based_on\">";
414         foreach($templates_list as $template) {
415             $name = __gettext($template['name']);
416             $column1 .= "<option value=\"".$template['name']."\"";
417             if ($template['name'] == "Default Template") {
418                 $column1 .= " selected=\"selected\"";
419             }
420             $column1 .= ">" . $name . "</option>";
421         }
422         
423         $column1 .= <<< END
424             </select>
425 END;
426                         
427         $panel .=templates_draw(array(
428                                                 'context' => 'databox1',
429                                                 'name' => __gettext("Based on"),
430                                                 'column1' => $column1
431                                             )
432                                             );
433             
434         $buttonValue = __gettext("Create Theme"); // gettext variable
435         $panel .= <<< END
436             
437             <p>
438                 <input type="hidden" name="action" value="templates:create" />
439                 <input type="submit" value="$buttonValue" />
440             </p>
441         
442         </form>
443         
444 END;
445
446         return $panel;
447 }
448
449 function templates_edit () {
450
451
452     global $template;
453     global $template_definition;
454     global $USER;
455
456     if (!isset($parameter)) {
457     // Get template details
458         if (!$template_name = user_info('template_name',$USER->ident)) {
459             $template_name = "Default_Template";
460         }
461     } else {
462         if (!is_array($parameter)) {
463             $template_name = trim($parameter);
464         } else {
465             $template_name = "Default_Template";
466         }
467     }
468
469     // Grab title, see if we can edit the template
470         $editable = 0;
471         if ($template_name == "Default_Template") {
472             $templatetitle = __gettext("Default Theme");
473         } else {
474             if ($templatestuff = get_record('templates','shortname',$template_name)) {
475                 $templatetitle = $templatestuff->name;
476                 if ($templatestuff->owner == $USER->ident) {
477                     $editable = 1;
478                 }
479                 if (($templatestuff->owner != $USER->ident) && ($templatestuff->public != 'yes')) {
480                     $template_name = 'Default_Template';
481