public static function view($viewname) { // Make this component view extend the base template, with their locations set to the component folders $componenturl = Wi3::inst()->urlof->pagefillerfiles("default") . "components/link/"; $componentpath = Wi3::inst()->pathof->pagefiller("default") . "components/link/"; $componentbaseview = Wi3_Baseview::instance('imagecomponentbaseview', array('javascript_url' => $componenturl . 'static/javascript/', 'javascript_path' => $componentpath . 'static/javascript/', 'css_url' => $componenturl . 'static/css/', 'css_path' => $componentpath . 'static/css/')); $componentview = View::factory()->set("this", $componentbaseview); $componentview->set_filepath($componentpath . 'views/' . $viewname . EXT); // set_filepath sets a complete filename on the View return $componentview; }
public function view($viewname, $usecomponentlocation = TRUE) { if ($usecomponentlocation == FALSE) { // Use views from component_base $componenturl = Wi3::inst()->urlof->pagefillerfiles("default"); $componentpath = Wi3::inst()->pathof->pagefiller("default"); } else { // Use views from inherited component $componenturl = Wi3::inst()->urlof->pagefillerfiles("default") . "components/" . $this::$componentname . "/"; $componentpath = Wi3::inst()->pathof->pagefiller("default") . "components/" . $this::$componentname . "/"; } // Make this component view extend the base template, with their locations set to the above folders $componentbaseview = Wi3_Baseview::instance($this::$componentname . 'baseview_' . ($usecomponentlocation ? "true" : "false"), array('javascript_url' => $componenturl . 'static/javascript/', 'javascript_path' => $componentpath . 'static/javascript/', 'css_url' => $componenturl . 'static/css/', 'css_path' => $componentpath . 'static/css/')); $componentview = View::factory()->set("this", $componentbaseview); $componentview->set_filepath($componentpath . 'views/' . $viewname . EXT); // set_filepath sets a complete filename on the View return $componentview; }
public function init() { // Load session handler $this->session = Session::instance(); // Set cache handler $this->cache = Wi3TikoCache::instance(); // Define APPRELATIVEPATH, which is the path to the application relative to the web root // We can retrieve this by using the SCRIPT_NAME from the front-controller ({pathfromroot}/app/index.php), and extracting the path-from-root define("APPRELATIVEPATH", substr($_SERVER["SCRIPT_NAME"], 0, strpos($_SERVER["SCRIPT_NAME"], "/app/index.php")) . "/app/latest/"); // Define document root // TODO: Add support for ISS (see http://www.helicron.net/php/) define("DOCUMENTROOT", $_SERVER["DOCUMENT_ROOT"] . "/"); // Determine language $lang = Cookie::get('lang'); if ($lang !== NULL) { if (!in_array($lang, array('nl-nl', 'en-us'))) { // Check the allowed languages, and force the default $lang = 'nl-nl'; } } else { // Language not set in cookie. Get default language from i18n file. $i18nfiles = Kohana::find_file("config", "i18n"); if (!empty($i18nfiles)) { $i18nsettings = Kohana::load($i18nfiles[0]); $lang = $i18nsettings["lang"]; } else { $lang = 'nl-nl'; // Fall back to default } // Save loaded language in cookie Cookie::set('lang', $lang); } // Set the target language i18n::lang($lang); // Set the source language to some non-existing language to prevent Kohana skipping translation lookup if source and target language are identical i18n::$source = "bb-bb"; // See http://unicode.org/cldr/utility/languageid.jsp?a=bb&l=en for valid tags // Load wi3-kohana-specific functions $this->kohana = new Wi3_Kohana(); // XSS Clean all user input! // TODO: only do this if the user is not an admin... $this->originalpost = $_POST; // Save original $_POST foreach ($_POST as $key => $val) { $_POST[$key] = Security::xss_clean($val); } $this->originalget = $_GET; // Save original $_GET foreach ($_GET as $key => $val) { $_GET[$key] = Security::xss_clean($val); } // Load some Wi3 classes // Load a global database configuration $this->database = new Wi3_Database(); // Helper functions to create databases etc $this->globaldatabase = Wi3_Database::instance("global"); Event::instance("wi3.init.globaldatabase.loaded")->execute(); // Get routing, url and path information // These classes in turn add a callback to the wi3.init.site.loaded Event, after which they will update with path and urls to the site $this->routing = Wi3_Routing::instance(); Event::instance("wi3.init.routing.loaded")->execute(); $this->pathof = Wi3_Pathof::instance(); Event::instance("wi3.init.pathof.loaded")->execute(); $this->urlof = Wi3_Urlof::instance(); Event::instance("wi3.init.urlof.loaded")->execute(); // Load CSS and Javascript 'injectors' $this->css = Wi3_Css::instance(); $this->javascript = Wi3_Javascript::instance(); // Instantiate the Model class, that is an interface to the 'factory' method for any underlying model-systems $this->model = Wi3_Model::inst(); Event::instance("wi3.init.model.loaded")->execute(); // Instantiate the form-builder $this->formbuilder = Wi3_Formbuilder::inst(); Event::instance("wi3.init.formbuilder.loaded")->execute(); // Now find out what is the scope of this request // It most often is a site-scope (i.e. the admin or view of a site), but might also be a global scope (i.e. superadmin) // This depends on the controller. // Pagefiller-specific controllers are always for the the sitearea $this->scope = (substr(Request::instance()->controller, 0, 9) == "adminarea" or substr(Request::instance()->controller, 0, 10) == "pagefiller" or Request::instance()->controller == "sitearea") ? "site" : "global"; if ($this->scope == "site") { $this->sitearea = Wi3_Sitearea::inst(); // Find out what site we are working with // Both the admin controller and the site controller need to know this in order to work properly // Find the site by apache 'sitename' variable if (isset($_SERVER['REDIRECT_SITENAME'])) { $sitename = $_SERVER['REDIRECT_SITENAME']; // With correct loading, $_SERVER['REDIRECT_SITENAME'] should always be present, as it is set in the vhosts .htaccess that redirect here // Global site is the site in the global space, i.e. the Site model in the 'list of sites' that is always accesible // ( In the per-site database, there can only exist one Site model ) $this->sitearea->globalsite = $this->model->factory("site")->set('name', $sitename)->load(); Event::instance("wi3.init.sitearea.globalsite.loaded")->execute(); $this->sitearea->site = $this->sitearea->globalsite; // This site instance will be replaced by the local user site. The ->name will be added to that local site, since it does not store that in the local db } // If the sitename not present, the page request came here via some illegal method. // If the site was not loaded correctly or is not active, we cannot show the site either if (!isset($_SERVER['REDIRECT_SITENAME']) or empty($sitename) or !$this->sitearea->globalsite->loaded() or $this->sitearea->globalsite->active == FALSE) { // Site does not exist. Quit. throw new Kohana_Exception("site does not exist"); } // Global site has been loaded and it was found to be active // Now we load the local site and requested page from within the user Database // This requires the inclusion of the site as a module and an init on its database-config // // First, Include the whole site-tree in the find_file() function Kohana::modules(Kohana::modules() + array("site" => APPPATH . "../../sites/" . $sitename . "/")); // Because Kohana uses include_once() this will only init the new module, without double-including the others // Load the sitedatabase config. It will be fetched from the sites/sitename/config folder since the sites/sitename is now in the Kohana find_file paths $siteconfig = Kohana::config('sitedatabase')->site; // Set up a site database connection, to be used by the site-based-models like Site_Page, Site_User, File etc $this->sitearea->database = Wi3_Database::instance("site", $siteconfig); Event::instance("wi3.init.sitearea.database.loaded")->execute(); // Load the user-site $this->sitearea->site = $this->model->factory("site_site")->set('id', 1)->load(); $this->sitearea->site->name = $sitename; // Add name, since this is not stored in the local site tables, but only in the global ones Event::instance("wi3.init.sitearea.site.loaded")->execute(); // Load the pageposition, page and file manager, all within the sitearea $this->sitearea->pagepositions = Wi3_Sitearea_Pagepositions::inst(); $this->sitearea->pages = Wi3_Sitearea_Pages::inst(); $this->sitearea->files = Wi3_Sitearea_Files::inst(); $this->sitearea->users = Wi3_Sitearea_Users::inst(); } // Load baseviews that are passed as $this into views in order to enable some in-view functions // Different setups are possible with the different parameters supplied // An instance is created, so that they can also be referenced simply from again loading e.g. Wi3_Baseview::instance('superadminarea'); // These instances are used as 'object scope' for the $this variables in views. See i.e. the superadminarea-controller's ->view function and the Baseview->capture() for more details $this->baseview_superadminarea = Wi3_Baseview::instance('superadminarea', array('javascript_url' => $this->urlof->appfiles . 'static/javascript/', 'javascript_path' => $this->pathof->app . 'static/javascript/', 'css_url' => $this->urlof->appfiles . 'static/css/', 'css_path' => $this->pathof->app . 'static/css/')); //Maybe just define the asset-path(s), from which the URLs are deduced, based on the Wi3::inst()->urlof ? $this->baseview_adminarea = Wi3_Baseview::instance('adminarea', array('javascript_url' => $this->urlof->appfiles . 'static/javascript/', 'javascript_path' => $this->pathof->app . 'static/javascript/', 'css_url' => $this->urlof->appfiles . 'static/css/', 'css_path' => $this->pathof->app . 'static/css/')); $this->baseview_sitearea = Wi3_Baseview::instance('sitearea', array('javascript_url' => $this->urlof->site . 'static/javascript/', 'javascript_path' => $this->pathof->site . 'static/javascript/', 'css_url' => $this->urlof->site . 'static/css/', 'css_path' => $this->pathof->site . 'static/css/')); Event::instance("wi3.init.baseviews.loaded")->execute(); // Set up an config loader $this->configof = Wi3_Configof::instance(); // Set up auth. This will try to login the current user from either the site db or the global db, based on the scope if ($this->scope == "site") { $this->sitearea->auth = Wi3_Auth_Site::instance(); } else { // If user is in setup, then don't yet load Auth and Database instances, since they most probably don't yet exist if (Request::instance()->controller != "setup") { $this->globalauth = Wi3_Auth_Global::instance(); } } $this->acl = Wi3_ACL::instance(); // Load the plugin-manager. The manager will also include the paths to the plugins in the modules-system $this->plugins = new Wi3_Plugins(); if ($this->scope == "site") { // Make all the pageversion-plugins to load // The versionplugins should respond to this event call, and add them to the $this->versionplugins array Event::instance('wi3.sitearea.pages.versionplugins.load')->execute(); } }
public function render($page, $renderedinadminarea) { // Debug: Make sure the 'site_data' and 'site_field' table exists //Wi3::inst()->database->create_table_from_sprig_model("site_data"); //Wi3::inst()->database->create_table_from_sprig_model("site_field"); //------------------- // Enable Components //------------------- // Get component path $componentpath = Wi3::inst()->pathof->pagefiller("default") . "components/"; $components = array(); // Loop over component-modules and add them $dir = new DirectoryIterator($componentpath); foreach ($dir as $file) { if ($file->isDir() && !$file->isDot()) { $components[] = $file->getPathname(); } } Kohana::modules(Kohana::modules() + $components); //------------------- // Raw template //------------------- // Get template $templatename = $page->templatename; $templates = Wi3::inst()->configof->site->templates->templates; // Must exist! if (isset($templates)) { // If there is a templatename set, use that one (if it is available), otherwise use the first that is encountered if ($templatename != NULL and isset($templates->{$templatename})) { $templateconfig = new Wi3_Config(array("configfile" => $templates->{$templatename}->path . "config/config.php")); } } // A page template always extends the base template, with their locations set to the template folders $templatebaseview = Wi3_Baseview::instance('templatebaseview', array('javascript_url' => $templates->{$templatename}->url . 'static/javascript/', 'javascript_path' => $templates->{$templatename}->path . 'static/javascript/', 'css_url' => $templates->{$templatename}->url . 'static/css/', 'css_path' => $templates->{$templatename}->path . 'static/css/', 'image_url' => $templates->{$templatename}->url . 'static/images/', 'view_path' => $templates->{$templatename}->path . 'views/')); $templateview = View::factory()->set("this", $templatebaseview)->set("renderedinadminarea", $renderedinadminarea); $templateview->set_filepath($templateconfig->templateview); // set_filepath sets a complete filename on the View $html = $templateview->render(); //------------------- // Helper functions for editing and viewing //------------------- function getAllFields($content) { $fields = $content->find("cms[type=field]"); $sitefields = $content->find("cms[type=sitefield]"); $allfields = array(); foreach ($sitefields as $pqfield) { $allfields[] = $pqfield; } foreach ($fields as $pqfield) { $allfields[] = $pqfield; } return $allfields; } function getField($pqfield, $page) { $fieldid = pq($pqfield)->attr("fieldid"); $fieldname = pq($pqfield)->attr("fieldname"); $type = pq($pqfield)->attr("type"); $field = Wi3::inst()->model->factory("site_field"); if ($type == "field") { if ($fieldid) { return $field->setref($page)->set("id", $fieldid)->load(); } else { if ($fieldname) { return $field->setref($page)->set("name", $fieldname)->load(); } } } else { if ($type == "sitefield") { $siteFieldObject = new siteFieldObject(); if (!empty($fieldid)) { return $field->setref($siteFieldObject)->set("id", $fieldid)->load(); } else { if (!empty($fieldname)) { return $field->setref($siteFieldObject)->set("name", $fieldname)->load(); } else { throw new Exception("either fieldid or fieldname should be set on sitefield"); } } } } return $field; // loaded() is false } //------------------- // Editing //------------------- // Check whether the user is in adminarea, and if so, inject the popupdiv and page-id at <body> if ($renderedinadminarea === true) { // Enable FilteredPaste.js for use in wi3 plugin Wi3::inst()->plugins->load("plugin_jquery_filteredpaste"); // Enable jQuery UI Wi3::inst()->plugins->load("plugin_jquery_ui"); Wi3::inst()->plugins->load("plugin_jquery_wi3"); $this->javascript("edittoolbar/onpage.js"); $this->javascript("jq-wysihat.js"); $this->javascript("rangy-core.js"); // Insert Popup $popuphtml = $this->view("popup")->render(); $html = preg_replace("@<body[^>]*>@", "\$0" . $popuphtml, $html); // Insert Page-ID $pageidhtml = $this->view("pageid")->set("page", $page)->render(); $html = preg_replace("@<body[^>]*>@", "\$0" . $pageidhtml, $html); // Replace all the <cms> blocks with the appropriate content $html = phpQuery::newDocument($html); // Give PHPQuery a context to work with function replacePQFieldsWithAdminHTML($content, $page, $controller) { $allfields = getAllFields($content); foreach ($allfields as $pqfield) { $field = getField($pqfield, $page); if (!$field->loaded()) { // Create field $fieldtype = pq($pqfield)->attr("fieldtype"); if (pq($pqfield)->attr("type") == "field") { $ref = $page; } else { $ref = new siteFieldObject(); } $field = Wi3::inst()->model->factory("site_field")->setref($ref)->set("type", $fieldtype); // Store name, if present $fieldname = pq($pqfield)->attr("fieldname"); if ($fieldname) { $field->set("name", $fieldname); } // This should not happen... Log it! if (empty($field->type)) { // TODO: log pq($pqfield)->replaceWith("Could not be loaded"); continue; } $field->create(); } if ($field->loaded()) { $fieldedithtml = $controller->view("fieldrender_edit")->set("field", $field)->set("pqfield", $pqfield)->render(); pq($pqfield)->replaceWith($fieldedithtml); } } } //------------------- // Fields outside editable blocks //------------------- $count = count(getAllFields($html)); while ($count > 0) { replacePQFieldsWithAdminHTML($html, $page, $this); $count = count(getAllFields($html)); } //------------------- // Editable blocks and the fields therein //------------------- $editableblocks = $html->find("cms[type=editableblock]"); while (count($editableblocks->elements) > 0) { foreach ($editableblocks as $editableblock) { $name = pq($editableblock)->attr("name"); // Try to load up to date content for this block, otherwise show the default content $refname = pq($editableblock)->attr("reference"); // Check if we need to load from field or from the page // By default, if there's no refname, try to search for a wrapping field, otherwise fallback to the page if (empty($refname)) { $refname = "field"; } if ($refname == "field") { // Get the field in which this block is located $parentField = pq($editableblock)->parents("[type=field][fieldid]"); if (count($parentField->elements) > 0) { $fieldid = $parentField->attr("fieldid"); $ref = Wi3::inst()->model->factory("site_field")->set("id", $fieldid)->load(); // Load content from field $content = $ref->loadEditableBlockContent($editableblock, $name); } else { $refname = "page"; } } if ($refname == "page") { // Load content from page $content = $page->loadEditableBlockContent($editableblock, $name); } // Replace the <cms type='field'> blocks and expand them into real field-renders $content = phpQuery::newDocument($content); $count = count(getAllFields($content)); while ($count > 0) { replacePQFieldsWithAdminHTML($content, $page, $this); $count = count(getAllFields($content)); } // Ensure that inner CMS blocks have the same display (i.e. block or inline) as its parent $style = "style='display: inherit'"; // Set block-content $blockcontent = "<div type='editableblock' " . $style . " name='" . $name . "' contenteditable='true'>" . $content . "</div>"; pq($editableblock)->replaceWith($blockcontent); } // Check if this rendering cycle might have yielded even more editable blocks that need to be processed $editableblocks = $html->find("cms[type=editableblock]"); } } else { // If user is logged in, enable the Control+Alt+E for editmode if (Wi3::inst()->sitearea->auth->user) { // TODO } // Simply display the contents of the block, not making them editable $html = phpQuery::newDocument($html); // Give PHPQuery a context to work with function replacePQFieldsWithViewHTML($content, $page, $renderedinadminarea) { $allfields = getAllFields($content); foreach ($allfields as $pqfield) { $field = getField($pqfield, $page); if (!$field->loaded()) { // Create field $fieldtype = pq($pqfield)->attr("fieldtype"); // Determine whether the field should be attached to the page or to the 'site' (i.e. page-independent) if (pq($pqfield)->attr("type") == "field") { $ref = $page; } else { $ref = new siteFieldObject(); } $field = Wi3::inst()->model->factory("site_field")->setref($ref)->set("type", $fieldtype); // Store name, if present $fieldname = pq($pqfield)->attr("fieldname"); if ($fieldname) { $field->set("name", $fieldname); } // This should not happen... Log it! if (empty($field->type)) { // TODO: log pq($pqfield)->replaceWith("Could not be loaded"); continue; } /* var_dump($field); var_dump(pq($pqfield)->attr("type")); var_dump(pq($pqfield)->attr("name")); var_dump(pq($pqfield)->parent()->html()); exit;*/ $field->create(); } if ($field->loaded()) { // Get set style $style = pq($pqfield)->attr("style"); $field->options["style"] = $style; // Get style options $stylearray = array(); $stylearray["float"] = pq($pqfield)->attr("style_float"); $stylearray["padding"] = pq($pqfield)->attr("style_padding"); $stylearray["width"] = pq($pqfield)->attr("style_width"); // Only set an explicit display block if no display is found in '$style' if (strpos($style, "display:") === false) { $stylearray["display"] = "block"; } $field->options["stylearray"] = $stylearray; // Render the field, in which the field can also change the style options $fieldhtml = $field->render($renderedinadminarea, $pqfield); // The field can override these options, if it wants $style = $field->options["style"]; $stylearray = $field->options["stylearray"]; // Once the field is rendered, it is known whether it wants to be an inline element, or a block element // Use float and padding only if element is not inline if (strpos($style, "display:inline") !== false || isset($stylearray["display"]) && $stylearray["display"] == "inline") { unset($stylearray["float"]); unset($stylearray["padding"]); } // Calculate total style $totalstyle = $style; foreach ($stylearray as $name => $val) { if (!empty($val)) { $totalstyle .= "; " . $name . ":" . $val; } } $totalstyle .= "; position: relative;"; // Replace the <cms> part with a render of the field $fieldedithtml = "<div type='field' fieldid='" . $field->id . "' style='" . $totalstyle . "' contenteditable='false'>" . $fieldhtml . "</div>"; pq($pqfield)->replaceWith($fieldedithtml); } } // Return how many fields were replaced return count($allfields); } //------------------- // Fields outside editable blocks //------------------- $count = count(getAllFields($html)); while ($count > 0) { replacePQFieldsWithViewHTML($html, $page, $renderedinadminarea); $count = count(getAllFields($html)); } //------------------- // Editable blocks and the fields therein //------------------- $editableblocks = $html->find("cms[type=editableblock]"); while (count($editableblocks->elements) > 0) { foreach ($editableblocks as $editableblock) { $name = pq($editableblock)->attr("name"); // Try to load up to date content for this block, otherwise show the default content $refname = pq($editableblock)->attr("reference"); // Check if we need to load from field or from the page // By default, if there's no refname, try to search for a wrapping field, otherwise fallback to the page if (empty($refname)) { $refname = "field"; } if ($refname == "field") { // Get the field in which this block is located $parentField = pq($editableblock)->parents("[type=field][fieldid]"); if (count($parentField->elements) > 0) { $fieldid = $parentField->attr("fieldid"); $ref = Wi3::inst()->model->factory("site_field")->set("id", $fieldid)->load(); // Load content from field $content = $ref->loadEditableBlockContent($editableblock, $name); } else { $refname = "page"; } } if ($refname == "page") { // Load content from page $content = $page->loadEditableBlockContent($editableblock, $name); } // Replace the <cms type='field'> and <cms type='sitefield'> blocks and expand them into real field-renders // For normal fields, the fieldid is unique for the page // For sitefields, the fieldid is unique for the site, using the siteFieldObject // Example layout: /** * <cms type='field' fieldtype='image' fieldname='uniqueid' style_float="left" style_padding="20px"> * </cms> */ $content = phpQuery::newDocument($content); $count = count(getAllFields($content)); while ($count > 0) { replacePQFieldsWithViewHTML($content, $page, $renderedinadminarea); $count = count(getAllFields($content)); } // Ensure that inner CMS blocks have the same display (i.e. block or inline) as its parent $style = "style='display: inherit'"; // Replace the <cms type='editableblock'> blocks into DOM tags if (!empty($id)) { $blockcontent = "<div " . $style . " id='" . $id . "' type='contentblock' ref='" . $refname . "' name='" . $name . "'>" . $content . "</div>"; } else { $blockcontent = "<div " . $style . " type='contentblock' ref='" . $refname . "' name='" . $name . "'>" . $content . "</div>"; } pq($editableblock)->replaceWith($blockcontent); } // Check if this rendering cycle might have yielded even more editable blocks that need to be processed $editableblocks = $html->find("cms[type=editableblock]"); } } return $html; }