/** * Send email an email with attachements * @param $files - array of files to send * ex: array( * "my_image.png" => array( * "path" => "/home/datawrapper/my_image.png", * "format" => "image/png" * ) * ) * */ function dw_send_mail_attachment($to, $from, $subject, $body, $files) { $random_hash = md5(date('r', time())); // $random_hash = md5(date('r', time())); $random_hash = '-----=' . md5(uniqid(mt_rand())); // headers $headers = 'From: ' . $from . "\n"; // $headers .= 'Return-Path: <'.$email_reply.'>'."\n"; $headers .= 'MIME-Version: 1.0' . "\n"; $headers .= 'Content-Type: multipart/mixed; boundary="' . $random_hash . '"'; // message $message = 'This is a multi-part message in MIME format.' . "\n\n"; $message .= '--' . $random_hash . "\n"; $message .= 'Content-Type: text/plain; charset="iso-8859-1"' . "\n"; $message .= 'Content-Transfer-Encoding: 8bit' . "\n\n"; $message .= $body . "\n\n"; // attached files foreach ($files as $fn => $file) { $path = $file["path"]; $format = $file["format"]; $attachment = chunk_split(base64_encode(file_get_contents($path))); $message .= '--' . $random_hash . "\n"; $message .= 'Content-Type: ' . $format . '; name="' . $fn . '"' . "\n"; $message .= 'Content-Transfer-Encoding: base64' . "\n"; $message .= 'Content-Disposition:attachement; filename="' . $fn . '"' . "\n\n"; $message .= $attachment . "\n"; } DatawrapperHooks::execute(DatawrapperHooks::SEND_EMAIL, $to, $subject, $message, $headers); }
public static function getInstance() { if (!isset(self::$instance)) { self::$instance = new DatawrapperHooks(); } return self::$instance; }
public function exportImage($job) { // since this job is run outside of a session we need // to manually set the language to the one of the // user who created the job (otherwise the mail won't // be translated right) global $__l10n; $__l10n->loadMessages($job->getUser()->getLanguage()); $chart = $job->getChart(); $params = $job->getParameter(); $format = $params['format']; $imgFile = ROOT_PATH . 'charts/exports/' . $chart->getId() . '-' . $params['ratio'] . '.' . $format; // execute hook provided by phantomjs plugin // this calls phantomjs with the provided arguments $res = DatawrapperHooks::execute('phantomjs_exec', ROOT_PATH . 'plugins/' . $this->getName() . '/export_chart.js', $chart->getPublicUrl(), $imgFile, $params['ratio']); if (empty($res[0])) { $job->setStatus('done'); // now send email to the user who is waiting for the image! dw_send_mail_attachment($job->getUser()->getEmail(), 'noreply@' . $GLOBALS['dw_config']['domain'], __('The image of your chart is ready', $this->getName()), vksprintf(__('Hello, Here is the requested static image of your chart "%title$s" on %domain$s. All the best, Datawrapper', $this->getName()), array('title' => $chart->getTitle(), 'domain' => $GLOBALS['dw_config']['domain'])), array(basename($imgFile) => array('path' => $imgFile, 'format' => "image/{$format}"))); } else { // error message received, send log email dw_send_error_mail(sprintf('Image export of chart [%s] failed!', $chart->getId()), print_r($job->toArray()) . "\n\nError:\n" . $res[0]); $job->setStatus('failed'); $job->setFailReason($res[0]); } $job->save(); }
public function init() { $plugin = $this; // register plugin controller DatawrapperHooks::register(DatawrapperHooks::GET_ADMIN_PAGES, function () use($plugin) { return array('url' => '/users', 'title' => __('Users', $plugin->getName()), 'controller' => array($plugin, 'users'), 'order' => '2'); }); $this->declareAssets(array('vendor/serious-toolkit/serious-widget.js', 'dw.admin.users.js', 'users.css'), "|/admin/users|"); $user = DatawrapperSession::getUser(); if ($user->isAdmin()) { $this->registerController(function ($app) use($plugin) { $app->get('/admin/users/:user_id', function ($uid) use($app, $plugin) { $theUser = UserQuery::create()->findPk($uid); $page = array('title' => 'Users » ' . $theUser->guessName()); // manually add the admin nav menu vars global $__dw_admin_pages; foreach ($__dw_admin_pages as $adm_pg) { $page['adminmenu'][$adm_pg['url']] = $adm_pg['title']; } add_header_vars($page, 'admin'); $page['the_user'] = $theUser; $page['userPlugins'] = DatawrapperPluginManager::getUserPlugins($theUser->getId(), false); $app->render('plugins/admin-users/admin-user-detail.twig', $page); }); }); } }
public function init() { $plugin = $this; // register plugin controller DatawrapperHooks::register(DatawrapperHooks::GET_ADMIN_PAGES, function () use($plugin) { return array('url' => '/themes', 'title' => __('Themes', $plugin->getName()), 'controller' => array($plugin, 'themesAdmin'), 'order' => '3'); }); }
public function init() { $plugin = $this; foreach ($this->getDemoDatasets() as $key => $dataset) { DatawrapperHooks::register(DatawrapperHooks::GET_DEMO_DATASETS, function () use($dataset) { return $dataset; }); } }
public function init() { $plugin = $this; // register plugin controller DatawrapperHooks::register(DatawrapperHooks::GET_ADMIN_PAGES, function () use($plugin) { return array('url' => '/users', 'title' => __('Users', $plugin->getName()), 'controller' => array($plugin, 'users'), 'order' => '2'); }); $this->declareAssets(array('vendor/serious-toolkit/serious-widget.js', 'dw.admin.users.js', 'users.css'), "|/admin/users|"); }
function header_nav_hook(&$headlinks, $part) { $links = DatawrapperHooks::execute('header_nav_' . $part); if (!empty($links)) { foreach ($links as $link) { $headlinks[] = $link; } } }
function dwInitTwigEnvironment(Twig_Environment $twig) { $twig->setCache(ROOT_PATH . '/tmp/twig'); $twig->enableAutoReload(); $twig->addExtension(new Twig_I18n_Extension()); $twig->addFilter(new Twig_SimpleFilter('purify', function ($dirty) { return dwGetHTMLPurifier()->purify($dirty); })); $twig->addFilter(new Twig_SimpleFilter('json', function ($arr) { $mask = 0; if (!empty($opts)) { if (!empty($opts['pretty'])) { $mask = $mask | JSON_PRETTY_PRINT; } } return json_encode($arr, $mask); })); $twig->addFilter(new Twig_SimpleFilter('css', function ($arr) { $css = ''; foreach ($arr as $prop => $val) { $css .= $prop . ':' . $val . ';'; } return $css; })); $twig->addFunction(new Twig_SimpleFunction('hook', function () { call_user_func_array(array(DatawrapperHooks::getInstance(), 'execute'), func_get_args()); })); $twig->addFunction(new Twig_SimpleFunction('has_hook', function ($hook) { return DatawrapperHooks::getInstance()->hookRegistered($hook); })); $twig->addFunction(new Twig_SimpleFunction('has_plugin', function ($plugin) { return DatawrapperPluginManager::loaded($plugin); })); $twig->addFilter(new Twig_SimpleFilter('lettering', function ($text) { $out = ''; foreach (str_split($text) as $i => $char) { $out .= '<span class="char' . $i . '">' . $char . '</span>'; } return $out; }, array('is_safe' => array('html')))); $loc = DatawrapperSession::getLanguage(); if ($loc == 'en') { $loc = 'en-US'; } \Moment\Moment::setLocale(str_replace('-', '_', $loc)); $twig->addFilter(new Twig_SimpleFilter('reltime', function ($time) { // return $time; return (new \Moment\Moment($time))->fromNow()->getRelative(); })); if (!empty($GLOBALS['dw_config']['debug'])) { $twig->addFilter('var_dump', new Twig_Filter_Function('var_dump')); } return $twig; }
public function init() { $plugin = $this; global $app; DatawrapperHooks::register(DatawrapperHooks::VIS_OPTION_CONTROLS, function ($o, $k) use($app, $plugin) { $env = array('option' => $o, 'key' => $k); $app->render('plugins/' . $plugin->getName() . '/controls.twig', $env); }); DatawrapperHooks::register(DatawrapperHooks::VIS_OPTION_CONTROLS, function ($o, $k) use($app, $plugin) { $env = array('option' => $o, 'key' => $k); $app->render('plugins/' . $plugin->getName() . '/colorselector.twig', $env); }); $this->declareAssets(array('sync-controls.js', 'sync-colorselector.js', 'colorpicker.css'), "|/chart/[^/]+/visualize|"); }
public function init() { $plugin = $this; // register plugin controller DatawrapperHooks::register(DatawrapperHooks::GET_ADMIN_PAGES, function () use($plugin) { // add badges to menu title $title = __('Jobs', $plugin->getName()); $q = JobQuery::create()->filterByStatus('queued')->count(); if ($q > 0) { $title .= ' <span class="badge badge-info">' . $q . '</span>'; } $f = JobQuery::create()->filterByStatus('failed')->count(); if ($f > 0) { $title .= ' <span class="badge badge-important">' . $f . '</span>'; } return array('url' => '/jobs', 'title' => $title, 'controller' => array($plugin, 'jobsAdmin'), 'order' => '10'); }); }
public function init() { // register plugin controller under /gallery/ $this->registerController($this, 'controller'); // show link 'show in gallery' DatawrapperHooks::register(DatawrapperHooks::PUBLISH_AFTER_CHART_ACTIONS, function () { global $app; $app->render('plugins/gallery/show-in-gallery.twig'); }); // show link to gallery in mycharts page DatawrapperHooks::register(DatawrapperHooks::MYCHARTS_AFTER_SIDEBAR, function ($chart, $user) { global $app; $app->render('plugins/gallery/take-a-look.twig'); }); if (!DatawrapperSession::getUser()->isLoggedIn()) { $this->addHeaderNav('mycharts', array('url' => '/gallery/', 'id' => 'gallery', 'title' => __('Gallery'), 'icon' => 'signal')); } }
function dwInitTwigEnvironment(Twig_Environment $twig) { $twig->setCache(ROOT_PATH . '/tmp/twig'); $twig->enableAutoReload(); $twig->addExtension(new Twig_I18n_Extension()); $twig->addFilter(new Twig_SimpleFilter('purify', function ($dirty) { return dwGetHTMLPurifier()->purify($dirty); })); $twig->addFilter(new Twig_SimpleFilter('json', function ($arr) { $mask = 0; if (!empty($opts)) { if (!empty($opts['pretty'])) { $mask = $mask | JSON_PRETTY_PRINT; } } return json_encode($arr, $mask); })); $twig->addFilter(new Twig_SimpleFilter('css', function ($arr) { $css = ''; foreach ($arr as $prop => $val) { $css .= $prop . ':' . $val . ';'; } return $css; })); $twig->addFunction(new Twig_SimpleFunction('hook', function () { call_user_func_array(array(DatawrapperHooks::getInstance(), 'execute'), func_get_args()); })); $twig->addFunction(new Twig_SimpleFunction('has_hook', function ($hook) { return DatawrapperHooks::getInstance()->hookRegistered($hook); })); $twig->addFunction(new Twig_SimpleFunction('has_plugin', function ($plugin) { return DatawrapperPluginManager::loaded($plugin); })); $twig->addFilter(new Twig_SimpleFilter('lettering', function ($text) { $out = ''; foreach (str_split($text) as $i => $char) { $out .= '<span class="char' . $i . '">' . $char . '</span>'; } return $out; }, array('is_safe' => array('html')))); return $twig; }
public function exportStaticPng($job) { $chart = $job->getChart(); $params = $job->getParameter(); $static_path = ROOT_PATH . 'charts/static/' . $chart->getId() . '/'; // execute hook provided by phantomjs plugin // this calls phantomjs with the provided arguments $res = DatawrapperHooks::execute('phantomjs_exec', ROOT_PATH . 'plugins/' . $this->getName() . '/gen_static_fallback.js', 'http://' . $GLOBALS['dw_config']['domain'] . '/chart/' . $chart->getId() . '/', $static_path, $params['width'], $params['height']); if (empty($res[0])) { $job->setStatus('done'); // upload to CDN if possible DatawrapperHooks::execute(DatawrapperHooks::PUBLISH_FILES, array(array($static_path . 'static.html', $chart->getId() . '/static.html', 'text/html'), array($static_path . 'static.png', $chart->getId() . '/static.png', 'image/png'))); } else { // error message received, send log email dw_send_error_mail(sprintf('Generation of static fallback for chart [%s] failed', $chart->getId()), print_r($job->toArray()) . "\n\nError:\n" . $res[0]); $job->setStatus('failed'); $job->setFailReason($res[0]); } $job->save(); }
public function init() { $meta = $this->getMeta(); $datasets = $this->getDemoDataSets(); $demo_hook = DatawrapperHooks::GET_DEMO_DATASETS; if (!empty($meta)) { DatawrapperVisualization::register($this, $meta); } if (!empty($datasets)) { $first_element = reset($datasets); if (is_array($first_element)) { foreach ($datasets as $key => $dataset) { DatawrapperHooks::register($demo_hook, function () use($dataset) { return $dataset; }); } } else { DatawrapperHooks::register($demo_hook, function () use($datasets) { return $datasets; }); } } }
public function isAbleToPublish() { return DatawrapperHooks::hookRegistered(DatawrapperHooks::PUBLISH_FILES); }
if ($plugin) { switch ($action) { case 'enable': $plugin->setEnabled(true); break; case 'disable': $plugin->setEnabled(false); break; case 'publish': $plugin->setIsPrivate(false); break; case 'unpublish': $plugin->setIsPrivate(true); break; } $plugin->save(); ok(); } else { error('plugin-not-found', 'No plugin found with that ID'); } }); })->conditions(array('action' => '(enable|disable|publish|unpublish)')); $pluginApiHooks = DatawrapperHooks::execute(DatawrapperHooks::PROVIDE_API); if (!empty($pluginApiHooks)) { foreach ($pluginApiHooks as $hook) { if (!isset($hook['method'])) { $hook['method'] = 'GET'; } $app->map('/plugin/' . $hook['url'], $hook['action'])->via($hook['method']); } }
} if ($currUser->isAdmin() && !empty($data->role)) { // Only sysadmin can set a sysadmin role if ($data->role == "sysadmin") { if (!$currUser->isSysAdmin()) { error(403, 'Permission denied'); return; } } $user->SetRole($data->role); } $user->setLanguage(DatawrapperSession::getLanguage()); $user->setActivateToken(hash_hmac('sha256', $data->email . '/' . time(), DW_TOKEN_SALT)); $user->save(); $result = $user->toArray(); DatawrapperHooks::execute(DatawrapperHooks::USER_SIGNUP, $user); // send an email $name = $data->email; $domain = $GLOBALS['dw_config']['domain']; $protocol = !empty($_SERVER['HTTPS']) ? "https" : "http"; if ($invitation) { // send account invitation link $invitationLink = $protocol . '://' . $domain . '/account/invite/' . $user->getActivateToken(); include ROOT_PATH . 'lib/templates/invitation-email.php'; dw_send_support_email($data->email, sprintf(__('You have been invited to Datawrapper on %s'), $domain), $invitation_mail, array('name' => $user->guessName(), 'invitation_link' => $invitationLink)); } else { // send account activation link $activationLink = $protocol . '://' . $domain . '/account/activate/' . $user->getActivateToken(); include ROOT_PATH . 'lib/templates/activation-email.php'; dw_send_support_email($data->email, __('Datawrapper: Please activate your email address'), $activation_mail, array('name' => $user->guessName(), 'activation_link' => $activationLink)); // we don't need to annoy the user with a login form now,
public function init() { DatawrapperHooks::register(DatawrapperHooks::AFTER_CHART_BODY, array($this, 'getTrackingCode')); DatawrapperHooks::register(DatawrapperHooks::AFTER_CORE_BODY, array($this, 'getTrackingCode')); }
<?php /* * UPLOAD STEP */ $app->get('/chart/:id/upload', function ($id) use($app) { disable_cache($app); check_chart_writable($id, function ($user, $chart) use($app) { $datasets = DatawrapperHooks::execute(DatawrapperHooks::GET_DEMO_DATASETS); $groups = array(); foreach ($datasets as $ds) { if (!isset($groups[$ds['type']])) { $groups[$ds['type']] = array('type' => $ds['type'], 'datasets' => array()); } $groups[$ds['type']]['datasets'][] = $ds; } $page = array('title' => $chart->getID() . ' :: ' . __('Upload Data'), 'chartData' => $chart->loadData(), 'chart' => $chart, 'datasets' => $groups); add_header_vars($page, 'chart'); add_editor_nav($page, 1); $res = $app->response(); $res['Cache-Control'] = 'max-age=0'; $app->render('chart/upload.twig', $page); }); });
<?php require_once ROOT_PATH . 'lib/utils/themes.php'; require_once ROOT_PATH . 'vendor/jsmin/jsmin.php'; /* * PUBLISH STEP - shows progress of publishing action and thumbnail generation * forwards to /chart/:id/finish */ $app->get('/chart/:id/publish', function ($id) use($app) { disable_cache($app); check_chart_writable($id, function ($user, $chart) use($app) { $cfg = $GLOBALS['dw_config']; $page = array('title' => $chart->getID() . ' :: ' . __('Publish'), 'chartData' => $chart->loadData(), 'chart' => $chart, 'visualizations' => DatawrapperVisualization::all(), 'vis' => DatawrapperVisualization::get($chart->getType()), 'chartUrl' => $chart->getPublicUrl(), 'chartUrlLocal' => '/chart/' . $chart->getID() . '/preview', 'themes' => DatawrapperTheme::all(), 'exportStaticImage' => !empty($cfg['phantomjs']), 'chartActions' => DatawrapperHooks::execute(DatawrapperHooks::GET_CHART_ACTIONS, $chart), 'estExportTime' => ceil(JobQuery::create()->estimatedTime('export_image') / 60)); add_header_vars($page, 'chart', 'chart-editor/publish.css'); add_editor_nav($page, 4); if ($user->isAbleToPublish() && ($chart->getLastEditStep() == 3 || $app->request()->get('republish') == 1)) { // actual publish process $chart->publish(); $page['chartUrl'] = $chart->getPublicUrl(); // generate thumbnails $page['publish'] = true; $page['republish'] = $app->request()->get('republish') == 1; } $app->render('chart/publish.twig', $page); }); });
} else { return error('unknown-organization', 'Organization not found'); } }); }); /* * remove user from organization */ $app->delete('/organizations/:id/users/:uid', function ($org_id, $user_id) use($app) { if_is_admin(function () use($app, $org_id, $user_id) { $org = OrganizationQuery::create()->findPk($org_id); $user = UserQuery::create()->findPk($user_id); if ($org && $user) { $org->removeUser($user); $org->save(); DatawrapperHooks::execute(DatawrapperHooks::USER_ORGANIZATION_REMOVE, $org, $user); ok(); } else { return error('unknown-organization-or-user', 'Organization or user not found'); } }); }); /* * toggle plugin permissions of organization */ $app->put('/organizations/:id/plugins/:op/:plugin_id', function ($org_id, $op, $plugin_id) use($app) { if_is_admin(function () use($app, $org_id, $op, $plugin_id) { $org = OrganizationQuery::create()->findPk($org_id); $plugin = PluginQuery::create()->findPk($plugin_id); if (!$org) { return error('unknown-organization', 'Organization not found');
$user->setActivateToken(hash_hmac('sha256', $data->email . '/' . time(), DW_TOKEN_SALT)); $user->save(); $result = $user->toArray(); // send an email $name = $data->email; $domain = $GLOBALS['dw_config']['domain']; if ($invitation) { $invitationLink = 'http://' . $domain . '/account/invite/' . $user->getActivateToken(); $from = $GLOBALS['dw_config']['email']['invite']; include ROOT_PATH . 'lib/templates/invitation-email.php'; DatawrapperHooks::execute(DatawrapperHooks::SEND_EMAIL, $data->email, sprintf(__('You have been invited to %s'), $domain), $invitation_mail, 'From: ' . $from); } else { $activationLink = 'http://' . $domain . '/account/activate/' . $user->getActivateToken(); $from = $GLOBALS['dw_config']['email']['activate']; include ROOT_PATH . 'lib/templates/activation-email.php'; DatawrapperHooks::execute(DatawrapperHooks::SEND_EMAIL, $data->email, __('Datawrapper Email Activation'), $activation_mail, 'From: ' . $from); // we don't need to annoy the user with a login form now, // so just log in.. DatawrapperSession::login($user); } ok($result); }); /* * update user profile * @needs admin or existing user */ $app->put('/users/:id', function ($user_id) use($app) { $payload = json_decode($app->request()->getBody()); $curUser = DatawrapperSession::getUser(); if ($curUser->isLoggedIn()) { if ($user_id == 'current' || $curUser->getId() === $user_id) {
<?php require_once ROOT_PATH . 'controller/account/activate.php'; require_once ROOT_PATH . 'controller/account/set-password.php'; require_once ROOT_PATH . 'controller/account/reset-password.php'; require_once ROOT_PATH . 'controller/account/profile.php'; require_once ROOT_PATH . 'controller/account/delete.php'; require_once ROOT_PATH . 'controller/account/password.php'; require_once ROOT_PATH . 'controller/account/mycharts.php'; call_user_func(function () { global $app; $user = DatawrapperSession::getUser(); $pages = DatawrapperHooks::execute(DatawrapperHooks::GET_ACCOUNT_PAGES, $user); foreach ($pages as $page) { if (!isset($page['order'])) { $page['order'] = 999; } } usort($pages, function ($a, $b) { return $a['order'] - $b['order']; }); $app->get('/account/?', function () use($app, $pages) { $app->redirect('/account/' . $pages[0]['url'] . '/'); }); // redirect to settings $app->get('/settings/?', function () use($app) { $app->redirect('/account'); }); $user = DatawrapperSession::getUser(); foreach ($pages as $page) { $context = array('title' => $page['title'], 'gravatar' => md5(strtolower(trim($user->getEmail()))), 'pages' => $pages, 'active' => $page['url'], 'user' => $user);
function get_chart_content($chart, $user, $published = false, $debug = false) { $theme_css = array(); $theme_js = array(); $next_theme_id = $chart->getTheme(); $locale = DatawrapperSession::getLanguage(); while (!empty($next_theme_id)) { $theme = DatawrapperTheme::get($next_theme_id); $theme_js[] = $theme['__static_path'] . $next_theme_id . '.js'; if ($theme['hasStyles']) { $theme_css[] = $theme['__static_path'] . $next_theme_id . '.css'; } $next_theme_id = $theme['extends']; } $abs = 'http://' . $GLOBALS['dw_config']['domain']; $debug = $GLOBALS['dw_config']['debug'] == true || $debug; if ($published && !$debug) { $base_js = array('//assets-datawrapper.s3.amazonaws.com/globalize.min.js', '//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js', '//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js'); if (substr($locale, 0, 2) != 'en') { $base_js[] = '//assets-datawrapper.s3.amazonaws.com/cultures/globalize.culture.' . str_replace('_', '-', $locale) . '.js'; } } else { // use local assets $base_js = array($abs . '/static/vendor/globalize/globalize.min.js', $abs . '/static/vendor/underscore/underscore-min.js', $abs . '/static/vendor/jquery/jquery-1.9.1' . ($debug ? '' : '.min') . '.js'); if (substr($locale, 0, 2) != 'en') { $base_js[] = $abs . '/static/vendor/globalize/cultures/globalize.culture.' . str_replace('_', '-', $locale) . '.js'; } } $vis_js = array(); $vis_css = array(); $next_vis_id = $chart->getType(); $vis_libs = array(); $vis_locale = array(); // visualizations may define localized strings, e.g. "other" while (!empty($next_vis_id)) { $vis = DatawrapperVisualization::get($next_vis_id); $vjs = array(); if (!empty($vis['libraries'])) { foreach ($vis['libraries'] as $url) { // at first we check if the library lives in ./lib of the vis module if (file_exists(ROOT_PATH . 'www/' . $vis['__static_path'] . $url)) { $vis_libs[] = $vis['__static_path'] . $url; } else { if (file_exists(ROOT_PATH . 'www/static/vendor/' . $url)) { $vis_libs[] = '/static/vendor/' . $url; } } } } if (!empty($vis['locale']) && is_array($vis['locale'])) { foreach ($vis['locale'] as $term => $translations) { if (!isset($vis_locale[$term])) { $vis_locale[$term] = $translations; } } } $vjs[] = $vis['__static_path'] . $vis['id'] . '.js'; $vis_js = array_merge($vis_js, array_reverse($vjs)); if ($vis['hasCSS']) { $vis_css[] = $vis['__static_path'] . $vis['id'] . '.css'; } $next_vis_id = !empty($vis['extends']) ? $vis['extends'] : null; } $styles = array_merge($vis_css, array_reverse($theme_css)); $the_vis = DatawrapperVisualization::get($chart->getType()); $the_vis['locale'] = $vis_locale; $the_theme = DatawrapperTheme::get($chart->getTheme()); if ($published) { $scripts = array_merge($base_js, array('/lib/vis/' . $the_vis['id'] . '-' . $the_vis['version'] . '.min.js', '/lib/theme/' . $the_theme['id'] . '-' . $the_theme['version'] . '.min.js')); $styles = array($chart->getID() . '.min.css'); $the_vis['__static_path'] = ''; $the_theme['__static_path'] = ''; } else { $scripts = array_unique(array_merge($base_js, array('/static/js/datawrapper' . ($debug ? '' : '.min') . '.js'), array_reverse($theme_js), array_reverse($vis_js), $vis_libs)); } $cfg = $GLOBALS['dw_config']; $published_urls = DatawrapperHooks::execute(DatawrapperHooks::GET_PUBLISHED_URL, $chart); if (empty($published_urls)) { $chart_url = 'http://' . $cfg['chart_domain'] . '/' . $chart->getID() . '/'; } else { $chart_url = $published_urls[0]; // ignore urls except from the first one } $page = array('chartData' => $chart->loadData(), 'chart' => $chart, 'chartLocale' => str_replace('_', '-', $locale), 'lang' => strtolower(substr($locale, 0, 2)), 'metricPrefix' => get_metric_prefix($locale), 'theme' => $the_theme, 'l10n__domain' => $the_theme['__static_path'], 'visualization' => $the_vis, 'stylesheets' => $styles, 'scripts' => $scripts, 'themeJS' => array_reverse($theme_js), 'visJS' => array_merge(array_reverse($vis_js), $vis_libs), 'origin' => !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '', 'DW_DOMAIN' => 'http://' . $cfg['domain'] . '/', 'DW_CHART_DATA' => 'http://' . $cfg['domain'] . '/chart/' . $chart->getID() . '/data', 'ASSET_PATH' => $published ? '' : $the_theme['__static_path'], 'trackingCode' => !empty($analyticsMod) ? $analyticsMod->getTrackingCode($chart) : '', 'chartUrl' => $chart_url, 'embedCode' => '<iframe src="' . $chart_url . '" frameborder="0" allowtransparency="true" allowfullscreen webkitallowfullscreen mozallowfullscreen oallowfullscreen msallowfullscreen width="' . $chart->getMetadata('publish.embed-width') . '" height="' . $chart->getMetadata('publish.embed-height') . '"></iframe>', 'chartUrlFs' => strpos($chart_url, '.html') > 0 ? str_replace('index.html', 'fs.html', $chart_url) : $chart_url . '?fs=1'); return $page; }
public function init() { DatawrapperHooks::register(DatawrapperHooks::PUBLISH_FILES, array($this, 'publish')); DatawrapperHooks::register(DatawrapperHooks::UNPUBLISH_FILES, array($this, 'unpublish')); DatawrapperHooks::register(DatawrapperHooks::GET_PUBLISHED_URL, array($this, 'getUrl')); }
function get_theme_js($theme, $themeJS) { $all = ''; $org = DatawrapperSession::getUser()->getCurrentOrganization(); if (!empty($org)) { $org = '/' . $org->getID(); } else { $org = ''; } $keys = DatawrapperHooks::execute(DatawrapperHooks::GET_PUBLISH_STORAGE_KEY); if (is_array($keys)) { $org .= '/' . join($keys, '/'); } foreach ($themeJS as $js) { if (substr($js, 0, 7) != "http://" && substr($js, 0, 8) != "https://" && substr($js, 0, 2) != '//') { $all .= "\n\n\n" . file_get_contents(ROOT_PATH . 'www' . $js); } } $all = jsminify($all); $theme_js_md5 = md5($all . $org); $theme_path = 'theme/' . $theme['id'] . '-' . $theme_js_md5 . '.min.js'; return array($theme_path, $all); }
function publish_push_to_cdn($cdn_files, $chart) { DatawrapperHooks::execute(DatawrapperHooks::PUBLISH_FILES, $cdn_files); }
function add_header_vars(&$page, $active = null) { // define the header links global $app; $config = $GLOBALS['dw_config']; if (!isset($active)) { $active = explode('/', $app->request()->getResourceUri()); $active = $active[1]; } $user = DatawrapperSession::getUser(); $headlinks = array(); if ($user->isLoggedIn() || empty($config['prevent_guest_charts'])) { $headlinks[] = array('url' => '/chart/create', 'id' => 'chart', 'title' => __('Create Chart'), 'icon' => 'pencil'); } if ($user->isLoggedIn() && $user->hasCharts()) { $headlinks[] = array('url' => '/mycharts/', 'id' => 'mycharts', 'title' => __('My Charts'), 'icon' => 'signal'); } else { $headlinks[] = array('url' => '/gallery/', 'id' => 'gallery', 'title' => __('Gallery'), 'icon' => 'signal'); } if (isset($config['navigation'])) { foreach ($config['navigation'] as $item) { $link = array('url' => str_replace('%lang%', substr(DatawrapperSession::getLanguage(), 0, 2), $item['url']), 'id' => $item['id'], 'title' => __($item['title'])); if (!empty($item['icon'])) { $link['icon'] = $item['icon']; } $headlinks[] = $link; } } // language dropdown if (!empty($config['languages'])) { $langDropdown = array('url' => '', 'id' => 'lang', 'dropdown' => array(), 'title' => __('Language'), 'icon' => 'font'); foreach ($config['languages'] as $lang) { $langDropdown['dropdown'][] = array('url' => '#lang-' . $lang['id'], 'title' => $lang['title']); } if (count($langDropdown['dropdown']) > 1) { $headlinks[] = $langDropdown; } } if ($user->isLoggedIn()) { $shortenedMail = $user->getEmail(); $shortenedMail = strlen($shortenedMail) > 18 ? substr($shortenedMail, 0, 9) . '...' . substr($shortenedMail, strlen($shortenedMail) - 9) : $shortenedMail; $headlinks[] = array('url' => '#user', 'id' => 'user', 'title' => $shortenedMail, 'icon' => 'user', 'dropdown' => array(array('url' => '/account/settings', 'icon' => 'wrench', 'title' => __('Settings')), array('url' => '#logout', 'icon' => 'off', 'title' => __('Logout')))); if ($user->isAdmin()) { $headlinks[] = array('url' => '/admin', 'id' => 'admin', 'icon' => 'fire', 'title' => __('Admin')); } } else { $headlinks[] = array('url' => '#login', 'id' => 'login', 'title' => __('Login / Sign Up'), 'icon' => 'user'); } foreach ($headlinks as $i => $link) { $headlinks[$i]['active'] = $headlinks[$i]['id'] == $active; } $page['headlinks'] = $headlinks; $page['user'] = DatawrapperSession::getUser(); $page['language'] = substr(DatawrapperSession::getLanguage(), 0, 2); $page['locale'] = DatawrapperSession::getLanguage(); $page['DW_DOMAIN'] = $config['domain']; $page['DW_VERSION'] = DATAWRAPPER_VERSION; $page['DW_CHART_CACHE_DOMAIN'] = $config['chart_domain']; $page['ADMIN_EMAIL'] = $config['email']['admin']; $page['config'] = $config; $page['invert_navbar'] = substr($config['domain'], -4) == '.pro'; $uri = $app->request()->getResourceUri(); $plugin_assets = DatawrapperHooks::execute(DatawrapperHooks::GET_PLUGIN_ASSETS, $uri); if (!empty($plugin_assets)) { $plugin_js_files = array(); $plugin_css_files = array(); foreach ($plugin_assets as $files) { if (!is_array($files)) { $files = array($files); } foreach ($files as $file) { if (substr($file, -3) == '.js') { $plugin_js_files[] = $file; } if (substr($file, -4) == '.css') { $plugin_css_files[] = $file; } } } $page['plugin_js'] = $plugin_js_files; $page['plugin_css'] = $plugin_css_files; } if (isset($config['piwik'])) { $page['PIWIK_URL'] = $config['piwik']['url']; $page['PIWIK_IDSITE'] = $config['piwik']['idSite']; if (isset($config['piwik']['idSiteNoCharts'])) { $page['PIWIK_IDSITE_NO_CHARTS'] = $config['piwik']['idSiteNoCharts']; } } if ($config['debug']) { if (file_exists('../.git')) { // parse git branch $head = file_get_contents('../.git/HEAD'); $parts = explode("/", $head); $page['BRANCH'] = ' (' . trim($parts[count($parts) - 1]) . ')'; } } }
$page = array('email' => $user->getEmail(), 'auth_salt' => DW_AUTH_SALT); add_header_vars($page, 'about', 'account/invite.css'); $app->render('account/invite.twig', $page); }); }); /* * store new password, clear invitation token and login */ $app->post('/account/invite/:token', function ($token) use($app) { _checkInviteTokenAndExec($token, function ($user) use($app) { $data = json_decode($app->request()->getBody()); $user->setPwd($data->pwd); $user->setActivateToken(''); $user->save(); // notify plugins about the newly activated user DatawrapperHooks::execute(DatawrapperHooks::USER_ACTIVATED, $user); DatawrapperSession::login($user); print json_encode(array('result' => 'ok')); }); }); function _checkInviteTokenAndExec($token, $func) { if (!empty($token)) { $user = UserQuery::create()->findOneByActivateToken($token); if ($user && $user->getRole() != 'pending') { $func($user); } else { // this is not a valid token! $page['alert'] = array('type' => 'error', 'message' => __('The invitation token is invalid.')); global $app; $app->redirect('/');