示例#1
0
 /**
  * Validate fields values
  *
  * @return bool
  */
 protected function validate()
 {
     foreach ($this->getTableColumns() as $name => $attr) {
         // Get field label
         $label = $this->getFieldLabel($name);
         if (is_null($this->{$name}) || '' === $this->{$name}) {
             // Check required
             if (true === $attr['required']) {
                 if (null !== $attr['default']) {
                     $this->{$name} = $attr['default'];
                 } else {
                     $this->setError($name, I18n::__('The field %s is required.', '<strong>' . $label . '</strong>'));
                 }
             }
         }
         if (!is_null($this->{$name}) && '' !== $this->{$name}) {
             // Check length
             if (!\sJo\Data\Validate::is($attr['type'], $this->{$name}, $attr['length'], $attr['values'])) {
                 $this->setError($name, I18n::__('The field %s must be %s type and have maximum size %s.', '<strong>' . $label . '</strong>', '<strong>' . $attr['type'] . '</strong>', '<strong>' . $attr['length'] . '</strong>'));
             }
             // Check unique
             if (true === $attr['unique']) {
                 $exists = $this->db()->value($this->getPrimaryKey(), array($this->getPrimaryKey() => array('value' => $this->getPrimaryValue(), 'operator' => '!='), $name => $this->{$name}));
                 if ($exists) {
                     $this->setError($name, I18n::__('This %s already exists.', '<strong>' . $label . '</strong>'));
                 }
             }
         }
     }
     return !$this->hasErrors();
 }
