Esempio n. 1
0
 /**
  * The `control_name` parameter is request.
  *
  * @see ICanBoogie.Operation::validate()
  */
 protected function validate(\ICanBoogie\Errors $errors)
 {
     if (!$this->request['control_name']) {
         $errors['control_name'] = I18n\t('The %identifier is required.', array('identifier' => 'control_name'));
     }
     return true;
 }
Esempio n. 2
0
 public function stat()
 {
     global $core;
     $model = $core->models['contents/rendered'];
     list($count, $size) = $model->select('COUNT(nid) count, SUM(LENGTH(body)) size')->one(\PDO::FETCH_NUM);
     return [(int) $count, I18n\t(':count records<br /><span class="small">:size</span>', [':count' => (int) $count, 'size' => \ICanBoogie\I18n\format_size($size)])];
 }
Esempio n. 3
0
    protected function render_body()
    {
        global $core;
        $rendered_columns_cells = $this->render_columns_cells($this->columns);
        $rows = $this->columns_to_rows($rendered_columns_cells);
        $html = '';
        foreach ($rows as $i => $row) {
            $record = $this->records[$i];
            $title = $record->title;
            $label = new Element('a', array(Element::INNER_HTML => \ICanBoogie\escape($title), 'class' => 'goto-edit', 'title' => I18n\t('Edit this item'), 'href' => \ICanBoogie\Routing\contextualize("/admin/{$record->constructor}/{$record->nid}/edit")));
            $img = $record->thumbnail('$gallery')->to_element(array('title' => $title, 'alt' => $title));
            $html .= <<<EOT
<div class="thumbnailer-wrapper" data-key="{$record->nid}" style="width: 128px;">
\t<a href="{$record->path}" rel="lightbox[]">{$img}</a>
\t{$label}
</div>
EOT;
        }
        $colspan = count($this->columns) + 1;
        return <<<EOT
<tr id="gallery">
\t<td colspan="{$colspan}" class="gallery-inner">
\t\t<div class="gallery-contents">{$html}</div>
\t</td>
</tr>
EOT;
    }
Esempio n. 4
0
 protected function details($path)
 {
     $path = $this['value'];
     list($entry_width, $entry_height) = getimagesize($_SERVER['DOCUMENT_ROOT'] . $path);
     $w = $entry_width;
     $h = $entry_height;
     #
     # if the image is larger then the thumbnail dimensions, we resize the image using
     # the "surface" mode.
     #
     $resized = false;
     if ($w * $h > self::THUMBNAIL_WIDTH * self::THUMBNAIL_HEIGHT) {
         $resized = true;
         $ratio = sqrt($w * $h);
         $w = round($w / $ratio * self::THUMBNAIL_WIDTH);
         $h = round($h / $ratio * self::THUMBNAIL_HEIGHT);
     }
     $this->w = $w;
     $this->h = $h;
     #
     # infos
     #
     $details = array(I18n\t('Image size: {0}×{1}px', array($entry_width, $entry_height)));
     if ($entry_width != $w || $entry_height != $h) {
         $details[] = I18n\t('Display ratio: :ratio%', array(':ratio' => round($w * $h / ($entry_width * $entry_height) * 100)));
     } else {
         $details[] = I18n\t('Displayed as is');
     }
     $details[] = I18n\format_size(filesize($_SERVER['DOCUMENT_ROOT'] . $path));
     return $details;
 }
Esempio n. 5
0
 public function __construct(array $attributes = [])
 {
     global $core;
     $site = $core->site;
     $native = $site->native->language;
     parent::__construct('select', $attributes + [Form::LABEL => 'nativeid', Element::GROUP => 'i18n', Element::DESCRIPTION => I18n\t('nativeid', ['native' => $native, 'language' => $site->language], ['scope' => 'element.description'])]);
 }
Esempio n. 6
0
 protected function process()
 {
     global $core;
     $request = $this->request;
     $core->session->install['user'] = array('username' => $request['username'], 'email' => $request['email'], 'password' => $request['password'], 'language' => $request['language']);
     $this->response->message = I18n\t('panel.user.success');
     return parent::process();
 }
