View source
<?php
use Drupal\Core\File\FileSystemInterface;
module_load_include('inc', 'jstimer', '/jstimer.field');
function jstimer_help($path, $arg) {
switch ($path) {
case 'admin/modules#description':
return t('A module which creates javascript timers.');
case 'admin/help#jstimer':
$output = <<<HELP_TXT
<p>Please look at the readme.txt file that comes with this module. It really has a lot of great information.</p>
<p>The javascript timer module provides an api to allow you to make dhtml widgets which are updated every second.
There are some good examples for node and block usage in the readme.txt file.
Please look at it.</p>
HELP_TXT;
$output .= '<p>Usage Example for a Node<br/><span class="jst_timer">Count Up to 11:30<br/><span style="display:none" class="datetime">2007-02-26T09:30:00</span><br/><span style="display:none"<br/>';
$output .= '<span style="display:none" class="dir">up</span><br/></span></p>';
return $output;
}
}
function jstimer_theme($existing, $type, $theme, $path) {
$themes = array(
'jstimer' => array(
'variables' => array(
'widget_name' => NULL,
'widget_args' => NULL,
),
),
);
return $themes;
}
function theme_jstimer($variables) {
$widget_name = $variables['widget_name'];
$widget_args = $variables['widget_args'];
$widgets = jstimer_get_widgets();
$widget = NULL;
foreach ($widgets as $w) {
if ($widget_name == $w->name) {
$widget = $w;
break;
}
}
if (!isset($widget)) {
return "Widget {$widget_name} not found.";
}
if (function_exists($widget->theme_function)) {
return call_user_func($widget->theme_function, $widget_args);
}
else {
return "Widget {$widget_name} theme not found.";
}
}
function jstimer_menu() {
$items = array();
$items['admin/config/system/jstimer'] = array(
'title' => 'Javascript timer',
'description' => 'Configure Javascript timer widgets and settings.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'jstimer_admin_settings',
),
'access arguments' => array(
'administer site configuration',
),
'file' => 'jstimer.admin.inc',
);
return $items;
}
function jstimer_page_attachments_alter(array &$page) {
$page['#attached']['library'][] = 'jstimer/jstimer';
}
function jstimer_clean_for_javascript($format_string = '') {
$patterns = array(
'/\\n/',
'/\\r/',
'/\'/',
);
$replacements = array(
'<br/>',
'',
'"',
);
return preg_replace($patterns, $replacements, $format_string);
}
function jstimer_build_js_cache() {
$path = 'public://jstimer';
\Drupal::service('file_system')
->prepareDirectory($path, FileSystemInterface::CREATE_DIRECTORY);
$data = jstimer_get_javascript(TRUE);
file_save_data($data, $path . '/timer.js', FileSystemInterface::EXISTS_REPLACE);
\Drupal::messenger()
->addStatus(t('Javascript timer javascript file saved to: ') . $path . '/timer.js');
if (!file_exists($path . '/timer.js')) {
\Drupal::messenger()
->addError(t('File Create Error: timer.js could not be created'));
}
else {
\Drupal::configFactory()
->getEditable('jstimer.settings')
->set('jstimer_timerjs_path', $path . '/timer.js')
->save();
}
return $path . '/timer.js';
}
function jstimer_get_widgets($reset = FALSE) {
static $widgets;
if (!isset($widgets) || $reset) {
$widgets = \Drupal::moduleHandler()
->invokeAll('jstwidget');
}
return $widgets;
}
function jstimer_get_javascript($reset = FALSE) {
$widget_list = jstimer_get_widgets($reset);
$active_widgets = array();
$widget_implementation_code = '';
foreach ($widget_list as $widget) {
$active_widgets[] = "new " . $widget->js_name . "()";
$widget_implementation_code .= $widget->js_code;
}
$active_widgets_instantiation = implode(",\n ", $active_widgets);
$ouput = <<<JAVASCRIPT_CODE
// bootstrap
Drupal.behaviors.jstimer = {
attach: function(context) {
Drupal.jstimer.countdown_auto_attach(
new Array(
{<span class="php-variable">$active_widgets_instantiation</span>}
)
);
}
}
// Namespace for most of the javascript functions.
Drupal.jstimer = {};
Drupal.jstimer.once = 0;
// Array that holds all elements that need to be updated.
Drupal.jstimer.timer_stack = new Array();
// Attach all active widgets to their respective dom objects.
Drupal.jstimer.countdown_auto_attach = function (jstimer_active_widgets) {
// Call .attach() on the active widget items.
for (var i=0; i<jstimer_active_widgets.length; i++) {
jstimer_active_widgets[i].attach();
}
// If you have any widget items, start the timing loop.
if ( Drupal.jstimer.timer_stack.length > 0 && Drupal.jstimer.once < 1) {
Drupal.jstimer.timer_loop();
Drupal.jstimer.once++;
}
}
// The timing loop.
Drupal.jstimer.timer_loop = function() {
// run backwards so we can remove items and not messup the loop data.
for (var i = Drupal.jstimer.timer_stack.length - 1; i >= 0; i--) {
if ( Drupal.jstimer.timer_stack[i].update() == false ) {
Drupal.jstimer.timer_stack.splice(i, 1);
}
}
// Stop the timer if there are not more timer items.
if ( Drupal.jstimer.timer_stack.length > 0 ) {
setTimeout('Drupal.jstimer.timer_loop()',999);
}
}
{<span class="php-variable">$widget_implementation_code</span>}
// Util functions
function LZ(x) {
return (x >= 10 || x < 0 ? "" : "0") + x;
}
// iso8601 date parsing routines. Extends the built-in javascript date object.
Date.prototype.jstimer_set_iso8601_date = function (string) {
var iso8601_re = /^(?:(\\d{4})(?:-(\\d{2})(?:-(\\d{2}))?)?)?(?:[T ](\\d{2}):(\\d{2})(?::(\\d{2})(.\\d+)?)?((?:[+-](\\d{2}):(\\d{2}))|Z)?)?\$/;
var date_bits = iso8601_re.exec(string);
var date_obj = null;
if ( date_bits ) {
date_bits.shift();
date_bits[1] && date_bits[1]--; // normalize month
date_bits[6] && (date_bits[6] *= 1000); // convert mils
date_obj = new Date(date_bits[0]||1970, date_bits[1]||0, date_bits[2]||0, date_bits[3]||0, date_bits[4]||0, date_bits[5]||0, date_bits[6]||0);
if (date_bits[0] < 1000) {
date_obj.setFullYear(date_bits[0]);
}
//timezone handling
var zone_offset = 0; // in minutes
var zone_plus_minus = date_bits[7] && date_bits[7].charAt(0);
// get offset from isostring time to Z time
if ( zone_plus_minus != 'Z' ) {
zone_offset = ((date_bits[8] || 0) * 60) + (Number(date_bits[9]) || 0);
if ( zone_plus_minus != '-' ) {
zone_offset *= -1;
}
}
// convert offset to localtime offset, will include daylight savings
if ( zone_plus_minus ) {
zone_offset -= date_obj.getTimezoneOffset();
}
if ( zone_offset ) {
date_obj.setTime(date_obj.getTime() + zone_offset * 60000);
}
}
// set this object to current localtime representation
try {
this.setTime(date_obj.getTime());
}
catch(e) {
throw new Object({name:"DatePatternFail",message:"jstimer: Date does not have proper format (ISO8601, see readme.txt)."});
}
}
Date.prototype.jstimer_get_moy = function () {
var myMonths=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
return myMonths[this.getMonth()];
}
Date.prototype.jstimer_get_dow = function () {
var myDays=["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"];
return myDays[this.getDay()];
}
JAVASCRIPT_CODE;
return $ouput;
}