protected function render_inner_html() { global $core; $rc = parent::render_inner_html(); $constructor = $this[self::T_CONSTRUCTOR]; $value = $this['value'] ?: $this[self::DEFAULT_VALUE]; $record = null; if ($value) { $model = $core->models[$constructor]; try { $record = is_numeric($value) ? $model[$value] : $this->getEntry($model, $value); } catch (\Exception $e) { \ICanBoogie\log_error('Missing record %nid', ['%nid' => $value]); } } if (!$record) { $this->add_class('placeholder'); $value = null; } $rc .= new Element('input', ['type' => 'hidden', 'name' => $this['name'], 'value' => $value]); $placeholder = $this['placeholder']; if ($placeholder) { $rc .= '<em class="spinner-placeholder">' . \ICanBoogie\escape($placeholder) . '</em>'; } $rc .= '<span class="spinner-content">' . $this->getPreview($record) . '</span>'; return $rc; }
protected function process() { global $core; $record = $this->record; $key = $this->key; $title = $record->title; unset($record->nid); unset($record->is_online); unset($record->created_at); unset($record->updated_at); $record->uid = $core->user_id; $record->title .= ' (copie)'; $record->slug .= '-copie'; $contentsModel = $this->module->model('contents'); $contents = $contentsModel->where(array('pageid' => $key))->all; $nid = $this->module->model->save((array) $record); if (!$nid) { \ICanBoogie\log_error('Unable to copy page %title (#:nid)', array('title' => $title, 'nid' => $key)); return; } $this->response->message = new FormattedString('Page %title was copied to %copy', array('title' => $title, 'copy' => $record->title)); foreach ($contents as $record) { $record->pageid = $nid; $record = (array) $record; $contentsModel->insert($record, array('on duplicate' => $record)); } return array($key, $nid); }
/** * Collects versions. * * @return array[string]array */ private static function collect(\ICanBoogie\Core $core) { $versions = array(); $definitions = $core->registry->select('SUBSTR(name, LENGTH("thumbnailer.versions.") + 1) as name, value')->where('name LIKE ?', 'thumbnailer.versions.%')->pairs; foreach ($definitions as $name => $options) { if (!$options || !is_string($options) || $options[0] != '{') { \ICanBoogie\log_error('Bad version: %name, :options', array('name' => $name, 'options' => $options)); continue; } $versions[$name] = Version::normalize(json_decode($options, true)); } return $versions; }
/** * Displays a login form on {@link SecurityException}. * * @param \ICanBoogie\Exception\RescueEvent $event * @param SecurityException $target */ public static function on_security_exception_rescue(\ICanBoogie\Exception\RescueEvent $event, SecurityException $target) { global $core; $request = $event->request; if ($request->context->dispatcher instanceof \ICanBoogie\Operation\Dispatcher && $request->is_xhr) { return; } if ($target instanceof PermissionRequired || \ICanBoogie\Routing\decontextualize($request->normalized_path) != '/admin/') { \ICanBoogie\log_error($target->getMessage()); } $block = $core->modules['users']->getBlock('connect'); $document = new \Icybee\DocumentDecorator(new \Icybee\AdminDecorator($block)); $document->body->add_class('page-slug-authenticate'); $event->response = new Response((string) $document, $target->getCode(), ['Content-Type' => 'text/html; charset=utf-8']); $event->stop(); }
/** * The "defaults" operation can be used to retrieve the default values for the form, usualy * the values for the notify feature. */ protected function process() { global $core; $modelid = $this->key; $models = $core->configs->synthesize('formmodels', 'merge'); if (empty($models[$modelid])) { \ICanBoogie\log_error("Unknown model."); return; } $model = $models[$modelid]; $model_class = $model['class']; if (!method_exists($model_class, 'get_defaults')) { \ICanBoogie\log_success("The model doesn't have defaults."); return false; } return call_user_func(array($model_class, 'get_defaults')); }
/** * Try to rescue the exception. * * The rescue process consists in the following steps: * * 1. The operation associated with the exception cannot be retrieved the exception is * re-thrown. * 2. Otherwise, the `ICanBoogie\Operation::rescue` event of class {@link \ICanBoogie\Operation\RescueEvent} * is fired. Event hooks attached to this event may replace the exception or provide a * response. If a response is provided it is returned. * 3. Otherwise, if the exception is not an instance of {@link Failure} the exception is * re-thrown. * 4. Otherwise, if the request is an XHR the response of the operation is returned. * 5. Otherwise, if the operation was forwarded the exception message is logged as an error * and the method returns. * 6. Otherwise, the exception is re-thrown. * * In summary, a failed operation is rescued if a response is provided during the * `ICanBoogie\Operation::rescue` event, or later if the request is an XHR. Although the * rescue of an operation might be successful, the returned response can be an error response. * * @param \Exception $exception The exception to rescue. * @param Request $request The request. * * @return Response|null A response or `null` if the operation was forwarded. * * @throws Failure * @throws \Exception */ public function rescue(\Exception $exception, Request $request) { /* @var $failure Failure */ $failure = null; $operation = $this->retrieve_operation($exception, $request, $failure); # # We try to rescue the exception, the original exception in case of a Failure exception. If # the exception is rescued we return the response, otherwise if the exception is not a # Failure we re-throw the exception. # $response = null; new RescueEvent($operation, $exception, $request, $response); if ($response) { return $response; } if (!$failure) { throw $exception; } # # The exception is a Failure, which means that an exception occurred during # control/validate/process or a Failure was thrown because the response has an error. # # - If the request is an XHR we return the response of the operation. # # - If the operation is forwarded, the response of the actual URL needs to be displayed, # thus we cannot return a response nor re-throw the exception. In that case the message # of the exception is simply logged as an error and the method returns. # # - Otherwise, the exception is re-thrown. # if ($request->is_xhr) { return $operation->response; } if ($operation->is_forwarded) { if ($failure->previous) { \ICanBoogie\log_error($exception->getMessage()); } return null; } throw $exception; }
function doSourceCode($type, $text) { $text = trim($text); switch ($type) { case 'php': return '<pre class="php"><code>' . $this->doSourcePHP($text) . '</code></pre>'; case 'html': return '<pre class="html"><code>' . $this->doSourceHTML($text) . '</code></pre>'; case 'raw': return '<pre><code>' . $this->doSourceRaw($text) . '</code></pre>'; case 'publish': return $this->doSourcePublish($text); } \ICanBoogie\log_error('\\1: unknown source type "\\1"', __FUNCTION__, $type); return $text; }
public function render_cell($descriptor) { global $core; $module_id = $descriptor[Module::T_ID]; try { $module = $core->modules[$module_id]; } catch (\Exception $e) { return '<div class="alert alert-error">' . $e->getMessage() . '</div>'; } $html = ''; $is_installed = false; # EXTENDS $errors = new \ICanBoogie\Errors(); $extends_errors = new \ICanBoogie\Errors(); $n_errors = count($errors); while ($descriptor[Module::T_EXTENDS]) { $extends = $descriptor[Module::T_EXTENDS]; if (empty($core->modules->descriptors[$extends])) { $errors[$module_id] = I18n\t('Requires the %module module which is missing.', array('%module' => $extends)); break; } else { if (!isset($core->modules[$extends])) { $errors[$module_id] = I18n\t('Requires the %module module which is disabled.', array('%module' => $extends)); break; } else { $extends_errors->clear(); $extends_module = $core->modules[$extends]; $extends_is_installed = $extends_module->is_installed($extends_errors); if (count($extends_errors)) { $extends_is_installed = false; } if (!$extends_is_installed) { $errors[$module_id] = I18n\t('Requires the %module module which is disabled.', array('%module' => $extends)); break; } } } $descriptor = $core->modules->descriptors[$extends]; } if ($n_errors != count($errors)) { $html .= '<div class="alert alert-error">' . implode('<br />', (array) $errors[$module_id]) . '</div>'; } else { try { $n_errors = count($errors); $is_installed = $module->is_installed($errors); if (count($errors) != $n_errors) { $is_installed = false; } } catch (\Exception $e) { $errors[$module->id] = I18n\t('Exception with module %module: :message', array('%module' => (string) $module, ':message' => $e->getMessage())); } if ($is_installed) { $html .= I18n\t('Installed'); } else { if ($is_installed === false) { $btn = '<a class="btn btn-danger" href="' . \ICanBoogie\Routing\contextualize("/admin/modules/{$module}/install") . '">' . I18n\t('Install module') . '</a>'; $title = new FormattedString('The module %title is not properly installed', array('title' => $module->title)); \ICanBoogie\log_error("{$title}."); if (isset($errors[$module_id])) { $error = $errors[$module_id]; if (is_array($error)) { $error = implode('</p><p>', $error); } $html .= <<<EOT <div class="alert alert-error alert-block undismissable"> \t<h4 class="alert-heading">{$title}</h4> \t<div class="content"> \t\t<p>{$error}</p> \t</div> \t<div class="alert-actions">{$btn}</div> </div> EOT; } else { $html .= $btn; } } else { $html .= '<em class="not-applicable light">Not applicable</em>'; } } } return $html; }
protected static function get_template_info_callback($html, $parser) { $styles = array(); $contents = array(); # # search css files # preg_match_all('#<link.*type="text/css".*>#', $html, $matches); foreach ($matches[0] as $match) { preg_match_all('#(\\S+)="([^"]+)"#', $match, $attributes_matches, PREG_SET_ORDER); $attributes = array(); foreach ($attributes_matches as $attribute_match) { list(, $attribute, $value) = $attribute_match; $attributes[$attribute] = $value; } if (isset($attributes['media']) && $attributes['media'] != 'screen') { continue; } $styles[] = $attributes['href']; } # # # $tree = $parser->parse($html, \Patron\Engine::PREFIX); //\ICanBoogie\log('tree: \1', array($tree)); # # contents # $contents_collection = \Patron\HTMLParser::collectMarkup($tree, 'page:content'); // \ICanBoogie\log('contents collection: \1', array($contents_collection)); foreach ($contents_collection as $node) { if (isset($node['children'])) { foreach ($node['children'] as $child) { if (!is_array($child)) { continue; } if ($child['name'] != 'with-param') { continue; } $param = $child['args']['name']; // TODO: what about arrays ? we should create a tree to string function $value = ''; foreach ($child['children'] as $cv) { $value .= $cv; } $node['args'][$param] = $value; } } // \ICanBoogie\log('found content: \1', array($node)); $contents[] = $node['args'] + array('editor' => null, 'config' => null, 'description' => null); } # # recurse on templates # global $core; $site = $core->site; $root = $_SERVER['DOCUMENT_ROOT']; $call_template_collection = \Patron\HTMLParser::collectMarkup($tree, 'call-template'); foreach ($call_template_collection as $node) { $template_name = $node['args']['name']; $file = $template_name . '.html'; $path = $site->resolve_path('templates/partials/' . $file); if (!$path) { \ICanBoogie\log_error('Partial template %name not found', array('%name' => $file)); continue; } $template = file_get_contents($root . $path); list($partial_contents, $partial_styles) = self::get_template_info_callback($template, $parser); $contents = array_merge($contents, $partial_contents); if ($partial_styles) { $styles = array_merge($styles, $partial_styles); } } return array($contents, $styles); }
/** * Redirects the request to the first available website to the user if the request matches * none. * * Only online websites are used if the user is a guest or a member. * * @param Dispatcher\BeforeDispatchEvent $event * @param Dispatcher $target */ public static function before_http_dispatcher_dispatch(Dispatcher\BeforeDispatchEvent $event, Dispatcher $target) { global $core; if ($core->site_id) { return; } $request = $event->request; if (!in_array($request->method, array(Request::METHOD_ANY, Request::METHOD_GET, Request::METHOD_HEAD))) { return; } $path = \ICanBoogie\normalize_url_path(\ICanBoogie\Routing\decontextualize($request->path)); if (strpos($path, '/api/') === 0) { return; } try { $query = $core->models['sites']->order('weight'); $user = $core->user; if ($user->is_guest || $user instanceof \Icybee\Modules\Members\Member) { $query->filter_by_status(Site::STATUS_OK); } $site = $query->one; if ($site) { $request_url = \ICanBoogie\normalize_url_path($core->site->url . $request->path); $location = \ICanBoogie\normalize_url_path($site->url . $path); # # we don't redirect if the redirect location is the same as the request URL. # if ($request_url != $location) { $query_string = $request->query_string; if ($query_string) { $location .= '?' . $query_string; } $event->response = new RedirectResponse($location, 302, array('Icybee-Redirected-By' => __CLASS__ . '::' . __FUNCTION__)); return; } } } catch (\Exception $e) { } \ICanBoogie\log_error('You are on a dummy website. You should check which websites are available or create one if none are.'); }
/** * Notify users that a reply to their comment has been posted. * * @param int $commentid */ protected function notify($commentid) { global $core; $form_id = $core->site->metas['comments.form_id']; if (!$form_id) { return; } try { $form = $core->models['forms'][$form_id]; } catch (\Exception $e) { return; } $options = unserialize($form->metas['comments/reply']); if (!$options) { return; } $model = $this->module->model; $comment = $model[$commentid]; # # search previous message for notify # $records = $model->where('nid = ? AND `{primary}` < ? AND (`notify` = "yes" OR `notify` = "author") AND author_email != ?', $comment->nid, $commentid, $comment->author_email)->all; if (!$records) { return; } # # prepare subject and message # $patron = new \Patron\Engine(); $subject = $patron($options['subject'], $comment); $message = $patron($options['template'], $comment); $from = $options['from']; $bcc = $options['bcc']; foreach ($records as $entry) { # # notify only if the author of the node post a comment # if ($entry->notify == 'author' && $comment->uid != $comment->node->uid) { continue; } \ICanBoogie\log('Send notify to %author (email: %email, message n°%commentid, mode: %notify)', array('%author' => $entry->author, '%email' => $entry->author_email, '%commentid' => $entry->commentid, '%notify' => $entry->notify)); $mailer = new Mailer(array(Mailer::T_DESTINATION => $entry->author_email, Mailer::T_FROM => $from, Mailer::T_BCC => $bcc, Mailer::T_MESSAGE => $message, Mailer::T_SUBJECT => $subject, Mailer::T_TYPE => 'plain')); if (!$mailer()) { \ICanBoogie\log_error('Unable to send notify to %author', array('%author' => $entry->author)); continue; } $entry->notify = 'done'; $entry->save(); } }