コード例 #1
1
ファイル: mail.php プロジェクト: elaOnMars/datawrapper
/**
 * 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);
}
コード例 #2
0
ファイル: plugin.php プロジェクト: elaOnMars/datawrapper
    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();
    }
コード例 #3
0
 function header_nav_hook(&$headlinks, $part)
 {
     $links = DatawrapperHooks::execute('header_nav_' . $part);
     if (!empty($links)) {
         foreach ($links as $link) {
             $headlinks[] = $link;
         }
     }
 }
コード例 #4
0
ファイル: plugin.php プロジェクト: shelsonjava/datawrapper
 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();
 }
コード例 #5
0
ファイル: upload.php プロジェクト: Halfnhav4/datawrapper
<?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);
    });
});
コード例 #6
0
ファイル: hook.php プロジェクト: Halfnhav4/datawrapper
<?php

/*
 * Generic hook script
 */
define('ROOT_PATH', dirname(dirname(__FILE__)) . '/');
define('NO_SLIM', 1);
define('NO_SESSION', 1);
define('DATAWRAPPER_VERSION', json_decode(file_get_contents(ROOT_PATH . 'package.json'), true)['version']);
require_once ROOT_PATH . 'lib/bootstrap.php';
date_default_timezone_set('Europe/Berlin');
$hook = $argv[1];
if (!empty($hook)) {
    if (DatawrapperHooks::hookRegistered($hook)) {
        DatawrapperHooks::execute($hook, isset($argv[2]) ? $argv[2] : null, isset($argv[3]) ? $argv[3] : null, isset($argv[4]) ? $argv[4] : null);
    } else {
        print "no callback registered under the name " . $hook . "\n";
    }
}
コード例 #7
0
ファイル: publish.php プロジェクト: elaOnMars/datawrapper
<?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);
    });
});
コード例 #8
0
ファイル: Chart.php プロジェクト: Halfnhav4/datawrapper
 public function redirectPreviousVersions()
 {
     $current_target = $this->getCDNPath();
     $redirect_html = '<html><head><meta http-equiv="REFRESH" content="0; url=/' . $current_target . '"></head></html>';
     $redirect_file = chart_publish_directory() . 'static/' . $this->getID() . '/redirect.html';
     file_put_contents($redirect_file, $redirect_html);
     $files = array();
     for ($v = 0; $v < $this->getPublicVersion(); $v++) {
         $files[] = array($redirect_file, $this->getCDNPath($v) . 'index.html', 'text/html');
     }
     DatawrapperHooks::execute(DatawrapperHooks::PUBLISH_FILES, $files);
 }
コード例 #9
0
ファイル: users.php プロジェクト: elaOnMars/datawrapper
 }
 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,
コード例 #10
0
        } 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');
コード例 #11
0
ファイル: index.php プロジェクト: shelsonjava/datawrapper
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]) . ')';
        }
    }
}
コード例 #12
0
ファイル: upload.php プロジェクト: elaOnMars/datawrapper
<?php

/*
 * UPLOAD STEP
 */
