/[drupal]/contributions/modules/snippets/snippets.module
ViewVC logotype

Contents of /contributions/modules/snippets/snippets.module

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


Revision 1.9 - (show annotations) (download) (as text)
Wed Mar 2 08:16:24 2005 UTC (4 years, 8 months ago) by axel
Branch: MAIN
CVS Tags: HEAD
Changes since 1.8: +21 -9 lines
File MIME type: text/x-php
Snippets declared as functions.
1 <?php
2 // $Id$
3 // -*- coding: utf8 -*-
4 /**
5 * @file
6 * Creating and executing of code snippets (site macros).
7 * This module is part of WaterWiki.
8 * Author: Axel <axel@drupal.ru>
9 * License: GPL v2 or above
10 */
11
12 /**
13 * Implementation of hook_node_name().
14 */
15 function snippets_node_name($node) {
16 return t('code snippet');
17 }
18
19 /**
20 * Implementation of hook_help().
21 */
22 function snippets_help($section = "admin/help#snippets") {
23 switch ($section) {
24 case "admin/modules#description":
25 // This description shows up on modules list page
26 return t("Allow to create snippets of PHP-code. Site editors or users may use these snippets as macros in their postings.");
27 case 'node/add#snippets':
28 // This description shows up when users click "create content"
29 return t('Add code snippet to the site code repository.');
30 }
31 }
32
33 /**
34 * Implementation of hook_perm().
35 * Permissions are:
36 ** 'create snippets' - allow to add nodes with PHP-code to site repository
37 ** 'view snippet code' - allow to view PHP-code of the snippet node, otherwise
38 * user will see only description of the snippet (usage help etc.)
39 ** 'use snippets' - allow to insert snippet tags in posts
40 */
41 function snippets_perm() {
42 return array("create snippets", "view snippet code", "use snippets");
43 }
44
45 /**
46 * Implementation of hook_settings().
47 */
48 function snippets_settings() {
49 $output = t("Carefully configure 'input formats' and allow creation of snippets only for priveleged/advanced users. Remember, what improper configuration of snippets may open big security hole on your site.");
50 $output .= form_textarea(t('Explanation or submission guidelines'), 'snippets_help', variable_get('snippets_help', ''), 70, 5, t('This text will be displayed at the top of the snippet submission form. It is useful for helping or instructing your users.'));
51 $output .= form_checkbox(t("Fast snippets"), "snippets_fast", 1 , variable_get("snippets_fast", 1), t("Snippets are fast but checking this option make them additionaly faster. But price of this speedup is lack of the node-based access grants for snippets: published/unpublished status and per node permissions are ignored."). " <b>Note: alpha-version of snippets work in 'Fast mode' only and disabling this option will ignored. Per node permissions for snippets will work in beta.</b>");
52 return $output;
53 }
54
55 /**
56 * Implementation of hook_menu().
57 * Show link to snippet creation.
58 */
59 function snippets_menu($may_cache) {
60 $items = array();
61 if ($may_cache) {
62 $items[] = array('path' => 'node/add/snippets', 'title' => t('code snippet'),
63 'access' => user_access('create snippets'));
64 $items[] = array('path' => 'snippets', 'title' => t('Snippets Repository'),
65 'callback' => 'snippets_page',
66 'access' => user_access('use snippets'),
67 'type' => MENU_CALLBACK);
68 }
69 return $items;
70 }
71
72 function snippets_form(&$node, &$error) {
73 $output = variable_get("snippets_help", "");
74
75 // Display taxonomies:
76 if (function_exists('taxonomy_node_form')) {
77 $output .= implode('', taxonomy_node_form('snippets', $node));
78 }
79
80 // Show snippet specific fields:
81 $output .= form_textfield(t('Snippet name'), 'snippet', $node->snippet, 60, 64, t('This name will be used for calling the code snippet from text of another node.'), NULL, TRUE);
82 $output .= form_textfield(t('Function name'), 'fname', $node->fname, 60, 64, t('Code of snippets are PHP-functions and may be used from another snippets. Let name for function. Name must be unique and consist of latin characters and numbers.'), NULL, TRUE);
83 $output .= form_textarea(t('Code'), 'code', $node->code, 60, 25, t('Code ot the snippet. Place the code without <code>&lt;?php</code> tags around it!'), NULL, TRUE);
84 $output .= form_textfield(t('Syntax help'), 'tip', $node->tip, 60, 128, t('Short explanation of the snippet parameters and result etc. This text will be shown on some pages instead of long description.'), NULL, FALSE);
85 $output .= form_textarea(t('Description'), 'body', $node->body, 60, 10, t('Explanation of the code, help or examples of usage this snippet.'));
86 $output .= filter_form('format', $node->format);
87
88 return $output;
89 }
90
91 /**
92 * Implementation of the hook_insert()
93 */
94 function snippets_insert($node) {
95 db_query("INSERT INTO {snippets} (nid, snippet, fname, tip, code) VALUES (%d, '%s', '%s', '%s')", $node->nid, $node->snippet, $node->tip, $node->code);
96 }
97
98 /**
99 * Implementation of hook_update().
100 */
101 function snippets_update($node) {
102 db_query("UPDATE {snippets} SET snippet = '%s', fname = '%s', tip = '%s', code = '%s' WHERE nid = %d", $node->snippet, strtolower($node->fname), $node->tip, $node->code, $node->nid);
103 }
104
105 /**
106 * Implementation of hook_delete().
107 */
108 function snippets_delete($node) {
109 db_query("DELETE FROM {snippets} WHERE nid = %d", $node->nid);
110 }
111
112 /**
113 * Implementation of hook_load().
114 */
115 function snippets_load($node) {
116 return db_fetch_object(db_query("SELECT nid, snippet, fname, tip, code FROM {snippets} WHERE nid = %d", $node->nid));
117 }
118
119 /**
120 * Implementation of hook_view().
121 */
122 function snippets_view(&$node, $teaser) {
123 if (user_access("view snippet code") && !$teaser) {
124 theme_snippets_view_code($node);
125 }
126 $node = node_prepare($node, $teaser);
127 }
128
129 /**
130 * Implementation of hook_validate().
131 */
132 function snippets_validate(&$node) {
133 // check for proper function name
134 if (!$node->fname) $ferror = t('You must enter a name of function.');
135 if (ereg(' ', $node->fname)) $ferror = t('The function name cannot contain spaces.');
136 if (ereg("[^\x80-\xF7 [:alnum:]@_.-]", $node->fname)) $ferror = t('The function name contains an illegal character. Use only digits or latin characters');
137 if ($ferror) {
138 form_set_error('fname', $ferror);
139 }
140 // check for snippet name or function name duplicates
141 $snippet = db_fetch_object(db_query("SELECT s.nid, s.snippet, s.fname FROM {snippets} s WHERE s.snippet = '%s' AND s.nid <> %d", $node->snippet, $node->nid));
142 if ($node->snippet == $snippet->snippet) {
143 form_set_error('snippet', t("The snippet with name %s already exists. Let unique name to your snippet.", array('%s' => l("$snippet->snippet", "node/$snippet->nid"))));
144 }
145 if ($node->fname == $snippet->$fname) {
146 form_set_error('fname', t("The function with name %s already exists. Let unique name to you function.", array('%s' => l("$snippet->fname", "node/$snippet->nid"))));
147 }
148 }
149
150 /**
151 * Implementation of hook_link().
152 */
153 function snippets_link($type, $node = 0, $main) {
154 $links = array();
155
156 if ($type == 'node' && $node->type == 'snippets' && !$main) {
157 $links[] = l(t('Snippets Repository'), "snippets", array("title" => t("Go to Snippets Repository")));
158 }
159
160 return $links;
161 }
162
163 /**
164 * Implementation of hook_page().
165 */
166 function snippets_page() {
167 // Fast mode:
168 $snippets = db_query("SELECT nid, snippet, tip FROM {snippets} ORDER BY snippet");
169 while ($snippet = db_fetch_object($snippets)) {
170 // Fast mode:
171 $terms = db_query("SELECT td.tid, td.name FROM {term_data} td INNER JOIN {term_node} tn ON td.tid = tn.tid WHERE tn.nid = %d", $snippet->nid);
172 $term_list = array();
173 while ($term = db_fetch_object($terms)) {
174 $term_list[$term->tid] = $term->name;
175 }
176 $snippet_list[$snippet->snippet] = array("nid" => $snippet->nid, "tip" => $snippet->tip, "terms" => $term_list);
177 }
178 return theme_snippets_page($snippet_list);
179 }
180
181 /**
182 * Internal function for extracting parameters from macro.
183 */
184 function _snippets_params($macro) {
185 // We assume what parameters separated by '|'
186 $snippet = explode('|', $macro);
187 $name = trim(array_shift($snippet));
188 // But name of macro may be separated by space (alternative of '|')
189 if ($pos = strpos($name, ' ')) {
190 array_unshift($snippet, trim(substr($name, $pos)));
191 $name = trim(substr($name, 0, $pos));
192 }
193 return array('name' => $name, 'params' => $snippet, 'source' => $macro);
194 }
195
196 /**
197 * Internal function for extracting parameters from macro.
198 */
199 function _snippets_names($macro) {
200 if (!$pos = strpos($macro, '|')) {
201 if (!$pos = strpos($macro, ' ')) {
202 return $macro;
203 }
204 }
205 return check_query(addslashes(trim(substr($macro, 0, $pos))));
206 }
207
208 /**
209 * Implementation of hook_filter().
210 */
211 function snippets_filter($op, $delta = 0, $format = -1, $text = '') {
212 if ($op == "list") {
213 // We offer one filter in this module:
214 return array(0 => t('Snippet macros'));
215 }
216
217 switch ($op) {
218
219 case "description":
220 return t("Substitutes a macro occurencies with result of snippet code execution. Use carefully!");
221
222 case "prepare":
223 return $text;
224
225 case "process":
226 if (!user_access("use snippets")) return $text;
227 preg_match_all("/\[ ( [^\[\]]+ )* \]/x", $text, $matches);
228 $matches = array_unique($matches[1]);
229 $snippet_map = array_map("_snippets_params", $matches);
230 $snippet_names = array_map("_snippets_names", $matches);
231 $snippet_str = implode("', '", $snippet_names);
232 // Fast mode:
233 $snippets = db_query("SELECT snippet, fname, code FROM {snippets} s WHERE s.snippet IN ('". $snippet_str. "')");
234
235 while ($snippet = db_fetch_object($snippets)) {
236 $snippet_defs[] = '<?php if (!function_exists(\'snippet_'. $snippet->fname. '\')) function snippet_'. $snippet->fname. '($SNIPPET_NAME, $SNIPPET_PARAMS, $SNIPPET_MACRO) { '. $snippet->code. ' } ?>';
237 $snippet_names[$snippet->snippet] = $snippet->fname;
238 }
239 if (!$snippet_defs) return $text; // no one snippet defined
240 $definitions = implode("\n", $snippet_defs);
241
242 foreach($snippet_map as $macro) {
243 if ($fname = $snippet_names[$macro['name']]) {
244 $parray = array();
245 foreach($macro['params'] as $param) {
246 $parray[] = "'". addslashes($param). "'";
247 }
248 // Prepare params for macro function call
249 $params = array();
250 $params[] = "'". addslashes($macro['name']). "'"; // name
251 $params[] = 'array('. implode(',', $parray). ')'; // params
252 $params[] = "'". addslashes($macro['source']). "'"; // macro
253 $call = '<?php print_r(snippet_'. $fname. '('. implode(", ", $params). ')); ?>';
254 $text = str_replace('['. $macro['source']. ']', $call, $text);
255 }
256 }
257 return drupal_eval($definitions. $text);
258 }
259 }
260
261 /**
262 * Implementation of hook_filter_tips().
263 */
264 function snippets_filter_tips($delta, $format, $long = FALSE) {
265 if ($long) {
266 return t("Every instance of the macros will replaced with result of execution code snippet binded to this macro. Macros syntax is [macro] or [macro|param1|param2|param3]. The full list of the available macros is here: %s.", array('%s' => l(t("Snippets Repository"), "snippets")));
267 }
268 else {
269 return t("You may use predefined macros. See: %s.", array('%s' => l(t("Snippets Repository"), "snippets")));
270 }
271 }
272
273 /**
274 * Format the snippets page (Snippets Repository).
275 * Params:
276 * $snippet_list => array("snippet" => array of snippet options)
277 * $mode => 0 - normal, 1 - fast
278 * In "fast mode" less fields transferred to function - only
279 * "nid" and "tip" fields available.
280 *
281 * @ingroup themeable
282 */
283 function theme_snippets_page($snippet_list, $mode=0) {
284 // Some ugly default HTML here, ovewrite it in you theme!
285 if (user_access("create snippets")) {
286 $content[] = "<ul><li>". l(t("Add new snippet to repository"), "node/add/snippets"). "</li></ul>";
287 }
288 foreach($snippet_list as $snippet => $desc) {
289 $nid = $desc["nid"];
290 if (user_access("create snippets")) {
291 $edit_links = l(t("edit"), "node/$nid/edit", array("title" => t("Edit code and description of the snippet.")));
292 }
293 $terms = array();
294 foreach($desc["terms"] as $tid => $term) {
295 $terms[] = l("$term", "/taxonomy/term/$tid");
296 }
297 $term_links = "";
298 if($terms) {
299 $term_links = t("Categories: "). implode(' | ', $terms);
300 }
301 $description = $desc["tip"] ? t("Usage: "). $desc["tip"] : "";
302 $content[] = "<div class=\"description\"><h2>". l("[$snippet]", "node/$nid"). "</h2>". $description. "</div><div class=\"terms\">$term_links</div>$edit_links";
303 }
304 print theme('page', implode("\n", $content));
305 }
306
307 /**
308 * Format the view of the single snippet description.
309 *
310 * @ingroup themeable
311 */
312 function theme_snippets_view_code(&$node) {
313 // Some ugly default HTML here, ovewrite it in you theme!
314 $node->body .= "<br /><br /><div class=\"codeblock\"><h2>". t("Macro"). ": ". $node->snippet. "</h2><div class=\"description\">". $node->tip. "</div><div class=\"code\"><?php function (snippet_". $node->fname. ") {\n". $node->code. " } ?></div></div>";
315 }
316
317 ?>

  ViewVC Help
Powered by ViewVC 1.1.2