/** * Return the contents of the physical template file from the website private folder or from theme folder. * * The file is determined by the URL requested and the information in the database. * * @return string $template */ function nvweb_template_load($template_id = null) { global $current; global $DB; global $website; $template = ''; if (empty($template_id)) { $template_id = $current['template']; } if (!empty($template_id)) { $template = new template(); $template->load($template_id); if (!$template->enabled) { nvweb_clean_exit(); } if ($template->permission == 2) { nvweb_clean_exit(); } else { if ($template->permission == 1 && empty($_SESSION['APP_USER#' . APP_UNIQUE])) { nvweb_clean_exit(); } } if (file_exists($template->file)) { $template->file_contents = @file_get_contents($template->file); } else { if (file_exists(NAVIGATE_PRIVATE . '/' . $website->id . '/templates/' . $template->file)) { $template->file_contents = @file_get_contents(NAVIGATE_PRIVATE . '/' . $website->id . '/templates/' . $template->file); } else { $template->file_contents = 'NV error: template file not found! (' . $template->file . ')'; } } } return $template; }
function nvweb_votes_event($event, $html) { global $webuser; global $website; global $current; $code = ''; $js = ''; if ($event == 'before_parse') { if ($_REQUEST['plugin'] == 'nv_votes') { if (empty($webuser->id)) { echo json_encode(array('error' => 'no_webuser')); } else { $status = webuser_vote::update_object_votes($webuser->id, $_POST['object'], $_POST['object_id'], $_POST['score'], true); if ($status === 'already_voted') { echo json_encode(array('error' => 'already_voted')); } else { if ($status === true) { echo json_encode(array('ok' => 'true')); } else { if (!$status) { echo json_encode(array('error' => 'error')); } } } } nvweb_clean_exit(); } else { // add jquery from CDN if not already loaded if (strpos($html, 'jquery') === false) { $code = '<script language="javascript" type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>' . "\n"; } $js = ' function nvweb_votes_plugin_vote(value, callback) { jQuery.ajax({ type: "POST", url: "' . $website->absolute_path() . '/' . $current['route'] . '?plugin=nv_votes", data: { score: value, object: "' . $current['type'] . '", object_id: "' . $current['id'] . '" }, success: function(data) { if(callback) callback(data); }, dataType: "json" }); } '; nvweb_after_body("html", $code); nvweb_after_body("js", $js); } } return $html; }
function nvweb_route_parse($route = "") { global $website; global $DB; global $current; global $session; global $theme; global $events; global $dictionary; // node route types if (substr($route, 0, 5) == 'node/') { $node = substr($route, 5); $route = 'node'; } switch ($route) { case 'object': nvweb_object(); nvweb_clean_exit(); break; case 'nvajax': nvweb_ajax(); nvweb_clean_exit(); break; case 'nvtags': case 'nvsearch': $current['template'] = 'search'; break; case 'nv.webuser/verify': $hash = $_REQUEST['hash']; $email = filter_var($_REQUEST['email'], FILTER_VALIDATE_EMAIL); if (!empty($hash) && !empty($email)) { $ok = webuser::email_verification($email, $hash); if ($ok) { $session['nv.webuser/verify:email_confirmed'] = time(); } } nvweb_clean_exit(NVWEB_ABSOLUTE . $website->homepage()); break; case 'node': if ($node > 0) { $current['id'] = $node; $DB->query('SELECT * FROM nv_items WHERE id = ' . protect($current['id']) . ' AND website = ' . $website->id); $current['object'] = $DB->first(); // let's count a hit (except admin) if ($current['navigate_session'] != 1 && !nvweb_is_bot()) { $DB->execute(' UPDATE nv_items SET views = views + 1 WHERE id = ' . $current['id'] . ' AND website = ' . $website->id); } $current['type'] = 'item'; $current['template'] = $current['object']->template; if ($current['navigate_session'] == 1 && !empty($_REQUEST['template'])) { $current['template'] = $_REQUEST['template']; } } break; case 'sitemap.xml': nvweb_webget_load('sitemap'); echo nvweb_sitemap(array('mode' => 'xml')); nvweb_clean_exit(); break; // redirect to home page of the current website // redirect to home page of the current website case 'nvweb.home': case 'nv.home': header('location: ' . NVWEB_ABSOLUTE . $website->homepage()); nvweb_clean_exit(); break; // webservice endpoint via XML-RPC calls // webservice endpoint via XML-RPC calls case 'xmlrpc': $events->trigger('nvweb', 'xmlrpc', array('route' => '/' . $route)); // if no extension processes the call, use the integrated XML-RPC parser nvweb_xmlrpc(); nvweb_clean_exit(); break; // empty path // empty path case '': case '/': case 'nv.empty': if ($website->empty_path_action == 'homepage_noredirect') { $route = $website->homepage(); if (strpos($route, '/') === 0) { $route = substr($route, 1); } } else { $route = ""; $website->wrong_path_action = $website->empty_path_action; } // do NOT break this case, continue processing as wrong_path action // no special route (or already processed), look for the path on navigate routing table // do NOT break this case, continue processing as wrong_path action // no special route (or already processed), look for the path on navigate routing table default: $DB->query('SELECT * FROM nv_paths WHERE path = ' . protect('/' . $route) . ' AND website = ' . $website->id . ' ORDER BY id DESC'); $rs = $DB->result(); if (empty($rs)) { // no valid route found switch ($website->wrong_path_action) { case 'homepage': case 'homepage_redirect': header('location: ' . NVWEB_ABSOLUTE . $website->homepage()); nvweb_clean_exit(); break; case 'http_404': header("HTTP/1.0 404 Not Found"); nvweb_clean_exit(); break; case 'theme_404': $current['template'] = 'not_found'; $current['type'] = 'structure'; $current['id'] = 0; $current['object'] = new structure(); return; break; case 'website_path': $redirect_url = nvweb_template_convert_nv_paths($website->wrong_path_redirect); header('location: ' . $redirect_url); nvweb_clean_exit(); break; case 'blank': default: nvweb_clean_exit(); break; } } else { // route found! // let's count a hit (except admin) if ($current['navigate_session'] != 1 && !nvweb_is_bot()) { $DB->execute(' UPDATE nv_paths SET views = views + 1 WHERE id = ' . $rs[0]->id . ' AND website = ' . $website->id); } // set the properties found // set the default language for this route if (!isset($_REQUEST['lang'])) { $current['lang'] = $rs[0]->lang; $session['lang'] = $rs[0]->lang; // force reloading the dictionary $dictionary = nvweb_dictionary_load(); } $current['type'] = $rs[0]->type; $current['id'] = $rs[0]->object_id; // look for the template associated with this item if ($current['type'] == 'structure') { $obj = new structure(); $obj->load($current['id']); // check if it is a direct access to a "jump to another branch" path if ($obj->dictionary[$current['lang']]['action-type'] == 'jump-branch') { $current['id'] = $obj->dictionary[$current['lang']]['action-jump-branch']; $obj = new structure(); $obj->load($current['id']); header('location: ' . NVWEB_ABSOLUTE . $obj->paths[$current['lang']]); nvweb_clean_exit(); } else { if ($obj->dictionary[$current['lang']]['action-type'] == 'jump-item') { $current['id'] = $obj->dictionary[$current['lang']]['action-jump-item']; $obj = new item(); $obj->load($current['id']); header('location: ' . NVWEB_ABSOLUTE . $obj->paths[$current['lang']]); nvweb_clean_exit(); } } $current['object'] = $obj; $current['category'] = $current['id']; if ($current['navigate_session'] != 1 && !nvweb_is_bot()) { $DB->execute(' UPDATE nv_structure SET views = views + 1 WHERE id = ' . protect($current['id']) . ' AND website = ' . $website->id); } } else { if ($current['type'] == 'item') { $DB->query('SELECT * FROM nv_items WHERE id = ' . protect($current['id']) . ' AND website = ' . $website->id); $current['object'] = $DB->first(); // let's count a hit (except admin) if ($current['navigate_session'] != 1 && !nvweb_is_bot()) { $DB->execute(' UPDATE nv_items SET views = views + 1 WHERE id = ' . $current['id'] . ' AND website = ' . $website->id); } } else { if ($current['type'] == 'feed') { $out = feed::generate_feed($current['id']); if ($current['navigate_session'] != 1 && !nvweb_is_bot()) { $DB->execute(' UPDATE nv_feeds SET views = views + 1 WHERE id = ' . $current['id'] . ' AND website = ' . $website->id); } echo $out; nvweb_clean_exit(); } else { // path exists, but the object type is unknown // maybe the path belongs to an extension? $events->trigger('nvweb', 'routes', array('path' => $rs[0])); } } } $current['template'] = $current['object']->template; } break; } }
function nvweb_blocks_render_poll($object) { global $current; global $webgets; global $session; $webget = 'blocks'; nvweb_blocks_init(); if ($object->class != 'poll') { return; } if (!isset($session['polls'][$object->id])) { $session['polls'][$object->id] = false; } if ($_GET['poll_vote'] == $object->id && !empty($_POST['vote'])) { // submit vote and show results if (empty($session['polls'][$object->id])) { foreach ($object->trigger[$current['lang']] as $i => $answer) { if ($answer['code'] == $_POST['vote']) { $object->trigger[$current['lang']][$i]['votes'] = $object->trigger[$current['lang']][$i]['votes'] + 1; } } $object->save(); $session['polls'][$object->id] = true; } $out = nvweb_blocks_render_poll_results($object); echo $out; nvweb_clean_exit(); } else { if ($_GET['poll_result'] == $object->id) { echo nvweb_blocks_render_poll_results($object); nvweb_clean_exit(); } else { if (!empty($session['polls'][$object->id])) { $out = '<div class="block-poll ' . $object->type . '-' . $object->id . '" data-id="' . $object->id . '">'; $out .= nvweb_blocks_render_poll_results($object); $out .= '</div>'; } else { $out = '<div class="block-poll ' . $object->type . '-' . $object->id . '" data-id="' . $object->id . '">'; $out .= '<form action="?" method="post" id="block_poll_' . $object->type . '-' . $object->id . '_form">'; foreach ($object->trigger[$current['lang']] as $answer) { $out .= '<div class="block-poll-answer">'; $out .= ' <input type="radio" id="' . $object->type . '-' . $object->id . '-answer-' . $answer['code'] . '" name="' . $object->type . '-' . $object->id . '-answer" value="' . $answer['code'] . '" />'; $out .= ' <label for="' . $object->type . '-' . $object->id . '-answer-' . $answer['code'] . '">' . $answer['title'] . '</label>'; $out .= '</div>'; } $out .= '<div class="block-poll-actions">'; $out .= ' <input type="submit" id="' . $object->type . '-' . $object->id . '-submit" value="' . $webgets[$webget]['translations']["vote"] . '" />'; $out .= ' <input type="button" value="' . $webgets[$webget]['translations']["results"] . '" />'; $out .= '</div>'; $out .= '</form>'; $out .= '</div>'; nvweb_after_body("js", ' function block_poll_' . $object->id . '_vote() { if(document.querySelector("input[name=\\"' . $object->type . '-' . $object->id . '-answer\\"]:checked")) { var vote_value = document.querySelector("input[name=\\"' . $object->type . '-' . $object->id . '-answer\\"]:checked").value; var request = new XMLHttpRequest(); request.open("POST", "?poll_vote=' . $object->id . '", true); request.setRequestHeader("Content-type","application/x-www-form-urlencoded"); request.onreadystatechange = function() { if (this.readyState === 4) { if (this.status >= 200 && this.status < 400) { var resp = this.responseText; document.querySelector(".' . $object->type . '-' . $object->id . '").innerHTML = resp; } else { // Error } } }; request.send("poll=' . $object->id . '&vote=" + vote_value); request = null; return false; } else return false; } function block_poll_' . $object->id . '_result() { var request = new XMLHttpRequest(); request.open("GET", "?poll_result=' . $object->id . '", true); request.onreadystatechange = function() { if (this.readyState === 4) { if (this.status >= 200 && this.status < 400) { var resp = this.responseText; document.querySelector(".' . $object->type . '-' . $object->id . '").innerHTML = resp; } else { // Error } } }; request.send(); request = null; return false; } document.querySelector("form[id=block_poll_' . $object->type . '-' . $object->id . '_form]").onsubmit = block_poll_' . $object->id . '_vote; document.querySelector(".block-poll-actions input[type=button]").onclick = block_poll_' . $object->id . '_result; '); } } } return $out; }
$current['webuser'] = $session['webuser']; setlocale(LC_ALL, $website->languages[$session['lang']]['system_locale']); date_default_timezone_set($webuser->timezone ? $webuser->timezone : $website->default_timezone); // help developers to find problems if ($current['navigate_session'] == 1 && APP_DEBUG) { error_reporting(E_ALL ^ E_NOTICE); ini_set('display_errors', true); } // parse route nvweb_route_parse($current['route']); $permission = nvweb_check_permission(); // if no preview & permission not allowed // if preview but no navigate_session active if ($_REQUEST['preview'] == 'true' && $current['navigate_session'] != 1 || empty($_REQUEST['preview']) && !$permission) { nvweb_route_parse('***nv.not_allowed***'); nvweb_clean_exit(); } $template = nvweb_template_load(); $events->trigger('theme', 'template_load', array('template' => &$template)); if (empty($template)) { throw new Exception('Navigate CMS: no template found!'); } // parse the special tag "include" // also convert curly brackets tags {{nv object=""}} to <nv object="" /> version // we do it now because new nv tags could be added before parsing the whole html $html = nvweb_template_parse_special($template->file_contents); $current['plugins_called'] = nvweb_plugins_called_in_template($html); $html = nvweb_plugins_event('before_parse', $html); $html = nvweb_theme_settings($html); $html = nvweb_template_parse_lists($html); $html = nvweb_template_parse($html);
function nv_plugin_init() { global $DB; global $webuser; global $config; global $website; global $current; global $dictionary; global $session; global $events; global $idn; // create database connection $DB = new database(); if (!$DB->connect()) { die(APP_NAME . ' # ERROR<br /> ' . $DB->get_last_error()); } // global exception catcher try { $idn = new idna_convert(); // which website do we have to load? $url = nvweb_self_url(); if (!empty($_REQUEST['wid'])) { $website = new website(); $website->load(intval($_REQUEST['wid'])); } else { $website = nvweb_load_website_by_url($url); } if ($website->permission == 2 || $website->permission == 1 && empty($_SESSION['APP_USER#' . APP_UNIQUE])) { nvweb_clean_exit(); } // global helper variables $session = array(); // user session $webuser = new webuser(); $nvweb_absolute = empty($website->protocol) ? 'http://' : $website->protocol; if (!empty($website->subdomain)) { $nvweb_absolute .= $website->subdomain . '.'; } $nvweb_absolute .= $website->domain . $website->folder; define('NVWEB_ABSOLUTE', $nvweb_absolute); define('NVWEB_OBJECT', $nvweb_absolute . '/object'); if (!defined('NAVIGATE_URL')) { define('NAVIGATE_URL', NAVIGATE_PARENT . NAVIGATE_FOLDER); } if (!isset($_SESSION['nvweb.' . $website->id])) { $_SESSION['nvweb.' . $website->id] = array(); $session['lang'] = nvweb_country_language(); } else { $session = $_SESSION['nvweb.' . $website->id]; if (empty($session['lang'])) { $session['lang'] = nvweb_country_language(); } } if (isset($_REQUEST['lang'])) { $session['lang'] = $_REQUEST['lang']; } if (!empty($session['webuser'])) { $webuser->load($session['webuser']); } else { if (!empty($_COOKIE["webuser"])) { $webuser->load_by_hash($_COOKIE['webuser']); } } @setlocale(LC_ALL, $website->languages[$session['lang']]['system_locale']); // remove the "folder" part of the route $route = ''; if (!empty($_REQUEST['route'])) { $route = $_REQUEST['route']; // remove the "folder" part of the route (only if this url is really under a folder) if (!empty($website->folder) && strpos('/' . $route, $website->folder) === 0) { $route = substr('/' . $route, strlen($website->folder) + 1); } } // global data across webgets $current = array('lang' => $session['lang'], 'route' => $route, 'object' => '', 'template' => '', 'category' => '', 'webuser' => @$session['webuser'], 'navigate_session' => !empty($_SESSION['APP_USER#' . APP_UNIQUE]), 'html_after_body' => array(), 'js_after_body' => array()); $dictionary = nvweb_dictionary_load(); $_SESSION['nvweb.' . $website->id] = $session; } catch (Exception $e) { ?> <html> <body> ERROR <br /><br /> <?php echo $e->getMessage(); ?> </body> </html> <?php } $events = new events(); nvweb_plugins_load(); $events->extension_backend_bindings(); }
function nvweb_object($ignoreEnabled = false, $ignorePermissions = false) { global $website; global $DB; session_write_close(); ob_end_clean(); $item = new file(); header('Cache-Control: private'); header('Pragma: private'); $type = @$_REQUEST['type']; $id = @$_REQUEST['id']; if (!empty($id)) { if (is_numeric($id)) { $item->load($id); } else { $item->load($_REQUEST['id']); } } if (empty($type) && !empty($item->type)) { $type = $item->type; } // if the type requested is not a special type, check its access permissions if (!in_array($type, array("blank", "transparent", "flag"))) { $enabled = nvweb_object_enabled($item); if (!$enabled && !$ignorePermissions) { $type = 'not_allowed'; } } switch ($type) { case 'not_allowed': header("HTTP/1.0 405 Method Not Allowed"); break; case 'blank': case 'transparent': $path = NAVIGATE_PATH . '/img/transparent.gif'; header('Content-Disposition: attachment; filename="transparent.gif"'); header('Content-Type: image/gif'); header('Content-Disposition: inline; filename="transparent.gif"'); header("Content-Transfer-Encoding: binary\n"); $etag = base64_encode($path . filemtime($path)); header('ETag: "' . $etag . '"'); // check the browser cache and stop downloading again the file $cached = file::cacheHeaders(filemtime($path), $etag); if (!$cached) { readfile($path); } break; case 'flag': if ($_REQUEST['code'] == 'ca') { $_REQUEST['code'] = 'catalonia'; } header('Content-Disposition: attachment; filename="' . $_REQUEST['code'] . '.png"'); header('Content-Type: image/png'); header('Content-Disposition: inline; filename="' . $_REQUEST['code'] . '.png"'); header("Content-Transfer-Encoding: binary\n"); $path = NAVIGATE_PATH . '/img/icons/flags/' . $_REQUEST['code'] . '.png'; if (!file_exists($path)) { $path = NAVIGATE_PATH . '/img/transparent.gif'; } $etag = base64_encode($path . filemtime($path)); header('ETag: "' . $etag . '"'); // check the browser cache and stop downloading again the file $cached = file::cacheHeaders(filemtime($path), $etag); if (!$cached) { readfile($path); } break; case 'image': case 'img': if (!$item->enabled && !$ignoreEnabled) { nvweb_clean_exit(); } $path = $item->absolute_path(); $etag_add = ''; // calculate aspect ratio if width or height are given... $width = intval(@$_REQUEST['width']) + 0; $height = intval(@$_REQUEST['height']) + 0; // check size requested and ignore the empty values (or equal to zero) if (empty($width)) { $width = ""; } if (empty($height)) { $height = ""; } // get target quality (only for jpeg thumbnails!) $quality = $_REQUEST['quality']; if (empty($quality)) { $quality = 95; } $resizable = true; if ($item->mime == 'image/gif') { $resizable = !file::is_animated_gif($path); } if ((!empty($width) || !empty($height)) && ($resizable || @$_REQUEST['force_resize'] == 'true')) { $border = $_REQUEST['border'] == 'false' ? false : true; $path = file::thumbnail($item, $width, $height, $border, NULL, $quality); if (empty($path)) { die; } $etag_add = '-' . $width . '-' . $height . '-' . $border . '-' . $quality; $item->name = $width . 'x' . $height . '-' . $item->name; $item->size = filesize($path); $item->mime = 'image/png'; if (strpos(basename($path), '.jpg') !== false) { $item->mime = 'image/jpeg'; } } $etag = base64_encode($item->id . '-' . $item->name . '-' . $item->date_added . '-' . filesize($path) . '-' . filemtime($path) . '-' . $item->permission . $etag_add); header('ETag: "' . $etag . '"'); header('Content-type: ' . $item->mime); header("Content-Length: " . $item->size); if (empty($_REQUEST['disposition'])) { $_REQUEST['disposition'] = 'inline'; } header('Content-Disposition: ' . $_REQUEST['disposition'] . '; filename="' . $item->name . '"'); // check the browser cache and stop downloading again the file $cached = file::cacheHeaders(filemtime($path), $etag); if (!$cached) { readfile($path); } break; case 'archive': case 'video': case 'file': default: if (!$item->enabled && !$ignoreEnabled) { nvweb_clean_exit(); } $path = NAVIGATE_PRIVATE . '/' . $website->id . '/files/' . $item->id; $etag_add = ''; clearstatcache(); $etag = base64_encode($item->id . '-' . $item->name . '-' . $item->date_added . '-' . filemtime($path) . '-' . $item->permission . $etag_add); header('ETag: "' . $etag . '"'); header('Content-type: ' . $item->mime); header("Accept-Ranges: bytes"); if (empty($_REQUEST['disposition'])) { $_REQUEST['disposition'] = 'attachment'; } header('Content-Disposition: ' . $_REQUEST['disposition'] . '; filename="' . $item->name . '"'); // check the browser cache and stop downloading again the file $cached = file::cacheHeaders(filemtime($path), $etag); if (!$cached) { $range = 0; $size = filesize($path); if (isset($_SERVER['HTTP_RANGE'])) { list($a, $range) = explode("=", $_SERVER['HTTP_RANGE']); str_replace($range, "-", $range); $size2 = $size - 1; $new_length = $size - $range; header("HTTP/1.1 206 Partial Content"); header("Content-Length: {$new_length}"); header("Content-Range: bytes {$range}{$size2}/{$size}"); } else { $size2 = $size - 1; header("Content-Range: bytes 0-{$size2}/{$size}"); header("Content-Length: " . $size); } $fp = fopen($path, "rb"); if (is_resource($fp)) { @fseek($fp, $range); while (!@feof($fp) && connection_status() == 0) { set_time_limit(0); print @fread($fp, 1024 * 1024); // 1 MB per second flush(); ob_flush(); sleep(1); } fclose($fp); } } break; } session_write_close(); if ($DB) { $DB->disconnect(); } exit; }