$app->get('/chart/:id/upload', function ($id) use($app) {
    disable_cache($app);
    check_chart_writable($id, function ($user, $chart) use($app) {
        $page = array('title' => $chart->getID() . ' :: ' . __('Upload Data'), 'chartData' => $chart->loadData(), 'chart' => $chart, 'datasets' => DatawrapperHooks::execute(DatawrapperHooks::GET_DEMO_DATASETS));
        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);
    });
});
コード例 #13
0
ファイル: users.php プロジェクト: rwardhan/datawrapper-1
    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,
        // so just log in..
        DatawrapperSession::login($user);
    }
    $welcome_msg = __("Hello %name%,\n\nWelcome to your new Datawrapper account.\n\nCheers,\nDatawrapper");
    DatawrapperHooks::execute(DatawrapperHooks::NOTIFY_USER, $user, __('Welcome to Datawrapper!'), str_replace('%name%', $user->guessName(), $welcome_msg));
    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() === intval($user_id)) {
            $user = $curUser;
        } else {
            if ($curUser->isAdmin()) {
                $user = UserQuery::create()->findPK($user_id);
コード例 #14
0
ファイル: admin.php プロジェクト: elaOnMars/datawrapper
<?php

if (DatawrapperHooks::hookRegistered(DatawrapperHooks::GET_ADMIN_PAGES)) {
    // pull admin pages from plugins
    $__dw_admin_pages = DatawrapperHooks::execute(DatawrapperHooks::GET_ADMIN_PAGES);
    // order admin pages by index "order"
    usort($__dw_admin_pages, function ($a, $b) {
        return (isset($a['order']) ? $a['order'] : 9999) - (isset($b['order']) ? $b['order'] : 9999);
    });
    foreach ($__dw_admin_pages as $admin_page) {
        $app->map('/admin' . $admin_page['url'], function () use($app, $admin_page, $__dw_admin_pages) {
            disable_cache($app);
            $user = DatawrapperSession::getUser();
            if ($user->isAdmin()) {
                $page_vars = array('title' => $admin_page['title'], 'adminmenu' => array(), 'adminactive' => $admin_page['url']);
                // add admin pages to menu
                foreach ($__dw_admin_pages as $adm_pg) {
                    $page_vars['adminmenu'][$adm_pg['url']] = $adm_pg['title'];
                }
                add_header_vars($page_vars, 'admin');
                call_user_func_array($admin_page['controller'], array($app, $page_vars));
            } else {
                $app->notFound();
            }
        })->via('GET', 'POST');
    }
}
コード例 #15
0
ファイル: auth.php プロジェクト: shelsonjava/datawrapper
        // we don't want to send it too often in order to prevent
        // mail spam coming from our server
        $r = ActionQuery::create()->filterByUser($user)->filterByKey('resend-activation')->find();
        if (count($r) > 2) {
            error('avoid-spam', str_replace('%ADMINEMAIL%', $GLOBALS['dw_config']['email']['admin'], __('You already resent the activation mail three times, now. Please <a href="mailto:%ADMINEMAIL%">contact an administrator</a> to proceed with your account activation.')));
            return false;
        }
        // remember that we send the email
        Action::logAction($user, 'resend-activation', $token);
        // send email with activation key
        $name = $user->getEmail();
        $domain = $GLOBALS['dw_config']['domain'];
        $activationLink = 'http://' . $domain . '/account/activate/' . $token;
        $from = 'activate@' . $domain;
        include '../../lib/templates/activation-email.php';
        DatawrapperHooks::execute(DatawrapperHooks::SEND_EMAIL, $user->getEmail(), 'Datawrapper Email Activation', $activation_mail, 'From: ' . $from);
        ok(__('The activation email has been send to your email address, again.'));
    } else {
        error('token-empty', __('You\'re account is probably already activated.'));
    }
});
/*
 * endpoint for validating an invitation. The user sends his new password
 */
