示例#1
0
 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;
 }
示例#2
0
 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);
 }
示例#3
0
 /**
  * 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;
 }
示例#4
0
 /**
  * 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();
 }
示例#5
0
 /**
  * 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'));
 }
示例#6
0
 /**
  * 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;
 }
示例#7
0
 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;
 }
示例#8
0
    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;
    }
示例#9
0
 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);
 }
示例#10
0
 /**
  * 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.');
 }
示例#11
0
 /**
  * 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();
     }
 }