Esempio n. 7
0
 protected function process()
 {
     global $core;
     $request = $this->request;
     $core->session->install['database'] = array('name' => $request['name'], 'username' => $request['username'], 'password' => $request['password'], 'host' => $request['host'], 'prefix' => $request['prefix']);
     $this->response->message = I18n\t('panel.database.success');
     return parent::process();
 }
 protected function get_config_preview()
 {
     global $core;
     $registry = $core->registry;
     $rc = I18n\t("The cache size does not exceed :cache_sizeMb.", array('cache_size' => $registry['thumbnailer.cache_size'] ?: 8));
     $rc .= ' ' . I18n\t("The cache is cleaned every :cleanup_interval minutes.", array('cleanup_interval' => $registry['thumbnailer.cleanup_interval'] ?: 15));
     return $rc;
 }
Esempio n. 9
0
 protected function process()
 {
     global $core;
     $request = $this->request;
     $core->session->install['site'] = array('title' => $request['title'], 'language' => $request['language'], 'timezone' => $request['timezone']);
     $this->response->message = I18n\t('panel.site.success');
     return parent::process();
 }
Esempio n. 10
0
 public function __construct(array $attributes = array())
 {
     global $core;
     $options = array();
     foreach ($core->editors as $id => $editor) {
         $options[$id] = I18n\t($id, array(), array('scope' => 'editor_title'));
     }
     parent::__construct('select', $attributes + array(Element::OPTIONS => $options));
 }
Esempio n. 11
0
 public function render_cell($record)
 {
     $label = $record->username;
     $name = $record->name;
     if ($label != $name) {
         $label .= ' <small>(' . $name . ')</small>';
     }
     return new Element('a', [Element::INNER_HTML => $label, 'class' => 'edit', 'href' => \ICanBoogie\Routing\contextualize("/admin/{$record->constructor}/{$record->uid}/edit"), 'title' => I18n\t('manage.edit')]);
 }
Esempio n. 12
0
 public function __construct(array $attributes = [])
 {
     $login = new LoginForm();
     $password = new NonceRequestForm();
     $password->children['email'][Element::DESCRIPTION] = new A(I18n\t('Cancel', [], ['scope' => 'button']));
     $this->elements['login'] = $login;
     $this->elements['password'] = $password;
     parent::__construct('div', $attributes + [Element::WIDGET_CONSTRUCTOR => 'LoginCombo', 'id' => 'login', 'class' => 'widget-login-combo']);
 }
Esempio n. 13
0
 public static function markup_form(array $args, \Patron\Engine $patron, $template)
 {
     global $core, $document;
     $page = $core->site->resolve_view_target('search/home');
     if (!$page) {
         throw new Exception\Config($core->modules['search']);
     }
     $label = I18n\t('search.label.search');
     $tags = array(Form::VALUES => $_GET, Element::CHILDREN => array('q' => new Searchbox(array(Form::LABEL => $label, 'placeholder' => $label))), 'class' => 'navbar-search', 'method' => \ICanBoogie\HTTP\Request::METHOD_GET, 'action' => $page->url);
     return $template ? new \WdTemplatedForm($tags, $patron($template)) : (string) new Form($tags);
 }
Esempio n. 14
0
 public static function get_vars_stat($regex)
 {
     global $core;
     $n = 0;
     $size = 0;
     foreach ($core->vars->matching($regex) as $pathname => $fileinfo) {
         ++$n;
         $size += $fileinfo->getSize();
     }
     return array($n, I18n\t(':count files<br /><span class="small">:size</span>', array(':count' => $n, 'size' => \ICanBoogie\I18n\format_size($size))));
 }
Esempio n. 15
0
 protected function block_profile()
 {
     global $core;
     $core->document->page_title = I18n\t('My profile');
     $module = $this;
     $user = $core->user;
     $constructor = $user->constructor;
     if ($constructor != $this->id) {
         $module = $core->modules[$user->constructor];
     }
     return $module->getBlock('edit', $user->uid);
 }
Esempio n. 16
0
 /**
  * Only modules which are not used by other modules can be disabled.
  */
 protected function validate(\ICanboogie\Errors $errors)
 {
     global $core;
     if ($this->key) {
         foreach (array_keys($this->key) as $module_id) {
             $n = $core->modules->usage($module_id);
             if ($n) {
                 $errors[] = $errors->format('The module %title cannot be disabled, :count modules are using it.', array('title' => I18n\t($module_id, array(), array('scope' => 'module_title')), ':count' => $n));
             }
         }
     }
     return $errors;
 }
