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

Contents of /contributions/modules/jqp/jqp.module

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


Revision 1.4 - (show annotations) (download) (as text)
Sun Apr 19 10:35:14 2009 UTC (7 months, 1 week ago) by skilip
Branch: MAIN
CVS Tags: DRUPAL-6--2-0-BETA1, HEAD
Branch point for: DRUPAL-6--2
Changes since 1.3: +1 -1 lines
File MIME type: text/x-php
Updated jqp.module and jqp.info to v.2
1 <?php
2 // $Id: jqp.module,v 2.0 2009/04/19 12:32:00 jjeff, skilip Exp $
3
4 /**
5 * @file
6 * Used to register and load javascript libraries and plugins from a cetral point
7 */
8
9 /**
10 * Implementation of hook_help().
11 */
12 function jqp_help($path, $arg) {
13
14 switch ($path) {
15 case 'admin/help#jqp':
16 $output[] = '<p>'. t('Javascript libraries can either be built up from an single javascript file, a javascript plugin or a set of javascript files, sometimes with stylesheets included. These libraries can be used to extend the look and feel of modules.') .'</p>';
17 $output[] = '<p>'. t('Libraries can be registered in several ways:') .'</p>';
18 $output[] = '<ul>';
19 $output[] = ' <li>';
20 $output[] = '<h4>'. t('.info files') .'</h4>';
21 $output[] = '<p>'. t('This is the preferred way of registering a library into javascript libraries\' cache. During installation, jQp module will check for the presence of a js_libraries folder in one of the following directories:') .'</p>';
22 $output[] = '<ul>';
23 $output[] = ' <li>js_libraries</li>';
24 $output[] = ' <li>sites/all/js_libraries</li>';
25 $output[] = ' <li>$profile/install_profile/js_libraries</li>';
26 $output[] = ' <li>$conf_path/js_libraries</li>';
27 $output[] = ' <li>$file_directory_path/js_libraries</li>';
28 $output[] = '</ul>';
29 $output[] = '<p>'. t('If this directory exists, this should be the place to place all libraries as separate folders, containing all required files for the library. If a library folder contains a .info file, this will be used to register the library. Here\'s an example of how a .info file should be written:', $replacements) .'</p>';
30 $output[] = '<pre>';
31 $output[] = '; $Id$';
32 $output[] = 'name = Library Name';
33 $output[] = 'description = Description of the library';
34 $output[] = 'project_url = http://www.library_project_page.org';
35 $output[] = 'stylesheets[][] = style.css';
36 $output[] = 'scripts[][] = jquery.test.min.js';
37 $output[] = 'scripts[1.4.4][] = jquery.test[1.4.4].min.js';
38 $output[] = 'scripts[1.4.4][] = drupal.js';
39 $output[] = '</pre>';
40 $output[] = '<p>'. t('This .info file will register two versions of this library (default and 1.4.4). style.css is added as a first element of the stylesheets array, and will therefore will have 0 as key. All elements of both the stylesheets and scripts array with a 0 key will be treated as the default version. Files with other keys, such as 1.4.4, will be handled as separate versions. If a specific version of a library is loaded, and there\'s no file type which overrides the default one, the default one is included automatically. Note that versions can include several files!') .'</p>';
41 $output[] = '</li>';
42 $output[] = '<li>';
43 $output[] = '<h4>'. t('hook_jqp()') .'</h4>';
44 $output[] = '<p>'. t('Modules can also register their own libraries using the provided hook function.') .'</p>';
45 $output[] = '<p><strong>'. t('Definition') .':</strong></p>';
46 $output[] = '<p><code>hook_jqp(&amp;$js_libraries)</code></p>';
47 $output[] = '<p><strong>'. t('Description') .':</strong></p>';
48 $output[] = '<p>'. t('Provide other modules a hook to add custom libraries or alter already registered libraries.') .'</p>';
49 $output[] = '<p><strong>'. t('Parameters') .':</strong></p>';
50 $output[] = '<p><code>$js_libraries</code>: '. t('An associative array in which the library register is built up.') .'</p>';
51 $output[] = '<p><strong>'. t('Code') .':</strong></p>';
52 $output[] = '<pre class="php">';
53 $output[] = '/**';
54 $output[] = ' * Implemantation of hook_jqp().';
55 $output[] = ' */';
56 $output[] = 'function hook_jqp(&amp;$js_libraries) {';
57 $output[] = ' $js_libraries[\'plugin1\'] = array(';
58 $output[] = ' \'name\' => \'Plugin 1\',';
59 $output[] = ' \'description\' => \'This plugin is registered by a module.\',';
60 $output[] = ' \'project_url\' => \'http://www.library_project_page.org\',';
61 $output[] = ' \'scripts\' => array(';
62 $output[] = ' array(\'jquery.hoi.min.js\'), // This will have key 0, so it is the default version';
63 $output[] = ' \'1.4.3-BETA-3\' => array(\'jquery.hoi[2].min.js\'),';
64 $output[] = ' ),';
65 $output[] = ' \'stylesheets\' => array(';
66 $output[] = ' array(\'plugin1.css\'),';
67 $output[] = ' \'1.4.3-BETA-3\' => array(';
68 $output[] = ' \'plugin1[1.4.3-BETA-3].css\'';
69 $output[] = ' ),';
70 $output[] = ' ),';
71 $output[] = ' );';
72 $output[] = '}';
73 $output[] = '</pre>';
74 $output[] = '</li>';
75 $output[] = '<li>';
76 $output[] = '<h4>'. t('Loading a javascript library') .'</h4>';
77 $output[] = '<p>'. t('Loading a javascript library or plugin can be done using drupal_add_js_library().') .'</p>';
78 $output[] = '<p><strong>'. t('Definition') .':</strong></p>';
79 $output[] = '<p><code>drupal_add_js_library($name, $version = 0, $options = array())</code></p>';
80 $output[] = '<p><strong>'. t('Description') .':</strong></p>';
81 $output[] = '<p>'. t('Load a shared library from the javascript library directory.') .'</p>';
82 $output[] = '<p><strong>'. t('Parameters') .':</strong></p>';
83 $output[] = '<p><code>$name</code>: '. t('(required)') ."&nbsp;". t('the name of the library or plugin to load.') .'</p>';
84 $output[] = '<p><code>$version</code>: '. t('(optional)') ."&nbsp;". t('the version of the library to load. If omitted the default version is loaded.') .'</p>';
85 $output[] = '<p><code>$options</code>: '. t('(optional)') ."&nbsp;". t('Array containing additional options to pass to drupal_add_js or drupal_add_css.') .'</p>';
86 $output[] = '<pre class="php">';
87 $output[] = ' array(';
88 $output[] = ' \'css\' => array($type = \'module\', $media = \'all\', $preprocess = TRUE),';
89 $output[] = ' \'js\' => array($type = \'module\', $scope = \'header\', $defer = FALSE, $cache = TRUE, $preprocess = TRUE),';
90 $output[] = ' );';
91 $output[] = '</pre>';
92 $output[] = '<p><strong>'. t('Example') .':</strong></p>';
93 $output[] = '<p><code>drupal_add_js_library(\'beautytips\', \'0.9\', array(\'css\' => array(\'theme\', \'all\', FALSE)));</code></p>';
94 $output[] = '</li>';
95 $output[] = '<li>';
96 $output[] = '<h4>'. t('Administration pages') .'</h4>';
97 $output[] = '<p>'. t('After registering a library, the paths of the attached files can be changed at the !admin_pages. It is also possible to attach an detach files per version.', array('!admin_pages' => l('administration pages', 'admin/build/jqp'))) .'</p>';
98 $output[] = '</li>';
99 $output[] = '</ul>';
100 return join("\n", $output);
101 case 'admin/build/jqp':
102 $output[] = '<p>'. t('Javascript libraries can either be built up from an single javascript file, a javascript plugin or a set of javascript files, sometimes with stylesheets included. These libraries can be used to extend the look and feel of modules.') .'</p>';
103 $output[] = '<p>'. t('After registering a library, the paths of the attached files can be changed here. It is also possible to attach and detach files per version by clicking on the configure link.') .'</p>';
104 $output[] = '<p>'. t('You can completely rebuild the cache by clicking !rebuild link.', array('!rebuild' => l(t('this'), 'admin/build/jqp/rebuild_confirm'))) .'</p>';
105 return join("\n", $output);
106 }
107 }
108
109 /**
110 * Implementation of hook_perm().
111 */
112 function jqp_perm() {
113 return array('administer javascript libraries');
114 }
115
116 /**
117 * Implementation of hook_menu().
118 */
119 function jqp_menu() {
120
121 $items['admin/build/jqp'] = array(
122 'title' => 'Javascript libraries',
123 'description' => "Administer javascript libraries.",
124 'page callback' => 'jqp_status_page',
125 'access arguments' => array('administer javascript libraries'),
126 'file' => 'jqp.admin.inc',
127 );
128
129 $items['admin/build/jqp/rebuild_confirm'] = array(
130 'title' => 'Reset all libraries',
131 'page callback' => 'drupal_get_form',
132 'page arguments' => array('jqp_confirm_form'),
133 'access arguments' => array('administer javascript libraries'),
134 'type' => MENU_CALLBACK,
135 'file' => 'jqp.admin.inc',
136 );
137
138 $items['admin/build/jqp/%js_library/%'] = array(
139 'title callback' => 'jqp_overview_title',
140 'title arguments' => array(3, 4),
141 'page callback' => 'drupal_get_form',
142 'page arguments' => array('js_library_edit', 3, 4),
143 'access arguments' => array('administer javascript libraries'),
144 'type' => MENU_CALLBACK,
145 'file' => 'jqp.admin.inc',
146 );
147 $items['admin/build/jqp/%js_library/%/list'] = array(
148 'title' => 'List files',
149 'type' => MENU_DEFAULT_LOCAL_TASK,
150 'weight' => -10,
151 'file' => 'jqp.admin.inc',
152 );
153 $items['admin/build/jqp/%js_library/%/reset'] = array(
154 'title' => 'Reset library',
155 'page callback' => 'drupal_get_form',
156 'page arguments' => array('jqp_confirm_form', 3, 4),
157 'access arguments' => array('administer javascript libraries'),
158 'type' => MENU_CALLBACK,
159 'file' => 'jqp.admin.inc',
160 );
161 $items['admin/build/jqp/%js_library/%/remove_file'] = array(
162 'title' => 'Reset library',
163 'page callback' => 'drupal_get_form',
164 'page arguments' => array('jqp_confirm_form', 3, 4),
165 'access arguments' => array('administer javascript libraries'),
166 'type' => MENU_CALLBACK,
167 'file' => 'jqp.admin.inc',
168 );
169 $items['admin/build/jqp/%js_library/%/add'] = array(
170 'title' => 'Add file',
171 'page callback' => 'drupal_get_form',
172 'page arguments' => array('js_library_edit', 3, 4, 5),
173 'access arguments' => array('administer javascript libraries'),
174 'type' => MENU_LOCAL_TASK,
175 'file' => 'jqp.admin.inc',
176 );
177
178 $items['jqp_ajax_check_file'] = array(
179 'page callback' => '_jqp_ajax_check_file',
180 'access arguments' => array('administer javascript libraries'),
181 'type' => MENU_CALLBACK,
182 'file' => 'jqp.admin.inc',
183 );
184 $items['jqp_autocomplete'] = array(
185 'page callback' => '_jqp_autocomplete',
186 'access arguments' => array('administer javascript libraries'),
187 'type' => MENU_CALLBACK,
188 'file' => 'jqp.admin.inc',
189 );
190 return $items;
191 }
192
193 /**
194 * Implementation of hook_theme().
195 */
196 function jqp_theme() {
197 return array(
198 'js_library_edit' => array(
199 'arguments' => array('form' => array(), 'js_library' => array(), 'version' => 0),
200 )
201 );
202 }
203
204 /**
205 * Title callback.
206 */
207 function jqp_overview_title($js_library, $version = NULL) {
208 return $js_library->info['name'] . ($version ? " v.$version" : "");
209 }
210
211 /**
212 * Add a shared library from the javascript library directory
213 *
214 * @param $name
215 * the name of the library to add
216 *
217 * @param $version
218 * the version of the library to add
219 *
220 * @param $options
221 * Array containing additional options to pass to drupal_add_js or drupal_add_css.
222 * array(
223 * 'css' => array($path = NULL, $type = 'module', $media = 'all', $preprocess = TRUE),
224 * 'js' => array($data = NULL, $type = 'module', $scope = 'header', $defer = FALSE, $cache = TRUE, $preprocess = TRUE),
225 * );
226 *
227 * @see drupal_add_js()
228 * @see drupal_add_css()
229 */
230 function drupal_add_js_library($name, $version = 0, $options = array()) {
231 // Get the library
232 $js_library = js_library_load($name);
233
234 $types = array('js' => 'scripts', 'css' => 'stylesheets');
235 $files = array();
236
237 // Loop trough the file types
238 foreach ($types as $key => $type) {
239
240 // Add the files of the default version, if exist
241 if ($version !== 0 && is_array($js_library->info[$type][0])) {
242 $files[$key] = $js_library->info[$type][0];
243 }
244
245 if (is_array($js_library->info[$type][$version])) {
246 $files[$key] = $js_library->info[$type][$version];
247 }
248 }
249
250 // Load all files using drupal_add_js and drupal_add_css
251 foreach ($types as $key => $type) {
252
253 if (!$files[$key]) {
254 continue;
255 }
256
257 foreach ($files[$key] as $path) {
258 //trace("$path $key");
259 $args[0] = $path;
260 $args = array_merge($args, $options);
261 call_user_func_array("drupal_add_$key", $args);
262 }
263 }
264 }
265
266 /**
267 * Scan the 'js_libraries', 'modules' and 'themes' directories for .js and .css files
268 *
269 * @return an array where key is file name and value is file path
270 *
271 * Example:
272 * array('sites/all/modules/cck/content.js' => (object)array(
273 * 'filename' => 'sites/all/modules/cck/content.js',
274 * 'basename' => 'content.js',
275 * 'name' => 'content',
276 * );
277 *
278 * LIKE MODULES, javascript libraries should have unique file names
279 *
280 * @see _jqp_autocomplete()
281 */
282 function jqp_scan_dir() {
283 static $files;
284 if (!isset($files)) {
285 if ($cache = cache_get('jqp')) {
286 $files = $cache->data;
287 }
288 else {
289 $profile = variable_get('install_profile', 'default');
290 $config = conf_path();
291 $file_dir = file_directory_path();
292 $files = array();
293
294 foreach (array('modules', 'js_libraries', 'themes') as $directory) {
295 $searchdir[] = "$directory";
296 $searchdir[] = "sites/all/$directory";
297 $searchdir[] = "profiles/$profile/$directory";
298 $searchdir[] = "$config/$directory";
299 $searchdir[] = "$file_dir/$directory";
300 }
301
302 foreach ($searchdir as $dir) {
303 if (file_exists($dir)) {
304 $files = array_merge($files, file_scan_directory($dir, '(\.js$|\.css$)', array('.', '..', 'CVS'), 0, TRUE, 'filename', 0));
305 }
306 }
307
308 cache_set('jqp', $files);
309 }
310 }
311 return $files;
312 }
313
314 /**
315 * Implementation of hook_requirements().
316 *
317 * Checks if a js_libraries directory is present at install
318 */
319 function jqp_requirements($phase) {
320 // Ensure translations don't break at install time
321 $t = get_t();
322
323 // Report Drupal version
324 if ($phase == 'runtime') {
325 $library_exists = _check_js_library_directory('js_libraries');
326
327 $requirements['jqp'] = array(
328 'title' => $t('Javascript libraries directory'),
329 'value' => $library_exists ? $t('Exists') : $t('Not present'),
330 'severity' => $library_exists ? REQUIREMENT_OK : REQUIREMENT_WARNING,
331 );
332
333 if (!$library_exists) {
334 $requirements['jqp']['description'] = $t('There\'s no javascript libraries folder present yet! Please create a directory called "js_libraries" at sites/all/js_libraries or sites/[example.com]/js_libraries or similar.');
335 }
336 }
337
338 return $requirements;
339 }
340
341 /**
342 * Searches for a js_libraries directory
343 */
344 function _check_js_library_directory($directory) {
345 global $profile;
346 $config = conf_path();
347
348 $searchdir = array(
349 "$directory",
350 "sites/all/$directory",
351 "profiles/$profile/$directory",
352 "$config/$directory",
353 );
354
355 foreach ($searchdir as $dir) {
356 if (file_exists($dir)) {
357 variable_set('jqp_directory', $dir);
358 return TRUE;
359 }
360 }
361 return FALSE;
362 }
363
364 /**
365 * Rebuilds the javascript libraries cache.
366 *
367 * It registers both all libraries defined in library info files,
368 * as well as libraries defined in hook_jqp.
369 *
370 * @param $reset
371 * If true, all javascript libraries are completely reindexed.
372 * Otherwise only libraries which havent been costumized by administrators are reindexed.
373 */
374 function jqp_rebuild_cache($reset = FALSE) {
375
376 cache_clear_all('jqp', 'cache');
377
378 // Set defaults for library info
379 $defaults = array(
380 'description' => '',
381 'version' => NULL,
382 );
383
384 // The following code is merely copied from drupal_system_listing.
385 // Added the file_directory to be a possible location for the library directory.
386 $profile = variable_get('install_profile', 'default');
387 $directory = 'js_libraries';
388 $config = conf_path();
389 $file_dir = file_directory_path();
390 $js_libraries = array();
391
392 $searchdir = array(
393 "$directory",
394 "sites/all/$directory",
395 "profiles/$profile/$directory",
396 "$config/$directory",
397 "$file_dir/$directory",
398 );
399
400 // Get current list of libraries registerd by dot-info files
401 foreach ($searchdir as $dir) {
402 if (file_exists($dir)) {
403 $js_libraries = array_merge($js_libraries, file_scan_directory($dir, '\.info$', array('.', '..', 'CVS'), 0, TRUE, 'name', 0));
404 }
405 }
406
407 // Get all libraries registerd by modules
408 $module_libraries = module_invoke_all('jqp');
409 if (is_array($module_libraries)) {
410 foreach ($module_libraries as $module_library_name => $module_library) {
411 $js_libraries[$module_library_name] = (object) ($module_library + array('type' => 'javascript library'));
412 }
413 }
414
415 // Extract current files from database.
416 system_get_files_database($js_libraries, 'javascript library');
417
418 ksort($js_libraries);
419
420 foreach ($js_libraries as $name => $library) {
421 $versions_changed = array();
422
423 // Look for the info file.
424 $library->info = drupal_parse_info_file(dirname($library->filename) .'/'. $library->name .'.info');
425
426 // If the library doesn't provide info, we're dealing with an module registered library.
427 // We'll create the info manually.
428 if (empty($library->info)) {
429 $info = clone $library;
430 unset($info->type, $info->info, $js_libraries[$name]->scripts, $js_libraries[$name]->styles);
431 $js_libraries[$name]->info = (array) $info;
432 $js_libraries[$name]->name = $name;
433 $js_libraries[$name]->filename = "$name-module-jqp";
434 }
435
436 // Merge in defaults and save.
437 $js_libraries[$name]->info = $library->info + $defaults;
438
439 // Used to merge saved data with loaded data
440 $old_library = js_library_load($name);
441
442 // Loop trough each file type
443 foreach (array('stylesheets', 'scripts') as $type) {
444
445 // Continue if no data is found for this file type
446 if (empty($js_libraries[$name]->info[$type])) {
447 continue;
448 }
449
450 $files = array();
451
452 // Get the data of each file type per version
453 foreach ($js_libraries[$name]->info[$type] as $version => $data) {
454 // Check whether this version have been madified and saved before
455 if (isset($old_library->info[$type][$version]['changed']) && $reset === FALSE) {
456 $versions_changed[] = $version;
457 }
458
459 foreach ($data as $file_name) {
460 $dirname = file_exists($js_libraries[$name]->filename) ? dirname($js_libraries[$name]->filename) : '';
461 $files[$version][$file_name] = $dirname ? "$dirname/$file_name" : $file_name;
462
463 // Let's store the basepath of the dot-info file
464 $library->info['base'] = ($dirname ? $dirname : NULL);
465 }
466 }
467
468 $js_libraries[$name]->info[$type] = $files;
469 }
470
471 if (!empty($versions_changed)) {
472 foreach ($versions_changed as $version_changed) {
473 if (isset($js_libraries[$name]->info['scripts'][$version_changed])) {
474 $js_libraries[$name]->info['scripts'][$version_changed] = $old_library->info['scripts'][$version_changed];
475 }
476 if (isset($js_libraries[$name]->info['stylesheets'][$version_changed])) {
477 $js_libraries[$name]->info['stylesheets'][$version_changed] = $old_library->info['stylesheets'][$version_changed];
478 }
479 }
480 }
481
482 // Invoke hook_system_info_alter() to give installed modules a chance to
483 // modify the data in the .info files if necessary.
484 drupal_alter('system_info', $js_libraries[$name]->info, $js_libraries[$name]);
485
486 // Update the contents of the system table:
487 if (isset($library->status) || (isset($library->old_filename) && $library->old_filename != $library->filename)) {
488 db_query("UPDATE {system} SET info = '%s', name = '%s', filename = '%s', bootstrap = %d WHERE filename = '%s'", serialize($js_libraries[$name]->info), $library->name, $library->filename, $bootstrap, $library->old_filename);
489 }
490 else {
491 // This is a new library.
492 db_query("INSERT INTO {system} (name, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $name, serialize($js_libraries[$name]->info), 'javascript library', $js_libraries[$name]->filename, 0, 0, $bootstrap);
493 }
494 }
495 return $js_libraries;
496 }
497
498 /**
499 * Fetches all cached libraries from the system table
500 */
501 function jqp_list($refresh = FALSE) {
502 static $list;
503
504 if ($refresh) {
505 $list = array();
506 }
507
508 if (empty($list)) {
509 $list = array();
510 $js_libraries = array();
511 $result = db_query("SELECT * FROM {system} WHERE type = '%s'", 'javascript library');
512
513 while ($library = db_fetch_object($result)) {
514 $library->info = unserialize($library->info);
515 $js_libraries[] = $library;
516
517 foreach (array('stylesheets', 'scripts') as $type) {
518 if (empty($library->info[$type])) {
519 continue;
520 }
521
522 foreach ($library->info[$type] as $version => $data) {
523 foreach ($data as $file_name => $path) {
524 if (file_exists($path)) {
525 $library->{$type}[$version][$file_name] = $path;
526 }
527 }
528 }
529 }
530 $list[$library->name] = $library;
531 }
532 }
533 return $list;
534 }
535
536 /**
537 * Loads a single library
538 *
539 * @param $name
540 * the name of the library to add
541 */
542 function js_library_load($name) {
543 static $js_libraries;
544
545 if (empty($js_libraries)) {
546 $js_libraries = jqp_list();
547 }
548 return $js_libraries[$name];
549 }
550
551 /**
552 * Implementation of hook_jqp().
553 *
554 * ONLY FOR TESTING PURPOSES!!!
555 */
556 function jqp_jqp() {
557 $js_libraries['dummy_plugin1'] = array(
558 'name' => 'Dummy plugin 1',
559 'description' => 'This plugin is registered by the jqp module.',
560 'project_url' => 'http://www.library_project_page.org',
561 'scripts' => array(
562 array('jquery.dummy.min.js'),
563 '1.4.3-BETA-3' => array('jquery.dummy[1.4.3-BETA-3].min.js'),
564 ),
565 'stylesheets' => array(
566 array('styles.css'),
567 '1.4.3-BETA-3' => array(
568 'styles[1.4.3-BETA-3].css'
569 ),
570 ),
571 );
572 $js_libraries['dummy_plugin2'] = array(
573 'name' => 'Dummy plugin 2',
574 'description' => 'This plugin is also registered by the jqp module.',
575 'project_url' => 'http://www.library_project_page.org',
576 'scripts' => array(
577 array('jquery.dummy2.min.js'),
578 '2' => array('jquery.dummy2[2].min.js'),
579 ),
580 );
581 return $js_libraries;
582 }

  ViewVC Help
Powered by ViewVC 1.1.2