$app->post('/account/invitation/:token', function ($token) use($app) {
    $data = json_decode($app->request()->getBody());
    if (!empty($token)) {
        $users = UserQuery::create()->filterByActivateToken($token)->find();
        if (count($users) != 1) {
            error("token-invalid", _("This activation token is invalid. Your email address is probably already activated."));
        } elseif (empty($data->pwd1)) {
コード例 #16
0
<?php

/*
 * UPLOAD STEP
 */
$app->get('/chart/:id/upload', function ($id) use($app) {
    disable_cache($app);
    check_chart_writable($id, function ($user, $chart) use($app) {
        $page = array('chartData' => $chart->loadData(), 'chart' => $chart, 'datasets' => DatawrapperHooks::execute(DatawrapperHooks::GET_DEMO_DATASETS));
        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);
    });
});
コード例 #17
0
ファイル: users.php プロジェクト: Halfnhav4/datawrapper
         Action::logAction($curUser, 'change-password', array('user' => $user->getId()));
     } else {
         Action::logAction($curUser, 'change-password-failed', array('user' => $user->getId(), 'reason' => 'old password is wrong'));
         $errors[] = __('The password could not be changed because your old password was not entered correctly.');
     }
 }
 if (!empty($payload->email) && $payload->email != $user->getEmail()) {
     if (check_email($payload->email) || $curUser->isAdmin()) {
         if (!email_exists($payload->email)) {
             if ($curUser->isAdmin()) {
                 $user->setEmail($payload->email);
             } else {
                 // non-admins need to confirm new emails addresses
                 $token = hash_hmac('sha256', $user->getEmail() . '/' . $payload->email . '/' . time(), DW_TOKEN_SALT);
                 $token_link = get_current_protocol() . '://' . $GLOBALS['dw_config']['domain'] . '/account/profile?token=' . $token;
                 DatawrapperHooks::execute(DatawrapperHooks::SEND_CHANGE_EMAIL_EMAIL, $payload->email, $user->guessName(), $user->getEmail(), $token_link);
                 // log action for later confirmation
                 Action::logAction($curUser, 'email-change-request', array('old-email' => $user->getEmail(), 'new-email' => $payload->email, 'token' => $token));
                 $messages[] = __('To complete the change of your email address, you need to confirm that you have access to it. Therefor we sent an email with the confirmation link to your new address. Your new email will be set right after you clicked that link.');
             }
         } else {
             $errors[] = sprintf(__('The email address <b>%s</b> already exists.'), $payload->email);
         }
     } else {
         $errors[] = sprintf(__('The email address <b>%s</b> is invalid.'), $payload->email);
     }
 }
 if (!empty($payload->name)) {
     $user->setName($payload->name);
 }
 if ($curUser->isAdmin() && !empty($payload->role)) {
コード例 #18
0
ファイル: activate.php プロジェクト: Halfnhav4/datawrapper
        $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('/');
コード例 #19
0
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;
}
コード例 #20
0
ファイル: publish.php プロジェクト: Halfnhav4/datawrapper
<?php

/*
 * PUBLISH STEP - shows progress of publishing action and thumbnail generation
 */
$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'];
        $chartActions = DatawrapperHooks::execute(DatawrapperHooks::GET_CHART_ACTIONS, $chart);
        // add duplicate action
        $chartActions[] = array('id' => 'duplicate', 'icon' => 'code-fork', 'title' => __('Duplicate this chart'), 'order' => 500);
        // sort actions
        usort($chartActions, function ($a, $b) {
            return (isset($a['order']) ? $a['order'] : 999) - (isset($b['order']) ? $b['order'] : 999);
        });
        $chartW = $chart->getMetadata('publish.embed-width');
        $chartH = $chart->getMetadata('publish.embed-height');
        if (substr($chartW, -1) != '%') {
            $chartW .= 'px';
        }
        if (substr($chartH, -1) != '%') {
            $chartH .= 'px';
        }
        $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', 'embedWidth' => $chartW, 'embedHeight' => $chartH, 'themes' => DatawrapperTheme::all(), 'exportStaticImage' => !empty($cfg['phantomjs']), 'chartActions' => $chartActions, 'estExportTime' => ceil(JobQuery::create()->estimatedTime('export') / 60));
        add_header_vars($page, 'chart', 'chart-editor/publish.css');
        add_editor_nav($page, 4);
        $app->render('chart/publish.twig', $page);
    });
});
コード例 #21
0
ファイル: users.php プロジェクト: shelsonjava/datawrapper
    $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) {
コード例 #22
0
ファイル: charts.php プロジェクト: shelsonjava/datawrapper
    if_chart_is_writable($chart_id, function ($user, $chart) use($app) {
        echo _getPublishStatus($chart);
    });
});
/*
 * stores client-side generated chart thumbnail
 */
$app->put('/charts/:id/thumbnail/:thumb', function ($chart_id, $thumb) use($app) {
    disable_cache($app);
    if_chart_is_writable($chart_id, function ($user, $chart) use($app, $thumb) {
        try {
            $imgurl = $app->request()->getBody();
            $imgdata = base64_decode(substr($imgurl, strpos($imgurl, ",") + 1));
            $static_path = get_static_path($chart);
            file_put_contents($static_path . "/" . $thumb . '.png', $imgdata);
            DatawrapperHooks::execute(DatawrapperHooks::PUBLISH_FILES, array(array($static_path . "/" . $thumb . '.png', $chart->getID() . '/' . $thumb . '.png', 'image/png')));
            ok();
        } catch (Exception $e) {
            error('io-error', $e->getMessage());
        }
    });
});
/*
 * stores static snapshot of a chart (data, configuration, etc) as JSON
 * to /test/test-charts. This aims to simplify the generation of test
 * cases using the Datawrapper editor. Only for debugging.
 */