Esempio n. 17
0
 protected function get_children()
 {
     global $core;
     $models = $core->configs->synthesize('formmodels', 'merge');
     $models_options = array();
     if ($models) {
         foreach ($models as $modelid => $model) {
             $models_options[$modelid] = $model['title'];
         }
         asort($models_options);
     }
     $label_default_values = I18n\t('Default values');
     $description_notify = I18n\t('description_notify', array(':link' => '<a href="http://github.com/Weirdog/WdPatron" target="_blank">WdPatron</a>'));
     return array_merge(parent::get_children(), array('modelid' => new Element('select', array(Form::LABEL => 'modelid', Element::REQUIRED => true, Element::OPTIONS => array(null => '') + $models_options, Element::LABEL_POSITION => 'before')), 'before' => $core->editors['rte']->from(array(Form::LABEL => 'before', Element::GROUP => 'messages', 'rows' => 5)), 'after' => $core->editors['rte']->from(array(Form::LABEL => 'after', Element::GROUP => 'messages', 'rows' => 5)), 'complete' => $core->editors['rte']->from(array(Form::LABEL => 'complete', Element::GROUP => 'messages', Element::REQUIRED => true, Element::DESCRIPTION => 'complete', Element::DEFAULT_VALUE => '<p>' . I18n\t('default.complete') . '</p>', 'rows' => 5)), 'is_notify' => new Element(Element::TYPE_CHECKBOX, array(Element::LABEL => 'is_notify', Element::GROUP => 'options', Element::DESCRIPTION => 'is_notify')), 'notify_' => new EmailComposer(array(Element::GROUP => 'options', Element::DEFAULT_VALUE => array('from' => $core->site->email, 'destination' => $core->site->email), 'class' => 'form-horizontal'))));
 }
    public static function create_attachment($entry, $hard_bond = false)
    {
        global $core;
        $hiddens = null;
        $links = array();
        $i = uniqid();
        $size = \ICanBoogie\I18n\format_size($entry->size);
        $preview = null;
        if ($entry instanceof Uploaded) {
            $title = $entry->name;
            $extension = $entry->extension;
            $hiddens .= '<input type="hidden" class="file" name="nodes_attachments[' . $i . '][file]" value="' . \ICanBoogie\escape(basename($entry->location)) . '" />' . PHP_EOL;
            $hiddens .= '<input type="hidden" name="nodes_attachments[' . $i . '][mime]" value="' . \ICanBoogie\escape($entry->mime) . '" />' . PHP_EOL;
            $links = array('<a href="#remove" class="btn btn-warning">' . I18n\t('label.remove') . '</a>');
        } else {
            $fid = $entry->nid;
            $title = $entry->title;
            $extension = substr($entry->path, strrpos($entry->path, '.'));
            $hiddens .= '<input type="hidden" name="nodes_attachments[' . $i . '][fileid]" value="' . $fid . '" />';
            $links = array('<a href="' . \ICanBoogie\Routing\contextualize('/admin/files/' . $fid . '/edit') . '" class="btn"><i class="icon-pencil"></i> ' . I18n\t('label.edit') . '</a>', '<a href="' . Operation::encode('files/' . $fid . '/download') . '" class="btn"><i class="icon-download-alt"></i> ' . I18n\t('label.download') . '</a>', $hard_bond ? '<a href="#delete" class="btn btn-danger"><i class="icon-remove icon-white"></i> ' . I18n\t('Delete file') . '</a>' : '<a href="#remove" class="btn btn-warning"><i class="icon-remove"></i> ' . t('Break link') . '</a>');
            $node = $core->models['nodes'][$entry->nid];
            if ($node instanceof \Icybee\Modules\Images\Image) {
                $preview = $node->thumbnail('$icon')->to_element(array('data-popover-image' => $node->thumbnail('$popup')->url));
            }
        }
        $title = \ICanBoogie\escape($title);
        $links = empty($links) ? '' : ' &ndash; ' . implode(' ', $links);
        if ($extension) {
            $extension = '<span class="lighter">(' . $extension . ')</span>';
        }
        return <<<EOT
<li>
\t<span class="handle">↕</span>{$preview}<input type="text" name="nodes_attachments[{$i}][title]" value="{$title}" />
\t<span class="small">
\t\t<span class="info light">{$size} {$extension}</span> {$links}
\t</span>

\t{$hiddens}
</li>
EOT;
    }