示例#2
0
文件: Session.php 项目: johnstyle/sjo
 /**
  * @return bool
  */
 public static function start()
 {
     if (!self::$initialised) {
         session_cache_limiter('');
         ini_set('session.use_cookies', 1);
         if (version_compare(phpversion(), '5.4.0', '>=')) {
             session_register_shutdown();
         } else {
             register_shutdown_function('session_write_close');
         }
         self::$initialised = true;
     }
     if (session_status() === PHP_SESSION_DISABLED) {
         Exception::error(Lib\I18n::__('PHP sessions are disabled.'));
     }
     if (session_status() === PHP_SESSION_ACTIVE) {
         return true;
     }
     if (ini_get('session.use_cookies') && headers_sent($file, $line)) {
         Exception::error(Lib\I18n::__('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line));
     }
     if (!session_start()) {
         Exception::error(Lib\I18n::__('Failed to start the session.'));
     }
     self::$reference =& $_SESSION;
     return true;
 }
示例#3
0
 /**
  * @param int $code
  *
  * @return string
  */
 private function message($code)
 {
     switch ($code) {
         case UPLOAD_ERR_INI_SIZE:
             $message = I18n::__('The uploaded file exceeds the upload_max_filesize directive in php.ini');
             break;
         case UPLOAD_ERR_FORM_SIZE:
             $message = I18n::__('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form');
             break;
         case UPLOAD_ERR_PARTIAL:
             $message = I18n::__('The uploaded file was only partially uploaded');
             break;
         case UPLOAD_ERR_NO_FILE:
             $message = I18n::__('No file was uploaded');
             break;
         case UPLOAD_ERR_NO_TMP_DIR:
             $message = I18n::__('Missing a temporary folder');
             break;
         case UPLOAD_ERR_CANT_WRITE:
             $message = I18n::__('Failed to write file to disk');
             break;
         case UPLOAD_ERR_EXTENSION:
             $message = I18n::__('File upload stopped by extension');
             break;
         default:
             $message = I18n::__('Unknown upload error');
             break;
     }
     return $message;
 }
示例#4
0
文件: Entity.php 项目: johnstyle/sjo
 public function __unset($name)
 {
     if (!$this->__isset($name)) {
         Exception::error(I18n::__('Property %s->%s does not exist.', get_called_class(), $name));
     }
     unset($this->{$name});
 }
示例#5
0
文件: Event.php 项目: johnstyle/sjo
 /**
  * Enregistrement des actions
  *
  * @param string $name Nom de l'événement
  * @param callable $callback Action à executer
  * @param int $priority Priorité de l'action
  * @return void
  */
 public static function register($name, $callback, $priority = 10)
 {
     if (!is_callable($callback)) {
         Exception::error(I18n::__('The second parameter must be a function'));
     }
     self::$registered[$name][$priority][] = $callback;
 }
示例#6
0
 public static function check($classes)
 {
     foreach ($classes as $class) {
         if (!in_array($class, self::$requiredClasses)) {
             Exception::error(Lib\I18n::__('Class %s is required.', $class));
         }
     }
 }
示例#7
0
文件: http403.php 项目: johnstyle/sjo
 public function __initView()
 {
     http_response_code(403);
     if (!$this->message) {
         $this->message = Libs\I18n::__('From htaccess');
     }
     Logger::getInstance()->error('Error 403: {message}', array('message' => $this->message));
 }
示例#8
0
文件: Closure.php 项目: johnstyle/sjo
 function __call($method, $args)
 {
     if (isset($this->methods[$method])) {
         return call_user_func_array($this->methods[$method], $args);
     } else {
         Exception::error(I18n::__('Unknow method %s', $method));
     }
 }
示例#9
0
 private static function isRegistered($name = null, $exception = true)
 {
     if (isset(self::$registry[$name])) {
         return true;
     } elseif ($exception) {
         Exception::error(I18n::__('%s element %s is nor registered.', __CLASS__, $name));
     }
     return false;
 }
示例#10
0
文件: Router.php 项目: johnstyle/sjo
 public static function __callStatic($method, array $args = null)
 {
     if (preg_match("#^(link)([A-Z][a-z]+)\$#", $method, $match)) {
         switch ($match[1]) {
             case 'link':
                 return call_user_func_array('self::link', array_merge(array($match[2]), $args));
                 break;
         }
     }
     Exception::error(Lib\I18n::__('Unknow method %s', __CLASS__ . '::' . $method));
     return false;
 }
示例#11
0
文件: Module.php 项目: johnstyle/sjo
 public static function getClass($module, $className)
 {
     $class = '\\Module\\' . $module . '\\' . ltrim($className, '\\');
     $defaultClass = '\\sJo' . $class;
     if (class_exists($class)) {
         if (!get_parent_class($class) == $defaultClass) {
             Exception::error(Lib\I18n::__('Classe %s is not extended to %s.', $class, $defaultClass));
         }
     } else {
         $class = $defaultClass;
     }
     return $class;
 }
示例#12
0
文件: Upload.php 项目: johnstyle/sjo
 /**
  * @throws UploadException
  * @return bool
  */
 public function isSecure()
 {
     if (!Request::env('FILES')->{$this->requestName}->tmp_name->val()) {
         throw new UploadException(I18n::__('The file does not exist.'));
     }
     if (!Request::env('FILES')->{$this->requestName}->error->eq(UPLOAD_ERR_OK)) {
         throw new UploadException(null, Request::env('FILES')->{$this->requestName}->error->val());
     }
     if (Request::env('FILES')->{$this->requestName}->size->val() < static::MIN_FILE_SIZE) {
         throw new UploadException(I18n::__('The file is too small.'));
     }
     if (Request::env('FILES')->{$this->requestName}->size->val() > static::MAX_FILE_SIZE) {
         throw new UploadException(I18n::__('The file is too large.'));
     }
     if (!in_array(Request::env('FILES')->{$this->requestName}->type->val(), $this->fileTypes)) {
         throw new UploadException(I18n::__('The file is not in the correct format.'));
     }
     return true;
 }
示例#13
0
文件: Auth.php 项目: johnstyle/sjo
 public function signin()
 {
     if (Request::env('POST')->email->exists()) {
         if (Request::env('POST')->password->exists()) {
             if ($id = self::model()->exists(Request::env('POST')->email->val(), Request::env('POST')->password->val())) {
                 Logger::getInstance()->info('Signin {admin}', array('admin' => Request::env('POST')->email->val()));
                 self::model()->session()->id = $id;
                 self::model()->session()->token = Token::get($id);
                 $url = SJO_BASEHREF;
                 if (preg_match('#^(\\./|/)#', Request::env('GET')->redirect->val())) {
                     $url = Request::env('GET')->redirect->val();
                 }
                 Http::redirect($url);
             } else {
                 Alert::set(Lib\I18n::__('Les informations de connexion sont incorrects'));
             }
         } else {
             Alert::set(Lib\I18n::__('Veuillez renseigner votre mot de passe'));
         }
     } else {
         Alert::set(Lib\I18n::__('Veuillez renseigner votre identifiant'));
     }
 }
示例#14
0
文件: Image.php 项目: johnstyle/sjo
 /**
  * @param $dest
  *
  * @throws \sJo\File\UploadException
  * @return bool
  */
 public function copy($dest)
 {
     $src = Request::env('FILES')->{$this->requestName}->tmp_name->val();
     list($width, $height, $type) = getimagesize($src);
     $newWidth = $width;
     $newHeight = $height;
     $source = null;
     switch ($type) {
         case IMG_GIF:
             $source = imagecreatefromgif($src);
             break;
         case IMG_JPG:
             $source = imagecreatefromjpeg($src);
             break;
         case IMG_PNG:
             $source = imagecreatefrompng($src);
             break;
     }
     if (is_null($source)) {
         throw new UploadException(I18n::__('Error image mime'));
     }
     if ($height > self::IMAGE_MAX_HEIGHT) {
         $newWidth = self::IMAGE_MAX_HEIGHT / $height * $width;
         $newHeight = self::IMAGE_MAX_HEIGHT;
     }
     if ($width > self::IMAGE_MAX_WIDTH) {
         $newHeight = self::IMAGE_MAX_WIDTH / $width * $height;
         $newWidth = self::IMAGE_MAX_WIDTH;
     }
     $img = imagecreatetruecolor($newWidth, $newHeight);
     imagecopyresampled($img, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
     if (!imagejpeg($img, $dest, static::IMAGE_QUALITY)) {
         throw new UploadException(I18n::__('Error image create.'));
     }
     return true;
 }
示例#15
0
文件: PDOCore.php 项目: johnstyle/sjo
 /**
  * Créé et retourne l'objet courrant
  *
  * @access public
  * @static
  * @param int $id
  * @return static
  */
 public static function getInstance($id = 0)
 {
     if (isset(self::$auth[$id])) {
         return static::SingletonGetInstance(self::$auth[$id], $id);
     } else {
         Exception::error(Lib\I18n::__('Drivers Unknow Auth ID %s.', $id));
     }
     return false;
 }
示例#16
0
文件: http404.php 项目: johnstyle/sjo
        h2{font-weight:300;font-size:3em;color:#afafaf}
        h3{font-weight:300;font-size:2em;margin-bottom:5px}
        p{font-weight:300;font-size:1.3em;line-height:1.5}
        #error{padding-bottom:30px;margin-bottom:50px}
        #message{background:#e0e0e0;padding:20px 0;margin-top:25px}
        @media screen and (max-width: 640px) {
            body{font-size:12px}
        }
    </style>
</head>
<body>
    <div id="error">
        <h1>404</h1>
        <h2><?php 
Lib\I18n::_e('Page Not Found!');
?>
</h2>
    </div>
    <div id="message">
        <h3><?php 
Lib\I18n::_e('We Are Sory');
?>
</h3>
        <p><?php 
Lib\I18n::_e('This could be the result of the page being removed,
         the name being changed or the page being temporarily unavailable.');
?>
</p>
    </div>
</body>
</html>
示例#17
0
文件: http403.php 项目: johnstyle/sjo
        h1{font-weight:300;font-size:15em;color:#a0a0a0}
        h2{font-weight:300;font-size:3em;color:#afafaf}
        h3{font-weight:300;font-size:2em;margin-bottom:5px}
        p{font-weight:300;font-size:1.3em;line-height:1.5}
        #error{padding-bottom:30px;margin-bottom:50px}
        #message{background:#e0e0e0;padding:20px 0;margin-top:25px}
        @media screen and (max-width: 640px) {
            body{font-size:12px}
        }
    </style>
</head>
<body>
    <div id="error">
        <h1>403</h1>
        <h2><?php 
Lib\I18n::_e('Forbidden!');
?>
</h2>
    </div>
    <div id="message">
        <h3><?php 
Lib\I18n::_e('We Are Sory');
?>
</h3>
        <p><?php 
Lib\I18n::_e('You do not have permission to access this page.');
?>
</p>
    </div>
</body>
</html>
示例#18
0
文件: Manager.php 项目: johnstyle/sjo
 public function index()
 {
     Helper\Menu::addRegistry('main', array(Helper\Link::create(array('elements' => I18n::__('Create admin'), 'attributes' => array('class' => 'bg-success plus', 'href' => Router::linkBack('Admin/Manager::edit'))))));
 }
示例#19
0
文件: index.php 项目: johnstyle/sjo
<?php

use sJo\Module\Admin\Model\Admin;
use sJo\View\Helper;
use sJo\Libraries as Lib;
Helper\Panel::create(array('col' => 6, 'title' => Lib\I18n::__('List of admins'), 'class' => 'panel-primary', 'elements' => Helper\Table::create(array('tbody' => Admin::getInstance(), 'actions' => array('edit', 'delete')))))->render();
示例#20
0
文件: Form.php 项目: johnstyle/sjo
 /**
  * @return bool
  */
 protected function validateForm()
 {
     foreach ($this->getFormFields() as $name => $attr) {
         // Get field label
         $label = $this->getFieldLabel($name);
         if (isset($attr['validate'])) {
             if (Validate::isCallable($attr['validate'])) {
                 call_user_func($attr['validate'], $attr, $name, $label);
             } elseif (preg_match("#^:([[:alnum:]]+)\$#", $attr['validate'], $match)) {
                 if (Request::env('POST')->{$name}->val() !== Request::env('POST')->{$match[1]}->val()) {
                     $this->setError($name, I18n::__('The field %s must be identical to %s.', '<strong>' . $label . '</strong>', '<strong>' . $this->getFieldLabel($match[1]) . '</strong>'));
                 }
             }
         }
     }
     return !$this->hasErrors();
 }
示例#21
0
文件: Loader.php 项目: johnstyle/sjo
 public function display()
 {
     $render = null;
     if (Router::$method) {
         switch (Request::env('GET')->content_type->val()) {
             case 'json':
                 header('Content-type:application/json; charset=' . SJO_CHARSET);
                 if (method_exists(Router::$controllerClass, Router::$method)) {
                     if (Token::has()) {
                         echo json_encode($this->instance->{Router::$method}());
                     } else {
                         $this->ErrorDocument('http403', Lib\I18n::__('Warning ! Prohibited queries.'));
                     }
                 }
                 exit;
                 break;
             default:
                 header('Content-type:text/html; charset=' . SJO_CHARSET);
                 if (method_exists(Router::$controllerClass, Router::$method)) {
                     if (Request::env('POST')->exists()) {
                         if (Token::has()) {
                             $render = $this->instance->{Router::$method}();
                         } else {
                             $this->ErrorDocument('http403', Lib\I18n::__('Warning ! Prohibited queries.'));
                         }
                     } else {
                         $render = $this->instance->{Router::$method}();
                     }
                 }
                 break;
         }
     }
     $this->event('loadedView');
     $this->view->display($render);
     $this->event('displayedView');
 }
示例#22
0
文件: Dom.php 项目: johnstyle/sjo
 protected final function inc(array $args)
 {
     $closure = new Closure();
     foreach ($args as $name => $value) {
         if (!in_array($name, array('attributes'))) {
             $closure->{$name} = $value;
         }
     }
     $closure->attributes = function (array $attributes = array()) use($args) {
         if (!isset($args['attributes'])) {
             return null;
         }
         $output = '';
         foreach ($attributes as $name => $value) {
             if (isset($args['attributes'][$name])) {
                 $args['attributes'][$name] .= ' ' . $value;
             } else {
                 $args['attributes'][$name] = $value;
             }
         }
         foreach ($args['attributes'] as $name => $value) {
             if (!Validate::isEmpty($value)) {
                 switch ($name) {
                     case 'data':
                         foreach ($value as $subname => $subvalue) {
                             $output .= ' ' . $name . '-' . $subname . '="' . trim($subvalue) . '"';
                         }
                         break;
                     default:
                         $output .= ' ' . $name . '="' . trim($value) . '"';
                         break;
                 }
             }
         }
         return $output;
     };
     $closure->attribute = function ($name) use($args) {
         if (!isset($args['attributes'])) {
             return null;
         }
         return isset($args['attributes'][$name]) ? $args['attributes'][$name] : null;
     };
     $filename = $this->getTplFile();
     if (file_exists($filename)) {
         ob_start();
         $closure->inc($filename);
         return ob_get_clean();
     } else {
         Exception::error(I18n::__('helper %s do not exists.', $filename . '.php'));
     }
     return false;
 }
示例#23
0
文件: Table.php 项目: johnstyle/sjo
 public function setElement($element)
 {
     $head = array();
     $instance = null;
     if (is_object($element['tbody']) && method_exists($element['tbody'], 'db')) {
         $instance = $element['tbody'];
         $element['tbody'] = $instance->db()->results();
     }
     if ($element['thead'] === null && is_array($element['tbody'])) {
         $thead = array();
         foreach ($element['tbody'] as $line) {
             foreach ($line as $name => $value) {
                 if (!in_array($name, $thead)) {
                     $thead[] = $name;
                 }
             }
         }
         $element['thead'] = $thead;
         unset($thead);
     }
     if (is_array($element['thead'])) {
         $arrayThead = array();
         foreach ($element['thead'] as $key => &$thead) {
             if (!is_array($thead)) {
                 if (!Validate::isInt($key)) {
                     $thead = array('name' => $key, 'label' => $thead);
                 } else {
                     $thead = array('name' => $thead);
                 }
             }
             $thead = Lib\Arr::extend(array('name' => $key, 'callback' => null, 'align' => null, 'label' => ucfirst(isset($thead['name']) ? $thead['name'] : $key)), $thead);
             $head[] = $thead['name'];
             $arrayThead[$thead['name']] = $thead;
         }
         $element['thead'] = $arrayThead;
     }
     if (is_array($element['tbody'])) {
         if ($element['actions']) {
             if (is_array($element['thead'])) {
                 $element['thead']['actions'] = array('name' => 'actions', 'label' => Lib\I18n::__('Actions'), 'align' => 'right');
             }
             foreach ($element['tbody'] as &$line) {
                 $line->actions = '';
                 foreach ($element['actions'] as $action => $options) {
                     if (!is_array($options)) {
                         $action = $options;
                         $options = array();
                     }
                     $options = Lib\Arr::extend(array('interface' => Router::$interface, 'controller' => null, 'href' => null, 'icon' => null), $options);
                     if (!$options['href']) {
                         $options['href'] = Router::link($options['interface'], $options['controller'], array('method' => $action, $instance->getPrimaryKey() => $line->{$instance->getPrimaryKey()}));
                     }
                     if (!$options['icon']) {
                         switch ($action) {
                             case 'delete':
                                 $options['icon'] = 'trash';
                                 break;
                             case 'update':
                                 $options['icon'] = 'edit';
                                 break;
                             case 'create':
                                 $options['icon'] = 'plus';
                                 break;
                             default:
                                 $options['icon'] = $action;
                                 break;
                         }
                     }
                     $line->actions .= self::createStatic('Link', array_merge(array('icon' => $options['icon']), $options))->html();
                 }
             }
         }
         if (count($head)) {
             foreach ($element['tbody'] as &$line) {
                 foreach ($line as $name => $value) {
                     if (!in_array($name, $head)) {
                         unset($line->{$name});
                         continue;
                     }
                     if (isset($element['thead'][$name]['callback'])) {
                         $line->{$name} = call_user_func($element['thead'][$name]['callback'], $line->{$name});
                     }
                 }
             }
         }
     }
     return $element;
 }
示例#24
0
文件: edit.php 项目: johnstyle/sjo
<?php

use sJo\Module\Admin\Model\Admin;
use sJo\Loader\Router;
use sJo\View\Helper;
use sJo\Libraries as Lib;
Helper\Panel::create(array('col' => 6, 'title' => Admin::getInstance()->getPrimaryValue() ? Lib\I18n::__('Edit admin') : Lib\I18n::__('Create admin'), 'class' => Admin::getInstance()->getPrimaryValue() ? 'panel-primary' : 'panel-success', 'elements' => Helper\Fieldset::create(array(Helper\Token::create(Router::getToken()), Helper\Input::create(array('type' => 'email', 'name' => 'email', 'label' => Lib\I18n::__('Email address'), 'placeholder' => Lib\I18n::__('Enter email'), 'value' => Admin::getInstance()->request('email'))), Helper\Input::create(array('type' => 'text', 'name' => 'name', 'label' => Lib\I18n::__('Name'), 'placeholder' => Lib\I18n::__('Enter name'), 'value' => Admin::getInstance()->request('name'))))), 'footer' => Helper\ButtonGroup::create(array('class' => 'pull-right', 'elements' => array(Helper\Button::create(array('name' => 'saveAndStay', 'value' => Lib\I18n::__('Save and stay'))), Helper\Button::create(array('name' => 'saveAndCreate', 'value' => Lib\I18n::__('Save and create new'), 'class' => 'btn-warning')), Helper\Button::create(array('value' => Lib\I18n::__('Save and back to list'), 'class' => 'btn-primary')))))))->render();
示例#25
0
文件: Auth.php 项目: johnstyle/sjo
?>
" />
    <title><?php 
Lib\I18n::_e('Authentification');
?>
</title>
    <meta name="description" content="<?php 
Lib\I18n::_e('Authentification');
?>
">
    <?php 
if (Helper\Style::hasRegistry()) {
    ?>
        <?php 
    Helper\Style::applyRegistry();
    ?>
    <?php 
}
?>
    <style type="text/css">
        body{background:#333}
        form{background:#fff;width:300px;margin:150px auto 0;padding:0 20px 20px;border:5px solid #000;border-radius:10px;box-shadow:0 0 10px #000}
    </style>
</head>
<body>

<?php 
Helper\Form::create(array(Helper\Fieldset::create(array(Helper\Token::create(Router::getToken('signin')), Helper\Container::create(array('tagname' => 'h2', 'attributes' => array('class' => 'form-signin-heading'), 'elements' => Lib\I18n::__('Authentification'))), Helper\Alert::create(), Helper\Input::create(array('attributes' => array('name' => 'email', 'value' => Request::env('POST')->email->val(), 'placeholder' => Lib\I18n::__('Adresse email'), 'autofocus' => true))), Helper\Input::create(array('attributes' => array('type' => 'password', 'name' => 'password', 'placeholder' => Lib\I18n::__('Mot de passe')))), Helper\Button::create(array('attributes' => array('class' => 'btn-lg btn-block btn-primary', 'value' => Lib\I18n::__('Connexion'))))))))->render();
?>
</body>
</html>
示例#26
0
文件: Profile.php 项目: johnstyle/sjo
 public function __construct()
 {
     parent::__construct();
     $this->name = I18n::__('My profil');
 }
示例#27
0
<?php

use sJo\Loader\Router;
use sJo\View\Helper;
use sJo\Libraries\I18n;
use sJo\Module\Admin\Back\Controller\Auth;
Auth::secure();
Helper\Menu::addRegistry('top', array(Helper\Link::create(array('elements' => I18n::__('My profil'), 'attributes' => array('href' => Router::linkBack('Admin/Profile'))))));
Helper\Menu::addRegistry('sidebar', array(Helper\Link::create(array('elements' => I18n::__('Manage admins'), 'attributes' => array('href' => Router::linkBack('Admin/Manager'))))));
示例#28
0
文件: File.php 项目: johnstyle/sjo
 /**
  * @param $file
  *
  * @throws \sJo\Exception\Exception
  */
 public static function __require($file)
 {
     if (!file_exists($file)) {
         throw new Exception(I18n::__('File %s do not exists', $file));
     }
     require $file;
 }
示例#29
0
文件: Profile.php 项目: johnstyle/sjo
<?php

use sJo\Loader\Router;
use sJo\Module\Admin\Model\Admin;
use sJo\View\Helper;
use sJo\Libraries as Lib;
$this->header();
Helper\Panel::create(array('col' => 6, 'title' => 'Edition', 'class' => 'panel-primary', 'elements' => Helper\Fieldset::create(array(Helper\Token::create(Router::getToken('update')), Helper\Input::create(array('type' => 'email', 'name' => 'email', 'label' => Lib\I18n::__('Email address'), 'placeholder' => Lib\I18n::__('Enter email'), 'value' => Admin::logged()->email)), Helper\Input::create(array('type' => 'text', 'name' => 'name', 'label' => Lib\I18n::__('Name'), 'placeholder' => Lib\I18n::__('Enter name'), 'value' => Admin::logged()->name)))), 'footer' => Helper\Button::create(array('class' => 'pull-right btn-primary', 'value' => Lib\I18n::__('Save')))))->render();
$this->footer();