$app->post('/charts/:id/store_snapshot', function ($chart_id) use($app) {
    if (!empty($GLOBALS['dw_config']['debug_export_test_cases'])) {
        if_chart_exists($chart_id, function ($chart) use($app) {
            $json = $chart->serialize();
コード例 #23
0
function publish_push_to_cdn($cdn_files, $chart)
{
    DatawrapperHooks::execute(DatawrapperHooks::PUBLISH_FILES, $cdn_files);
}
コード例 #24
0
ファイル: auth.php プロジェクト: Halfnhav4/datawrapper
 * expects payload { "email": "*****@*****.**" }
 */
$app->post('/account/resend-invitation', function () use($app) {
    $payload = json_decode($app->request()->getBody());
    $user = UserQuery::create()->findOneByEmail($payload->email);
    $token = $user->getActivateToken();
    if (!empty($user)) {
        if (empty($token)) {
            return error("token-invalid", __("This activation token is invalid. Your email address is probably already activated."));
        }
        // variables for `templates/invitation-email.php`
        $domain = $GLOBALS['dw_config']['domain'];
        $protocol = get_current_protocol();
        $invitationLink = $protocol . '://' . $domain . '/account/invite/' . $token;
        $name = $user->getEmail();
        DatawrapperHooks::execute(DatawrapperHooks::SEND_INVITE_EMAIL_TO_NEW_USER, $user->getEmail(), $user->guessName(), $invitationLink);
        ok(__('You should soon receive an email with further instructions.'));
    } else {
        error('login-email-unknown', __('The email is not registered yet.'));
    }
});
/*
 * endpoint for validating an invitation. The user sends his new password
 */
$app->post('/account/invitation/:token', function ($token) use($app) {
    $data = json_decode($app->request()->getBody());
    if (!empty($token)) {
        $users = UserQuery::create()->filterByActivateToken($token)->find();
        if (count($users) != 1) {
            error("token-invalid", __("This activation token is invalid. Your email address is probably already activated."));
        } elseif (empty($data->pwd1)) {
コード例 #25
0
ファイル: plugins.php プロジェクト: elaOnMars/datawrapper
        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']);
    }
}
コード例 #26
0
ファイル: bootstrap.php プロジェクト: Halfnhav4/datawrapper
    fclose($h);
}
// init l10n
$locale = str_replace('-', '_', DatawrapperSession::getLanguage());
$domain = 'messages';
putenv('LANGUAGE=' . $locale);
setlocale(LC_ALL, $locale);
setlocale(LC_TIME, $locale . '.utf8');
$__l10n = new Datawrapper_L10N();
$__l10n->loadMessages($locale);
parse_config();
if (!defined('NO_SLIM')) {
    // Initialize Slim app..
    if (ROOT_PATH == '../') {
        // ..either with TwigView for Datawrapper UI,...
        TwigView::$twigDirectory = ROOT_PATH . 'vendor/Twig';
        $app = new Slim(array('view' => new TwigView(), 'templates.path' => '../templates', 'session.handler' => null));
    } else {
        // ..or with JSONView for API.
        $app = new Slim(array('view' => 'JSONView'));
    }
}
if (isset($dw_config['memcache'])) {
    $memcfg = $dw_config['memcache'];
    $memcache = new Memcache();
    $memcache->connect($memcfg['host'], $memcfg['port']) or die("Could not connect");
}
DatawrapperPluginManager::load();
// notify the core that all plugins are loaded
DatawrapperHooks::execute(DatawrapperHooks::ALL_PLUGINS_LOADED);
コード例 #27
0
ファイル: chart_content.php プロジェクト: ac1714/datawrapper
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);
}
コード例 #28
0
ファイル: account.php プロジェクト: Halfnhav4/datawrapper
<?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);
コード例 #29
0
ファイル: plugin.php プロジェクト: ac1714/datawrapper
function update($pattern)
{
    _apply($pattern, function ($id) {
        $plugin = new Plugin();
        $plugin->setId($id);
        $repo = $plugin->getRepository();
        if ($repo) {
            if ($repo['type'] == 'git') {
                if (file_exists($plugin->getPath() . '.git/config')) {
                    $ret = array();
                    exec('cd ' . $plugin->getPath() . '; git pull origin master 2>&1', $ret, $err);
                    if ($ret[count($ret) - 1] == 'Already up-to-date.') {
                        print "Plugin {$id} is up-to-date.\n";
                    } else {
                        DatawrapperHooks::execute(DatawrapperHooks::PLUGIN_UPDATED, $id);
                        print "Updated plugin {$id}.\n";
                        install($id);
                    }
                } else {
                    print "Skipping {$id}: Not a valid Git repository.\n";
                }
            } else {
                print "Skipping {$id}: Unhandled repository type " . $repo['type'] . ".\n";
            }
        } else {
            if (file_exists($plugin->getPath() . '.git/config')) {
                print "Skipping {$id}: No repository information found in package.json.\n";
            }
        }
    });
}
コード例 #30
0
ファイル: hook.php プロジェクト: rwardhan/datawrapper-1
<?php

/*
 * Generic hook script
 */
define('ROOT_PATH', dirname(dirname(__FILE__)) . '/');
define('NO_SLIM', 1);
define('NO_SESSION', 1);
require_once ROOT_PATH . 'lib/bootstrap.php';
date_default_timezone_set('Europe/Berlin');
$hook = $argv[1];
if (!empty($hook)) {
    DatawrapperHooks::execute($argv[1], isset($argv[2]) ? $argv[2] : null);
}