Esempio n. 19
0
 protected function render_inner_html()
 {
     global $core;
     $slug = $this->slug_el['value'];
     $tease = '<strong>Slug&nbsp;:</strong> ';
     $tease .= '<a href="#slug-edit" title="' . I18n\t('edit', [], ['scope' => 'titleslugcombo.element']) . '">' . ($slug ? \ICanBoogie\escape(\ICanBoogie\shorten($slug)) : $this->dataset['auto-label']) . '</a>';
     $tease .= ' <span>&ndash; <a href="slug-delete" class="warn">' . I18n\t('reset', [], ['scope' => 'titleslugcombo.element']) . '</a></span>';
     $this->slug_tease->inner_html = $tease;
     $rc = parent::render_inner_html();
     $nid = $this[self::T_NODEID];
     if ($nid) {
         $node = $core->models['nodes'][$nid];
         if ($node && $node->url && $node->url[0] != '#') {
             $url = $node->url;
             $url_label = \ICanBoogie\shorten($url, 64);
             $rc .= '<p class="small light">';
             $rc .= '<strong>URL&nbsp;:</strong> ' . $url_label;
         }
     }
     return $rc;
 }
Esempio n. 20
0
 protected function block_install($module_id)
 {
     global $core;
     if (!$core->user->has_permission(self::PERMISSION_ADMINISTER, $this)) {
         return '<div class="alert alert-error">' . I18n\t('You don\'t have enought privileges to install packages.') . '</div>';
     }
     if (empty($core->modules[$module_id])) {
         return '<div class="alert alert-error">' . I18n\t('The module %module_id does not exists.', array('%module_id' => $module_id)) . '</div>';
     }
     $errors = new \ICanBoogie\Errors();
     $module = $core->modules[$module_id];
     $is_installed = $module->is_installed($errors);
     if ($is_installed && !count($errors)) {
         return '<div class="alert alert-error">' . I18n\t('The module %module is already installed', array('%module' => $module_id)) . '</div>';
     }
     $errors->clear();
     $is_installed = $module->install($errors);
     if (!$is_installed || count($errors)) {
         return '<div class="alert alert-error">' . I18n\t('Unable to install the module %module', array('%module' => $module_id)) . '</div>';
     }
     return '<div class="alert alert-success">' . I18n\t('The module %module has been installed. <a href="' . $core->site->path . '/admin/' . $this . '">Retourner à la liste.</a>', array('%module' => $module_id)) . '</div>';
 }
Esempio n. 21
0
    protected function render_panels(array $panels)
    {
        $colunms = [[], []];
        // config sign: ⚙
        foreach ($panels as $id => $descriptor) {
            try {
                if (empty($descriptor['callback'])) {
                    continue;
                }
                $contents = call_user_func($descriptor['callback']);
            } catch (\Exception $e) {
                $contents = \Brickrouge\render_exception($e);
            }
            if (!$contents) {
                continue;
            }
            $title = I18n\t($id, [], ['scope' => 'dashboard.title', 'default' => $descriptor['title']]);
            $panel = <<<EOT
<div class="panel" id="{$id}">
\t<div class="panel-title">{$title}</div>
\t<div class="panel-contents">{$contents}</div>
</div>
EOT;
            $colunms[$descriptor['column']][] = $panel;
        }
        $html = '';
        foreach ($colunms as $i => $panels) {
            $panels = implode(PHP_EOL, $panels);
            $html .= <<<EOT
<div class="column">
\t{$panels}
\t<div class="panel-holder">&nbsp;</div>
</div>
EOT;
        }
        return $html;
    }
Esempio n. 22
0
 protected function create_control_scope()
 {
     global $core;
     $options = array();
     $modules = $core->modules;
     foreach ($core->modules->descriptors as $module_id => $descriptor) {
         if (!isset($core->modules[$module_id])) {
             continue;
         }
         if (!$modules->is_extending($module_id, 'contents') && !$modules->is_extending($module_id, 'pages')) {
             continue;
         }
         $options[$module_id] = I18n\t($descriptor[Module::T_TITLE], array(), array('scope' => 'module_title'));
     }
     $options['google'] = '<em>Google</em>';
     asort($options);
     #
     $ns = $this->module->flat_id;
     $scope = explode(',', $core->site->metas[$ns . '.scope']);
     $scope = array_combine($scope, array_fill(0, count($scope), true));
     $sorted_options = array();
     foreach ($scope as $module_id => $dummy) {
         if (empty($options[$module_id])) {
             continue;
         }
         $sorted_options[$module_id] = $options[$module_id];
     }
     $sorted_options += $options;
     $el = '<ul class="sortable self-handle">';
     foreach ($sorted_options as $module_id => $label) {
         $el .= '<li>';
         $el .= new Element('input', array(Element::LABEL => $label, 'name' => "local[{$ns}.scope][{$module_id}]", 'type' => 'checkbox', 'checked' => !empty($scope[$module_id])));
         $el .= '</li>';
     }
     $el .= '</ul>';
     return new Element('div', array(Form::LABEL => 'scope', Element::INNER_HTML => $el, Element::DESCRIPTION => 'scope'));
 }
Esempio n. 23
0
 public function __invoke(Request $request)
 {
     global $core;
     try {
         $request->context->page = $page = $this->resolve_page($request);
         if (!$page) {
             return;
         }
         if ($page instanceof Response) {
             return $page;
         }
         return $this->resolve_response($page, $request);
     } catch (\Exception $e) {
         $code = $e->getCode();
         $pathname = \ICanBoogie\DOCUMENT_ROOT . "protected/all/templates/{$code}.html";
         if (file_exists($pathname)) {
             $request->context->page = $page = Page::from(['siteid' => $core->site_id, 'title' => I18n\t($e->getCode(), [], ['scope' => 'exception']), 'body' => I18n\t($e->getMessage(), [], ['scope' => 'exception'])]);
             $template = file_get_contents($pathname);
             $engine = $this->resolve_engine($template);
             return new Response($engine($template, $page), $code);
         }
         throw $e;
     }
 }
Esempio n. 24
0
 protected function alter_context(\BlueTihi\Context $context, Query $query, array $conditions)
 {
     $count = $query->count;
     $context['count'] = I18n\t('comments.count', array(':count' => $count));
     return $context;
 }
Esempio n. 25
0
    public static function dashboard_last()
    {
        global $core;
        if (empty($core->modules['comments'])) {
            return;
        }
        $document = $core->document;
        $document->css->add('../public/admin.css');
        $model = $core->models['comments'];
        $entries = $model->where('(SELECT 1 FROM {prefix}nodes WHERE nid = comment.nid AND (siteid = 0 OR siteid = ?)) IS NOT NULL', $core->site_id)->order('created DESC')->limit(5)->all;
        if (!$entries) {
            return '<p class="nothing">' . I18n\t('No record yet') . '</p>';
        }
        $model->including_node($entries);
        $rc = '';
        $context = $core->site->path;
        foreach ($entries as $entry) {
            $url = $entry->url;
            $author = \ICanBoogie\escape($entry->author);
            if ($entry->author_url) {
                $author = '<a class="author" href="' . \ICanBoogie\escape($entry->author_url) . '">' . $author . '</a>';
            } else {
                $author = '<strong class="author">' . $author . '</strong>';
            }
            $excerpt = \ICanBoogie\shorten(strip_tags((string) html_entity_decode($entry, ENT_COMPAT, \ICanBoogie\CHARSET)), 140);
            $target_url = $entry->node->url;
            $target_title = \ICanBoogie\escape(\ICanBoogie\shorten($entry->node->title));
            $image = \ICanBoogie\escape($entry->author_icon);
            $entry_class = $entry->status == 'spam' ? 'spam' : '';
            $url_edit = "{$context}/admin/comments/{$entry->commentid}/edit";
            $url_delete = "{$context}/admin/comments/{$entry->commentid}/delete";
            $date = \ICanBoogie\I18n\format_date($entry->created, 'dd MMM');
            $txt_delete = I18n\t('Delete');
            $txt_edit = I18n\t('Edit');
            $txt_display_associated_node = I18n\t('Display associated node');
            $rc .= <<<EOT
<div class="record {$entry_class}">
\t<div class="options">
\t\t<img src="{$image}&amp;s=48" alt="" />
\t</div>

\t<div class="contents">
\t\t<div class="head">
\t\t{$author}
\t\t<span class="date light">{$date}</span>
\t\t</div>

\t\t<div class="body"><a href="{$url}">{$excerpt}</a></div>

\t\t<div class="actions light">
\t\t\t<a href="{$url_edit}">{$txt_edit}</a>, <a href="{$url_delete}" class="danger">{$txt_delete}</a> − <a href="{$target_url}" class="target" title="{$txt_display_associated_node}">{$target_title}</a>
\t\t</div>
\t</div>
</div>
EOT;
        }
        $count = $model->joins(':nodes')->where('siteid = 0 OR siteid = ?', $core->site_id)->count;
        $txt_all_comments = I18n\t('comments.count', array(':count' => $count));
        $rc .= <<<EOT
<div class="panel-footer"><a href="{$context}/admin/comments">{$txt_all_comments}</a></div>
EOT;
        return $rc;
    }
Esempio n. 26
0
 protected function get_placeholder(array $options)
 {
     $search = $options['search'];
     return '<div class="no-response alert undissmisable">' . ($search ? I18n\t('Aucun enregistrement ne correspond aux termes de recherche spécifiés (%search)', ['%search' => $search]) : I18n\t("Il n'y a pas d'enregistrements")) . '</div>';
 }
Esempio n. 27
0
    foreach ($constructors as $constructor) {
        if ($constructor == 'google') {
            list($entries, $count) = query_google($search, 0, $_home_limit);
        } else {
            $model = $core->models[$constructor];
            if ($model instanceof PagesModel) {
                list($entries, $count) = query_pages($search, 0, $_home_limit);
            } else {
                list($entries, $count) = query_contents($constructor, $search, 0, $_home_limit);
            }
        }
        echo make_set($constructor, $entries, $count, $search);
    }
} else {
    if (!in_array($_GET['constructor'], $constructors)) {
        echo I18n\t("Le constructeur %constructor n'est pas supporté pour la recherche", array('%constructor' => $_GET['constructor']));
    } else {
        $constructor = $_GET['constructor'];
        if ($constructor == 'google') {
            list($entries, $count) = query_google($search, $position, $_list_limit);
        } else {
            $model = $core->models[$constructor];
            if ($model instanceof PagesModel) {
                list($entries, $count) = query_pages($search, $position, $_list_limit);
            } else {
                if ($model instanceof ContentsModel) {
                    list($entries, $count) = query_contents($constructor, $search, $position, $_list_limit);
                } else {
                    echo "<p>Don't know how to query: <em>{$constructor}</em></p>";
                }
            }
Esempio n. 28
0
 public static function get()
 {
     return new static(I18n\t("Before we can continue, you need to check the following things:"), array('core_config' => new CoreConfigRequirement()));
 }
Esempio n. 29
0
 /**
  * The `node:attachments` markup can be used to render a node attachments.
  *
  * There is actually two modes for rendering the attachments, depending on their number:
  *
  * - No attachment: nothing is rendered.
  *
  * - One attachment:
  *
  *     <div class="node-attachments">
  *     <p><a href="#{@url('download')}">#{t:Download attachment}</a>
  *     <span class="metas">(#{@extension} – #{@size.format_size()}</span></p>
  *     </div>
  *
  * - More than on attachment:
  *
  *     <div class="node-attachments">
  *     <h5>#{t:Attached files}</h5>
  *     <ul>
  *     <p:foreach>
  *     <p><a href="#{@url('download')}">#{@label}</a>
  *     <span class="metas">(#{@extension} – #{@size.format_size()}</span></p>
  *     </p:foreach>
  *     </ul>
  *     </div>
  *
  * Use the I18n scope to translate "Download attachment" or "Attachments" to module specific
  * translations such as "Download press release" or "Press release attachments".
  *
  * Attachments are created using the "resources.files.attached" module.
  *
  * @param array $args
  * @param Patron\Engine $patron
  * @param string|null $template
  *
  * @return string|null The rendered attached file(s), or null if no files were attached.
  */
 public static function markup_node_attachments(array $args = array(), \Patron\Engine $patron, $template)
 {
     $target = $patron->context['this'];
     $files = $target->attachments;
     if (!$files) {
         return;
     }
     $rc = '<div class="node-attachments">';
     if (count($files) == 1) {
         $file = $files[0];
         $rc .= '<p>' . self::make_link($file, I18n\t('Download attachment')) . '</p>';
     } else {
         $rc .= '<h5>' . I18n\t('Attachments') . '</h5>';
         $rc .= '<ul>';
         foreach ($files as $file) {
             $rc .= '<li>' . self::make_link($file) . '</li>';
         }
         $rc .= '</ul>';
     }
     return $rc . '</div>';
 }
Esempio n. 30
0
 protected function render($expression)
 {
     return I18n\t($expression);
 }