diff --git a/.gitmodules b/.gitmodules index 3ab1269..e84275b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,9 @@ [submodule "site/fields/markdown"] path = site/fields/markdown url = https://github.com/JonasDoebertin/kirby-visual-markdown.git +[submodule "kirby"] + path = kirby + url = https://github.com/getkirby/kirby.git +[submodule "panel"] + path = panel + url = https://github.com/getkirby/panel.git diff --git a/kirby b/kirby new file mode 160000 index 0000000..f452ae5 --- /dev/null +++ b/kirby @@ -0,0 +1 @@ +Subproject commit f452ae5d2f8cdf2e3f58ac6691781a072ddd282f diff --git a/kirby/bootstrap.php b/kirby/bootstrap.php deleted file mode 100644 index 1fa8242..0000000 --- a/kirby/bootstrap.php +++ /dev/null @@ -1,69 +0,0 @@ - __DIR__ . DS . 'kirby.php', - 'kirby\\roots' => __DIR__ . DS . 'kirby' . DS . 'roots.php', - 'kirby\\urls' => __DIR__ . DS . 'kirby' . DS . 'urls.php', - 'kirby\\component' => __DIR__ . DS . 'kirby' . DS . 'component.php', - 'kirby\\registry' => __DIR__ . DS . 'kirby' . DS . 'registry.php', - 'kirby\\request' => __DIR__ . DS . 'kirby' . DS . 'request.php', - 'kirby\\request\\params' => __DIR__ . DS . 'kirby' . DS . 'request' . DS . 'params.php', - 'kirby\\request\\query' => __DIR__ . DS . 'kirby' . DS . 'request' . DS . 'query.php', - 'kirby\\request\\path' => __DIR__ . DS . 'kirby' . DS . 'request' . DS . 'path.php', - - // core components - 'kirby\\component\\template' => __DIR__ . DS . 'kirby' . DS . 'component' . DS . 'template.php', - 'kirby\\component\\thumb' => __DIR__ . DS . 'kirby' . DS . 'component' . DS . 'thumb.php', - 'kirby\\component\\markdown' => __DIR__ . DS . 'kirby' . DS . 'component' . DS . 'markdown.php', - 'kirby\\component\\smartypants' => __DIR__ . DS . 'kirby' . DS . 'component' . DS . 'smartypants.php', - 'kirby\\component\\snippet' => __DIR__ . DS . 'kirby' . DS . 'component' . DS . 'snippet.php', - 'kirby\\component\\css' => __DIR__ . DS . 'kirby' . DS . 'component' . DS . 'css.php', - 'kirby\\component\\js' => __DIR__ . DS . 'kirby' . DS . 'component' . DS . 'js.php', - 'kirby\\component\\tinyurl' => __DIR__ . DS . 'kirby' . DS . 'component' . DS . 'tinyurl.php', - 'kirby\\component\\response' => __DIR__ . DS . 'kirby' . DS . 'component' . DS . 'response.php', - - // traits - 'kirby\\traits\\image' => __DIR__ . DS . 'kirby' . DS . 'traits' . DS . 'image.php', - - // all core abstracts - 'assetabstract' => __DIR__ . DS . 'core' . DS . 'asset.php', - 'avatarabstract' => __DIR__ . DS . 'core' . DS . 'avatar.php', - 'pagesabstract' => __DIR__ . DS . 'core' . DS . 'pages.php', - 'childrenabstract' => __DIR__ . DS . 'core' . DS . 'children.php', - 'contentabstract' => __DIR__ . DS . 'core' . DS . 'content.php', - 'fieldabstract' => __DIR__ . DS . 'core' . DS . 'field.php', - 'fileabstract' => __DIR__ . DS . 'core' . DS . 'file.php', - 'filesabstract' => __DIR__ . DS . 'core' . DS . 'files.php', - 'kirbytextabstract' => __DIR__ . DS . 'core' . DS . 'kirbytext.php', - 'kirbytagabstract' => __DIR__ . DS . 'core' . DS . 'kirbytag.php', - 'pageabstract' => __DIR__ . DS . 'core' . DS . 'page.php', - 'roleabstract' => __DIR__ . DS . 'core' . DS . 'role.php', - 'rolesabstract' => __DIR__ . DS . 'core' . DS . 'roles.php', - 'siteabstract' => __DIR__ . DS . 'core' . DS . 'site.php', - 'usersabstract' => __DIR__ . DS . 'core' . DS . 'users.php', - 'userabstract' => __DIR__ . DS . 'core' . DS . 'user.php', - - // lib - 'pageextension' => __DIR__ . DS . 'lib' . DS . 'pageextension.php', - 'structure' => __DIR__ . DS . 'lib' . DS . 'structure.php', - - // parsedown - 'parsedown' => __DIR__ . DS . 'vendors' . DS . 'parsedown.php', - 'parsedownextra' => __DIR__ . DS . 'vendors' . DS . 'parsedownextra.php', - - // smartypants - 'smartypantstypographer_parser' => __DIR__ . DS . 'vendors' . DS . 'smartypants.php', - -)); - -// load all helper functions -include(__DIR__ . DS . 'helpers.php'); diff --git a/kirby/branches/default.php b/kirby/branches/default.php deleted file mode 100644 index 6f27318..0000000 --- a/kirby/branches/default.php +++ /dev/null @@ -1,18 +0,0 @@ - __DIR__ . DS . 'multilang' . DS . 'content.php', - 'field' => __DIR__ . DS . 'multilang' . DS . 'field.php', - 'file' => __DIR__ . DS . 'multilang' . DS . 'file.php', - 'language' => __DIR__ . DS . 'multilang' . DS . 'language.php', - 'languages' => __DIR__ . DS . 'multilang' . DS . 'languages.php', - 'page' => __DIR__ . DS . 'multilang' . DS . 'page.php', - 'site' => __DIR__ . DS . 'multilang' . DS . 'site.php', -)); \ No newline at end of file diff --git a/kirby/branches/multilang/content.php b/kirby/branches/multilang/content.php deleted file mode 100644 index c80959c..0000000 --- a/kirby/branches/multilang/content.php +++ /dev/null @@ -1,41 +0,0 @@ -name = f::name($this->name); - $this->language = $language; - - } - - public function realroot() { - return dirname($this->root()) . DS . $this->name() . '.' . $this->language . '.' . f::extension($this->root()); - } - - public function exists() { - return file_exists($this->realroot()); - } - - public function language() { - - if(!is_null($this->language)) return $this->language; - - $codes = $this->page->site()->languages()->codes(); - $code = f::extension(f::name($this->root)); - - return $this->language = in_array($code, $codes) ? $this->page->site()->languages()->find($code) : false; - - } - -} \ No newline at end of file diff --git a/kirby/branches/multilang/field.php b/kirby/branches/multilang/field.php deleted file mode 100644 index d8dbeec..0000000 --- a/kirby/branches/multilang/field.php +++ /dev/null @@ -1,34 +0,0 @@ -page->site(); - - // use current language if $lang not set - if(is_null($lang)) $lang = $site->language()->code(); - - // if language is default/fallback language - if($site->language($lang)->default()) return true; - - $current = $this->page->content($lang); - $default = $this->page->content($site->defaultLanguage->code); - - $field = $current->get($this->key); - $untranslated = $default->get($this->key)->value(); - - return $field->isNotEmpty() and $field->value() !== $untranslated; - - } - - -} diff --git a/kirby/branches/multilang/file.php b/kirby/branches/multilang/file.php deleted file mode 100644 index eec16fb..0000000 --- a/kirby/branches/multilang/file.php +++ /dev/null @@ -1,170 +0,0 @@ -page->textfile($this->filename(), $lang); - } - - /** - * Get the meta information - * - * @param string $lang optional language code - * @return Content - */ - public function meta($lang = null) { - - // get the content for the current language - if(is_null($lang)) { - - // the current language's content can be cached - if(isset($this->cache['meta'])) return $this->cache['meta']; - - // get the current content - $meta = $this->_meta($this->site->language->code); - - // get the fallback content - if($this->site->language->code != $this->site->defaultLanguage->code) { - - // fetch the default language content - $defaultMeta = $this->_meta($this->site->defaultLanguage->code); - - // replace all missing fields with values from the default content - foreach($defaultMeta->data as $key => $field) { - if(empty($meta->data[$key]->value)) { - $meta->data[$key] = $field; - } - } - - } - - // cache the meta for this language - return $this->cache['meta'] = $meta; - - // get the meta for another language - } else { - return $this->_meta($lang); - } - - } - - /** - * Private method to simplify meta fetching - * - * @return Content - */ - protected function _meta($lang) { - - // get the inventory - $inventory = $this->page->inventory(); - - // try to fetch the content for this language - $meta = isset($inventory['meta'][$this->filename][$lang]) ? $inventory['meta'][$this->filename][$lang] : null; - - // try to replace empty content with the default language content - if(empty($meta) and isset($inventory['meta'][$this->filename][$this->site->defaultLanguage->code])) { - $meta = $inventory['meta'][$this->filename][$this->site->defaultLanguage->code]; - } - - // find and cache the content for this language - return new Content($this->page, $this->page->root() . DS . $meta, $lang); - - } - - /** - * Renames the file and also its meta info txt - * - * @param string $filename - * @param boolean $safeName - */ - public function rename($name, $safeName = true) { - - $filename = $this->createNewFilename($name, $safeName); - $root = $this->dir() . DS . $filename; - - if(empty($name)) { - throw new Exception('The filename is missing'); - } - - if($root == $this->root()) return $filename; - - if(file_exists($root)) { - throw new Exception('A file with that name already exists'); - } - - if(!f::move($this->root(), $root)) { - throw new Exception('The file could not be renamed'); - } - - foreach($this->site->languages() as $lang) { - - // rename all meta files - $meta = $this->textfile($lang->code()); - - if(file_exists($meta)) { - f::move($meta, $this->page->textfile($filename, $lang->code())); - } - - } - - // reset the page cache - $this->page->reset(); - - // reset the basics - $this->root = $root; - $this->filename = $filename; - $this->name = $name; - $this->cache = array(); - - cache::flush(); - - return $filename; - - } - - public function update($data = array(), $lang = null) { - - $data = array_merge((array)$this->meta()->toArray(), $data); - - foreach($data as $k => $v) { - if(is_null($v)) unset($data[$k]); - } - - if(!data::write($this->textfile($lang), $data, 'kd')) { - throw new Exception('The file data could not be saved'); - } - - // reset the page cache - $this->page->reset(); - - // reset the file cache - $this->cache = array(); - - cache::flush(); - return true; - - } - - public function delete() { - - foreach($this->site->languages() as $lang) { - // delete the meta file for each language - f::remove($this->textfile($lang->code())); - } - - parent::delete(); - - return true; - - } - - -} \ No newline at end of file diff --git a/kirby/branches/multilang/language.php b/kirby/branches/multilang/language.php deleted file mode 100644 index 18c6368..0000000 --- a/kirby/branches/multilang/language.php +++ /dev/null @@ -1,34 +0,0 @@ -site = $site; - $this->code = $lang['code']; - $this->name = $lang['name']; - $this->locale = $lang['locale']; - $this->default = (isset($lang['default']) and $lang['default']); - $this->direction = (isset($lang['direction']) and $lang['direction'] == 'rtl') ? 'rtl' : 'ltr'; - $this->url = isset($lang['url']) ? $lang['url'] : $lang['code']; - - } - - public function url() { - return url::makeAbsolute($this->url, $this->site->url()); - } - - public function isDefault() { - return $this->default; - } - - public function __toString() { - return $this->code; - } - -} diff --git a/kirby/branches/multilang/languages.php b/kirby/branches/multilang/languages.php deleted file mode 100644 index cb1cd43..0000000 --- a/kirby/branches/multilang/languages.php +++ /dev/null @@ -1,28 +0,0 @@ -site = $site; - } - - public function find($code) { - return isset($this->data[$code]) ? $this->data[$code] : null; - } - - public function codes() { - return $this->keys(); - } - - public function findDefault() { - return $this->site->defaultLanguage(); - } - -} \ No newline at end of file diff --git a/kirby/branches/multilang/page.php b/kirby/branches/multilang/page.php deleted file mode 100644 index bd25bc5..0000000 --- a/kirby/branches/multilang/page.php +++ /dev/null @@ -1,281 +0,0 @@ -intendedTemplate(); - if(is_null($lang)) $lang = $this->site->language->code; - return textfile($this->diruri(), $template, $lang); - } - - /** - * Returns the translated URI - */ - public function uri($lang = null) { - // build the page's uri with the parent uri and the page's slug - return ltrim($this->parent->uri($lang) . '/' . $this->slug($lang), '/'); - } - - /** - * Returns the URL key from the content file - * if available and otherwise returns the page UID - * - * @param string $lang - * @return string - */ - public function urlKey($lang = null) { - - if($content = $this->content($lang)) { - // search for a translated url_key in that language - if($key = (string)a::get((array)$content->data(), 'url_key')) { - // if available, use the translated url key as slug - return $key; - } - } - - return $this->uid(); - - } - - /** - * Returns the slug for the page - * The slug is the last part of the URL path - * For multilang sites this can be translated with a URL-Key field - * in the text file for this page. - * - * @param string $lang Optional language code to get the translated slug - * @return string i.e. 01-projects returns projects - */ - public function slug($lang = null) { - - $default = $this->site->defaultLanguage->code; - $current = $this->site->language->code; - - // get the slug for the current language - if(is_null($lang)) { - - // the current language's slug can be cached - if(isset($this->cache['slug'])) return $this->cache['slug']; - - // if the current language is the default language - // simply return the uid - if($current == $default) { - return $this->cache['slug'] = $this->uid(); - } - - // get the translated url key - return $this->urlKey(); - - } else { - - // if the passed language code is the current language code - // we can simply return the slug method without a language code specified - if($lang == $current) { - return $this->slug(); - } - - // the slug for the default language is just the name of the folder - if($lang == $default) { - return $this->uid(); - } - - // get the translated url key - return $this->urlKey($lang); - - } - - } - - /** - * Returns the full url for the page - * - * @param string $lang Optional language code to get the URL for that specific language on multilang sites - * @return string - */ - public function url() { - - $args = func_get_args(); - $lang = array_shift($args); - - // for multi language sites every url needs - // to be treated specially to make sure each uid is translated properly - // and language codes are prepended if needed - if(is_null($lang)) { - // get the current language - $lang = $this->site->language->code; - } - - // Kirby is trying to remove the home folder name from the url - if($this->isHomePage()) { - return $this->site->url($lang); - } else if($this->parent->isHomePage()) { - return $this->site->url($lang) . '/' . $this->parent->slug($lang) . '/' . $this->slug($lang); - } else { - return $this->parent->url($lang) . '/' . $this->slug($lang); - } - - } - - /** - * Modified inventory fetcher - * - * @return array - */ - public function inventory() { - - $inventory = parent::inventory(); - $defaultLang = $this->site->defaultLanguage->code; - $expression = '!(.*?)(\.(' . implode('|', $this->site->languages->codes()) . ')|)\.' . $this->kirby->options['content.file.extension'] . '$!i'; - - foreach($inventory['meta'] as $key => $meta) { - $inventory['meta'][$key] = array($defaultLang => $meta); - } - - foreach($inventory['content'] as $key => $content) { - - preg_match($expression, $content, $match); - - $file = $match[1]; - $lang = isset($match[3]) ? $match[3] : null; - - if(in_array($file, $inventory['files'])) { - $inventory['meta'][$file][$lang] = $content; - } else { - - if(is_null($lang)) { - $lang = f::extension($file); - if(empty($lang)) $lang = $defaultLang; - } - - $inventory['content'][$lang] = $content; - } - - unset($inventory['content'][$key]); - - } - - // try to fill the default language with something else - if(!isset($inventory['content'][$defaultLang])) { - $inventory['content'][$defaultLang] = a::first($inventory['content']); - } - - return $inventory; - - } - - /** - * Returns the content object for this page - * - * @param string $lang optional language code - * @return Content - */ - public function content($lang = null) { - - // get the content for the current language - if(is_null($lang)) { - - // the current language's content can be cached - if(isset($this->cache['content'])) return $this->cache['content']; - - // get the current content - $content = $this->_content($this->site->language->code); - - // get the fallback content - if($this->site->language->code != $this->site->defaultLanguage->code) { - - // fetch the default language content - $defaultContent = $this->_content($this->site->defaultLanguage->code); - - // replace all missing fields with values from the default content - foreach($defaultContent->data as $key => $field) { - if(empty($content->data[$key]->value)) { - $content->data[$key] = $field; - } - } - - } - - // find and cache the content for this language - return $this->cache['content'] = $content; - - // get the content for another language - } else { - return $this->_content($lang); - } - - } - - /** - * Private method to simplify content fetching - * - * @return Content - */ - protected function _content($lang) { - - // get the inventory - $inventory = $this->inventory(); - - // try to fetch the content for this language - $content = isset($inventory['content'][$lang]) ? $inventory['content'][$lang] : null; - - // try to replace empty content with the default language content - if(empty($content) and isset($inventory['content'][$this->site->defaultLanguage->code])) { - $content = $inventory['content'][$this->site->defaultLanguage->code]; - } - - // find and cache the content for this language - return new Content($this, $this->root() . DS . $content, $lang); - - } - - /** - * Creates a new page object - * - * @param string $uri - * @param string $template - * @param array $data - */ - static public function create($uri, $template, $data = array()) { - return parent::create($uri, $template . '.' . site()->defaultLanguage->code, $data); - } - - /** - * Update the page with a new set of data - * - * @param array $data - */ - public function update($input = array(), $lang = null) { - - $data = a::update($this->content($lang)->toArray(), $input); - - if(!data::write($this->textfile(null, $lang), $data, 'kd')) { - throw new Exception('The page could not be updated'); - } - - $this->kirby->cache()->flush(); - $this->reset(); - $this->touch(); - return true; - - } - - /** - * Returns the name of the content text file / intended template - * So even if there's no such template it will return the intended name. - * - * @return string - */ - public function intendedTemplate() { - if(isset($this->cache['intendedTemplate'])) return $this->cache['intendedTemplate']; - return $this->cache['intendedTemplate'] = $this->content($this->site->defaultLanguage()->code())->exists() ? $this->content()->name() : 'default'; - } - -} \ No newline at end of file diff --git a/kirby/branches/multilang/site.php b/kirby/branches/multilang/site.php deleted file mode 100644 index df465dd..0000000 --- a/kirby/branches/multilang/site.php +++ /dev/null @@ -1,193 +0,0 @@ -languages = new Languages($this); - - foreach($kirby->options['languages'] as $lang) { - - $language = new Language($this, $lang); - - // store the default language - if($language->default) $this->defaultLanguage = $this->language = $language; - - // add the language to the collection - $this->languages->data[$language->code] = $language; - - } - - } - - /** - * Returns the translated URI - */ - public function uri($lang = null) { - return null; - } - - public function slug($lang = null) { - return null; - } - - /** - * Returns the url of the site - * - * @return string - */ - public function url($lang = false) { - if($lang) { - // return the specific language url - return $this->languages->find($lang)->url(); - } else { - return parent::url(); - } - } - - /** - * Marks the site as a multilanguage site - * - * @return boolean - */ - public function multilang() { - return true; - } - - /** - * Returns the Languages Collection - * - * @return Languages - */ - public function languages() { - return $this->languages; - } - - /** - * Returns the current language - * or any other language by language code - * - * @param string $code - * @return Language - */ - public function language($code = null) { - if(is_null($code)) return $this->language; - return $this->languages()->find($code); - } - - /** - * Returns the default language - * - * @return Language - */ - public function defaultLanguage() { - return $this->defaultLanguage; - } - - /** - * Tries to find the language for the current visitor - * - * @return Language - */ - public function visitorLanguage() { - return $this->languages()->find(visitor::acceptedLanguageCode()); - } - - /** - * Returns the detected language - * - * @return Language - */ - public function detectedLanguage() { - - if($language = $this->visitorLanguage()) { - return $language; - } else { - return $this->defaultLanguage(); - } - - } - - /** - * Returns the language which will be - * remembered for the next visit - * - * @return Language - */ - public function sessionLanguage() { - if($code = s::get('language') and $language = $this->languages()->find($code)) { - return $language; - } else { - return null; - } - } - - public function switchLanguage(Language $language) { - - s::set('language', $language->code()); - - if($this->language()->code() != $language->code()) { - go($this->page()->url($language->code())); - } - - } - - /** - * Sets the currently active page - * and returns its page object - * - * @param string $uri - * @return Page - */ - public function visit($uri = '', $lang = null) { - - // if the language code is missing or the code is invalid (TODO) - if(!in_array($lang, $this->languages()->keys())) { - $lang = $this->defaultLanguage->code; - } - - // set the current language - $this->language = $this->languages()->data[$lang]; - - // clean the uri - $uri = trim($uri, '/'); - - if(empty($uri)) { - return $this->page = $this->homePage(); - } else { - - if($lang == $this->defaultLanguage->code and $page = $this->children()->find($uri)) { - return $this->page = $page; - } else if($page = $this->children()->findByURI($uri)) { - return $this->page = $page; - } else { - return $this->page = $this->errorPage(); - } - } - - } - - /** - * Returns the locale for the site - * - * @return string - */ - public function locale() { - return $this->language->locale; - } - -} diff --git a/kirby/core/asset.php b/kirby/core/asset.php deleted file mode 100644 index a92e457..0000000 --- a/kirby/core/asset.php +++ /dev/null @@ -1,21 +0,0 @@ -kirby = kirby::instance(); - if(is_a($path, 'Media')) { - parent::__construct($path->root(), $path->url()); - } else { - parent::__construct( - url::isAbsolute($path) ? null : $this->kirby->roots()->index() . DS . ltrim($path, DS), - url::makeAbsolute($path) - ); - } - } - -} \ No newline at end of file diff --git a/kirby/core/avatar.php b/kirby/core/avatar.php deleted file mode 100644 index e17d7ef..0000000 --- a/kirby/core/avatar.php +++ /dev/null @@ -1,30 +0,0 @@ -user = $user; - - // this should rather be coming from the user object - $this->kirby = kirby::instance(); - - // try to find the avatar - if($file = f::resolve($this->kirby->roots()->avatars() . DS . $user->username(), ['jpg', 'jpeg', 'gif', 'png'])) { - $filename = f::filename($file); - } else { - $filename = $user->username() . '.jpg'; - $file = $this->kirby->roots()->avatars() . DS . $filename; - } - - parent::__construct($file, $this->kirby->urls()->avatars() . '/' . $filename); - - } - -} \ No newline at end of file diff --git a/kirby/core/children.php b/kirby/core/children.php deleted file mode 100644 index 67ae247..0000000 --- a/kirby/core/children.php +++ /dev/null @@ -1,207 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class ChildrenAbstract extends Pages { - - protected $page = null; - protected $cache = array(); - - /** - * Constructor - */ - public function __construct($page) { - $this->page = $page; - } - - /** - * Creates a new Page object and adds it to the collection - */ - public function add($dirname) { - $page = new Page($this->page, $dirname); - $this->data[$page->id()] = $page; - return $page; - } - - /** - * Creates a new subpage - * - * @param string $uid - * @param string $template - * @param array $data - */ - public function create($uid, $template, $data = array()) { - $page = page::create($this->page->id() . '/' . $uid, $template, $data); - $this->data[$page->id()] = $page; - return $page; - } - - /** - * Returns the parent page - * - * @return Page - */ - public function page() { - return $this->page; - } - - /** - * Returns the Children of Children - * - * @return Children - */ - public function children() { - $grandChildren = new Children($this->page); - foreach($this->data as $page) { - foreach($page->children() as $subpage) { - $grandChildren->data[$subpage->id()] = $subpage; - } - } - return $grandChildren; - } - - /** - * Find a specific page by its uri - * - * @return Page or false - */ - public function find() { - - $args = func_get_args(); - - if(!count($args)) { - return false; - } else if (count($args) === 1 and is_array($args[0])) { - $args = $args[0]; - } - - if(count($args) > 1) { - $collection = new Children($this->page); - foreach($args as $id) { - if($page = $this->find($id)) { - $collection->data[$page->id()] = $page; - } - } - return $collection; - } else { - - // get the first argument and remove slashes - $id = trim($args[0], '/'); - - // build the direct uri - $directId = trim($this->page()->id() . '/' . $id, '/'); - - // fast access to direct uris - if(isset($this->data[$directId])) return $this->data[$directId]; - - $path = explode('/', $id); - $obj = $this; - $page = false; - - foreach($path as $uid) { - - $id = ltrim($obj->page()->id() . '/' . $uid, '/'); - - if(!isset($obj->data[$id])) return false; - - $page = $obj->data[$id]; - $obj = $page->children(); - - } - - return $page; - - } - - } - - /** - * Finds pages by it's unique URI - * - * @param mixed $uri Either a single URI string or an array of URIs - * @param string $use The field, which should be used (uid or slug) - * @return mixed Either a Page object, a Pages object for multiple pages or null if nothing could be found - */ - public function findByURI() { - - $args = func_get_args(); - - if(count($args) == 0) { - return false; - } else if(count($args) > 1) { - $collection = new Children($this->page); - foreach($args as $uri) { - $page = $this->findByURI($uri); - if($page) $collection->data[$page->id()] = $page; - } - return $collection; - } else { - - // get the first argument and remove slashes - $uri = trim($args[0], '/'); - $array = str::split($uri, '/'); - $obj = $this; - $page = false; - - foreach($array as $p) { - - $next = $obj->findBy('slug', $p); - - if(!$next) break; - - $page = $next; - $obj = $next->children(); - - } - - return ($page and $page->slug() != a::last($array)) ? false : $page; - - } - - } - - /** - * Creates a clean one-level collection with all - * pages, subpages, subsubpages, etc. - * - * @param object Pages object for recursive indexing - * @return Children - */ - public function index(Children $obj = null) { - - if(is_null($obj)) { - if(isset($this->cache['index'])) return $this->cache['index']; - $this->cache['index'] = new Children($this->page); - $obj = $this; - } - - foreach($obj->data as $key => $page) { - $this->cache['index']->data[$page->uri()] = $page; - $this->index($page->children()); - } - - return $this->cache['index']; - - } - - /** - * Extended group method - * detaches children and converts them to - * a simple pages collection - * - * @param function $callback - * @return Pages - */ - public function group($callback) { - $collection = new Pages($this); - return $collection->group($callback); - } - -} \ No newline at end of file diff --git a/kirby/core/content.php b/kirby/core/content.php deleted file mode 100644 index 0a6bac6..0000000 --- a/kirby/core/content.php +++ /dev/null @@ -1,151 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class ContentAbstract { - - public $page = null; - public $root = null; - public $raw = null; - public $data = array(); - public $fields = array(); - public $name = null; - - /** - * Constructor - */ - public function __construct($page, $root) { - - $this->page = $page; - $this->root = $root; - $this->name = pathinfo($root, PATHINFO_FILENAME); - - // stop at invalid files - if(empty($this->root) or !is_file($this->root) or !is_readable($this->root)) return; - - // read the content file and remove the BOM - $this->raw = str_replace(BOM, '', file_get_contents($this->root)); - - // explode all fields by the line separator - $fields = preg_split('!\n----\s*\n*!', $this->raw); - - // loop through all fields and add them to the content - foreach($fields as $field) { - $pos = strpos($field, ':'); - $key = str_replace(array('-', ' '), '_', strtolower(trim(substr($field, 0, $pos)))); - - // Don't add fields with empty keys - if(empty($key)) continue; - - // add the key to the fields list - $this->fields[] = $key; - - // add the key object - $this->data[$key] = new Field($this->page, $key, trim(substr($field, $pos+1))); - } - - } - - /** - * Returns the root for the content file - */ - public function root() { - return $this->root; - } - - /** - * Returns the name of the content file - * without the extension. This is - * being used to determine the template for the page - * - * @return string - */ - public function name() { - return $this->name; - } - - /** - * Returns an array with all - * field names - * - * @return array3 - */ - public function fields() { - return $this->fields; - } - - /** - * Returns the raw content from the file - * - * @return string - */ - public function raw() { - return $this->raw; - } - - /** - * Returns the entire data array - * with all field objects - * - * @return array - */ - public function data() { - return $this->data; - } - - /** - * Checks if the content file exists - * - * @return boolean - */ - public function exists() { - return file_exists($this->root); - } - - /** - * Gets a field from the content - * - * @return Field - */ - public function get($key, $arguments = null) { - - // case-insensitive data fetching - $key = strtolower($key); - - if(isset($this->data[$key])) { - return $this->data[$key]; - } else { - // return an empty field as default - return new Field($this->page, $key); - } - - } - - /** - * Checks if a field exists - * - * @param string $key - * @return boolean - */ - public function has($key) { - return isset($this->data[strtolower($key)]); - } - - public function __call($method, $arguments = null) { - return $this->get($method, $arguments); - } - - public function toArray() { - return array_map(function($item) { - return $item->value; - }, $this->data); - } - -} \ No newline at end of file diff --git a/kirby/core/field.php b/kirby/core/field.php deleted file mode 100644 index ba8127c..0000000 --- a/kirby/core/field.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class FieldAbstract { - - static public $methods = array(); - - public $page; - public $key; - public $value; - - public function __construct($page, $key, $value = '') { - $this->page = $page; - $this->key = $key; - $this->value = $value; - } - - public function page() { - return $this->page; - } - public function exists() { - return $this->page->content()->has($this->key); - } - public function key() { - return $this->key; - } - public function value() { - return $this->value; - } - public function isTranslated($lang = null) { - return true; - } - public function __toString() { - return (string)$this->value; - } - public function toString() { - return $this->value; - } - public function __call($method, $arguments = array()) { - if(isset(static::$methods[$method])) { - array_unshift($arguments, clone $this); - return call(static::$methods[$method], $arguments); - } else { - return $this; - } - } -} diff --git a/kirby/core/file.php b/kirby/core/file.php deleted file mode 100644 index 010f386..0000000 --- a/kirby/core/file.php +++ /dev/null @@ -1,333 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class FileAbstract extends Media { - - use Kirby\Traits\Image; - - static public $methods = array(); - - public $kirby; - public $site; - public $page; - public $files; - - /** - * Constructor - * - * @param Files The parent files collection - * @param string The filename - */ - public function __construct(Files $files, $filename) { - - $this->kirby = $files->kirby; - $this->site = $files->site; - $this->page = $files->page; - $this->files = $files; - $this->root = $this->files->page()->root() . DS . $filename; - - parent::__construct($this->root); - - } - - /** - * Returns the kirby object - * - * @return Kirby - */ - public function kirby() { - return $this->kirby; - } - - /** - * Returns the parent site object - * - * @return Site - */ - public function site() { - return $this->site; - } - - /** - * Returns the parent page object - * - * @return Page - */ - public function page() { - return $this->page; - } - - /** - * Returns the parent files collection - * - * @return Files - */ - public function files() { - return $this->files; - } - - /** - * Returns the full root for the content file - * - * @return string - */ - public function textfile() { - return $this->page->textfile($this->filename()); - } - - public function siblings() { - return $this->files->not($this->filename); - } - - public function next() { - $siblings = $this->files; - $index = $siblings->indexOf($this); - if($index === false) return false; - return $this->files->nth($index+1); - } - - public function hasNext() { - return $this->next(); - } - - public function prev() { - $siblings = $this->files; - $index = $siblings->indexOf($this); - if($index === false) return false; - return $this->files->nth($index-1); - } - - public function hasPrev() { - return $this->prev(); - } - - /** - * Returns the absolute URL for the file - * - * @return string - */ - public function url($raw = false) { - if($raw || empty($this->modifications)) { - return $this->page->contentUrl() . '/' . rawurlencode($this->filename); - } else { - return $this->kirby->component('thumb')->url($this); - } - } - - /** - * Returns the relative URI for the image - * - * @return string - */ - public function uri() { - return $this->page->uri() . '/' . rawurlencode($this->filename); - } - - /** - * Returns the full directory path starting from the content folder - * - * @return string - */ - public function diruri() { - return $this->page->diruri() . '/' . rawurlencode($this->filename); - } - - /** - * Get the meta information - * - * @return Content - */ - public function meta() { - - if(isset($this->cache['meta'])) { - return $this->cache['meta']; - } else { - - $inventory = $this->page->inventory(); - $file = isset($inventory['meta'][$this->filename]) ? $this->page->root() . DS . $inventory['meta'][$this->filename] : null; - - return $this->cache['meta'] = new Content($this->page, $file); - - } - - } - - /** - * Custom modified method for files - * - * @param string $format - * @return string - */ - public function modified($format = null, $handler = null) { - return parent::modified($format, $handler ? $handler : $this->kirby->options['date.handler']); - } - - /** - * Magic getter for all meta fields - * - * @return Field - */ - public function __call($key, $arguments = null) { - if(isset(static::$methods[$key])) { - if(!$arguments) $arguments = array(); - array_unshift($arguments, clone $this); - return call(static::$methods[$key], $arguments); - } else { - return $this->meta()->get($key, $arguments); - } - } - - /** - * Generates a new filename for a given name - * and makes sure to handle badly given extensions correctly - * - * @param string $name - * @return string - */ - public function createNewFilename($name, $safeName = true) { - - $name = basename($safeName ? f::safeName($name) : $name); - $ext = f::extension($name); - - // remove possible extensions - if(in_array($ext, f::extensions())) { - $name = f::name($name); - } - - return trim($name . '.' . $this->extension(), '.'); - - } - - /** - * Renames the file and also its meta info txt - * - * @param string $filename - * @param boolean $safeName - */ - public function rename($name, $safeName = true) { - - $filename = $this->createNewFilename($name, $safeName); - $root = $this->dir() . DS . $filename; - - if(empty($name)) { - throw new Exception('The filename is missing'); - } - - if($root == $this->root()) return $filename; - - if(file_exists($root)) { - throw new Exception('A file with that name already exists'); - } - - if(!f::move($this->root(), $root)) { - throw new Exception('The file could not be renamed'); - } - - $meta = $this->textfile(); - - if(file_exists($meta)) { - f::move($meta, $this->page->textfile($filename)); - } - - // reset the page cache - $this->page->reset(); - - // reset the basics - $this->root = $root; - $this->filename = $filename; - $this->name = $name; - $this->cache = array(); - - cache::flush(); - - return $filename; - - } - - public function update($data = array()) { - - $data = array_merge((array)$this->meta()->toArray(), $data); - - foreach($data as $k => $v) { - if(is_null($v)) unset($data[$k]); - } - - if(!data::write($this->textfile(), $data, 'kd')) { - throw new Exception('The file data could not be saved'); - } - - // reset the page cache - $this->page->reset(); - - // reset the file cache - $this->cache = array(); - - cache::flush(); - return true; - - } - - public function delete() { - - // delete the meta file - f::remove($this->textfile()); - - if(!f::remove($this->root())) { - throw new Exception('The file could not be deleted'); - } - - cache::flush(); - return true; - - } - - /** - * Get formatted date fields - * - * @param string $format - * @param string $field - * @return mixed - */ - public function date($format = null, $field = 'date') { - if($timestamp = strtotime($this->meta()->$field())) { - if(is_null($format)) { - return $timestamp; - } else { - return $this->kirby->options['date.handler']($format, $timestamp); - } - } else { - return false; - } - } - - /** - * Converts the entire file object into - * a plain PHP array - * - * @param closure $callback Filter callback - * @return array - */ - public function toArray($callback = null) { - - $data = parent::toArray(); - - // add the meta content - $data['meta'] = $this->meta()->toArray(); - - if(is_null($callback)) { - return $data; - } else { - return array_map($callback, $data); - } - - } - -} \ No newline at end of file diff --git a/kirby/core/files.php b/kirby/core/files.php deleted file mode 100644 index ec92d8e..0000000 --- a/kirby/core/files.php +++ /dev/null @@ -1,137 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class FilesAbstract extends Collection { - - static public $methods = array(); - - public $kirby = null; - public $site = null; - public $page = null; - - public function __construct($page) { - $this->kirby = $page->kirby; - $this->site = $page->site; - $this->page = $page; - $inventory = $page->inventory(); - - foreach($inventory['files'] as $filename) { - $file = new File($this, $filename); - $this->data[strtolower($file->filename())] = $file; - } - } - - public function __call($method, $arguments) { - - if(isset(static::$methods[$method])) { - array_unshift($arguments, clone $this); - return call(static::$methods[$method], $arguments); - } else { - return $this->get($method); - } - - } - - public function kirby() { - return $this->kirby; - } - - public function site() { - return $this->site; - } - - public function page() { - return $this->page; - } - - public function find() { - - $args = func_get_args(); - - if(!count($args)) { - return false; - } - - if(count($args) === 1 and is_array($args[0])) { - $args = $args[0]; - } - - if(count($args) > 1) { - $files = clone $this; - $files->data = array(); - foreach($args as $filename) { - $file = $this->find($filename); - if(!empty($file)) { - $files->data[$filename] = $file; - } - } - return $files; - } else { - $filename = strtolower($args[0]); - return isset($this->data[$filename]) ? $this->data[$filename] : null; - } - - } - - /** - * Returns a new collection of files without the given files - * - * @param args any number of filenames or file objects, passed as individual arguments - * @return object a new collection without the files - */ - public function not() { - $collection = clone $this; - foreach(func_get_args() as $filename) { - if(is_array($filename) or $filename instanceof Traversable) { - foreach($filename as $f) { - $collection = $collection->not($f); - } - } else if(is_a($filename, 'Media')) { - // unset by Media object - unset($collection->data[strtolower($filename->filename())]); - } else { - unset($collection->data[strtolower($filename)]); - } - } - return $collection; - } - - /** - * Converts the files collection - * into a plain array - * - * @param closure $callback Filter callback for each item - * @return array - */ - public function toArray($callback = null) { - - $data = array(); - - foreach($this as $file) { - $data[] = $file->toArray($callback); - } - - return $data; - - } - - /** - * Converts the files collection - * into a json string - * - * @param closure $callback Filter callback for each item - * @return string - */ - public function toJson($callback = null) { - return json_encode($this->toArray($callback)); - } - -} \ No newline at end of file diff --git a/kirby/core/kirbytag.php b/kirby/core/kirbytag.php deleted file mode 100644 index 8ad00fa..0000000 --- a/kirby/core/kirbytag.php +++ /dev/null @@ -1,173 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class KirbytagAbstract { - - protected $page; - protected $kirbytext; - protected $name; - protected $html; - protected $attr = array(); - - public function __construct($kirbytext, $name, $tag) { - - if(is_null($kirbytext)) $kirbytext = new Kirbytext(''); - - $this->page = $kirbytext->field->page; - $this->kirbytext = $kirbytext; - $this->name = $name; - $this->html = kirbytext::$tags[$name]['html']; - - // get a list with all attributes - $attributes = isset(kirbytext::$tags[$name]['attr']) ? (array)kirbytext::$tags[$name]['attr'] : array(); - - // add the name as first attribute - array_unshift($attributes, $name); - - if(is_array($tag)) { - foreach($attributes as $key) { - if(isset($tag[$key])) $this->attr[$key] = $tag[$key]; - } - } else { - - // extract all attributes - $search = preg_split('!(' . implode('|', $attributes) . '):!i', $tag, false, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); - $num = 0; - - foreach($search AS $key) { - - if(!isset($search[$num+1])) break; - - $key = trim($search[$num]); - $value = trim($search[$num+1]); - - $this->attr[$key] = $value; - $num = $num+2; - - } - - } - - } - - /** - * Returns the parent active page - * - * @return object Page - */ - public function page() { - return $this->page; - } - - /** - * Returns the parent kirbytext object - * - * @return object Kirbytext - */ - public function kirbytext() { - return $this->kirbytext; - } - - /** - * Returns the field object - * - * @return object Field - */ - public function field() { - return $this->kirbytext->field(); - } - - /** - * Tries to find all related files for the current page - * - * @return object Files - */ - public function files() { - return $this->page->files(); - } - - /** - * Tries to find a file for the given url/uri - * - * @param string $url a full path to a file or just a filename for files form the current active page - * @return object File - */ - public function file($url) { - - // if this is an absolute url cancel - if(preg_match('!(http|https)\:\/\/!i', $url)) return false; - - // skip urls without extensions - if(!preg_match('!\.[a-z0-9]+$!i',$url)) return false; - - // relative url - if(str::contains($url, '/')) { - - $path = dirname($url); - $filename = basename($url); - - if($page = page($path) and $file = $page->file($filename)) { - return $file; - } else { - return false; - } - - } - - // try to get all files for the current page - $files = $this->files(); - - // cancel if no files are available - if(!$files) return false; - - // try to find the file - return $files->find($url); - - } - - /** - * Returns a specific attribute by key or all attributes - * by passing no key at all. - * - * @param mixed $key - * @param mixed $default - * @return array - */ - public function attr($key = null, $default = null) { - if(is_null($key)) return $this->attr; - return isset($this->attr[$key]) ? $this->attr[$key] : $default; - } - - /** - * Smart getter for the applicable target attribute. - * This will watch for popup or target attributes and return - * a proper target value if available. - * - * @return string - */ - public function target() { - if(empty($this->attr['popup']) and empty($this->attr['target'])) return false; - return empty($this->attr['popup']) ? $this->attr['target'] : '_blank'; - } - - public function html() { - if(!is_callable($this->html)) { - return (string)$this->html; - } else { - return call_user_func_array($this->html, array($this)); - } - } - - public function __toString() { - return (string)$this->html(); - } - -} \ No newline at end of file diff --git a/kirby/core/kirbytext.php b/kirby/core/kirbytext.php deleted file mode 100644 index b46d9b9..0000000 --- a/kirby/core/kirbytext.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class KirbytextAbstract { - - static public $tags = array(); - static public $pre = array(); - static public $post = array(); - - public $field; - - public function __construct($field) { - - if(is_a($field, 'Field')) { - $this->field = $field; - } else if(is_array($field)) { - throw new Exception('Kirbytext cannot handle arrays'); - } else if(empty($field) or is_string($field)) { - $this->field = new Field(page(), null, $field); - } - - } - - public function field() { - return $this->field; - } - - public function parse() { - - if(!$this->field) return ''; - - $text = $this->field->value; - - // pre filters - foreach(static::$pre as $filter) { - $text = call_user_func_array($filter, array($this, $text)); - } - - // tagsify - $text = preg_replace_callback('!(?=[^\]])\([a-z0-9_-]+:.*?\)!is', array($this, 'tag'), $text); - - // markdownify - $text = kirby::instance()->component('markdown')->parse($text); - - // smartypantsify - $text = kirby::instance()->component('smartypants')->parse($text); - - // post filters - foreach(static::$post as $filter) { - $text = call_user_func_array($filter, array($this, $text)); - } - - return $text; - - } - - public function tag($input) { - - // remove the brackets - $tag = trim(rtrim(ltrim($input[0], '('), ')')); - $name = trim(substr($tag, 0, strpos($tag, ':'))); - - // if the tag is not installed return the entire string - if(!isset(static::$tags[$name])) return $input[0]; - - try { - $tag = new Kirbytag($this, $name, $tag); - return $tag->html(); - } catch(Exception $e) { - // broken tags will be ignored - return $input[0]; - } - - } - - static public function install($root) { - - if(!is_dir($root)) return false; - - foreach(scandir($root) as $file) { - if(pathinfo($file, PATHINFO_EXTENSION) == 'php') { - $name = pathinfo($file, PATHINFO_FILENAME); - $tag = include($root . DS . $file); - if(is_array($tag)) Kirbytext::$tags[$name] = $tag; - } - } - - } - - public function __toString() { - try { - return $this->parse(); - } catch(Exception $e) { - // on massive render bugs the entire text will be returned - return $this->field->value; - } - } - -} \ No newline at end of file diff --git a/kirby/core/page.php b/kirby/core/page.php deleted file mode 100644 index fff6cca..0000000 --- a/kirby/core/page.php +++ /dev/null @@ -1,1443 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class PageAbstract { - - static public $models = array(); - static public $methods = array(); - - public $kirby; - public $site; - public $parent; - - protected $id; - protected $dirname; - protected $root; - protected $depth; - protected $uid; - protected $num; - protected $uri; - protected $cache = array(); - - /** - * Constructor - * - * @param Page $parent - * @param string $dirname - */ - public function __construct($parent, $dirname) { - - $this->kirby = $parent->kirby; - $this->site = $parent->site; - $this->parent = $parent; - $this->dirname = $dirname; - $this->root = $parent->root() . DS . $dirname; - $this->depth = $parent->depth() + 1; - - // extract the uid and num of the directory - if(preg_match('/^([0-9]+)[\-](.*)$/', $this->dirname, $match)) { - $this->uid = $match[2]; - $this->num = $match[1]; - } else { - $this->num = null; - $this->uid = $this->dirname; - } - - // assign the uid - $this->id = $this->uri = ltrim($parent->id() . '/' . $this->uid, '/'); - - } - - /** - * Cleans the temporary page cache and - * the cache of all parent pages - */ - public function reset() { - $this->cache = array(); - $this->parent()->reset(); - } - - /** - * Mark the page as modified - */ - public function touch() { - return touch($this->root()); - } - - /** - * Returns the kirby object - * - * @return Kirby - */ - public function kirby() { - return $this->kirby; - } - - /** - * Returns the site object - * - * @return Site - */ - public function site() { - return $this->site; - } - - /** - * Returns the parent page element - * - * @return Page - */ - public function parent() { - return $this->parent; - } - - /** - * Returns all parents - * - * @return Children - */ - public function parents() { - - if(isset($this->cache['parents'])) return $this->cache['parents']; - - $children = new Children($this->site); - $parents = array(); - $next = $this->parent(); - - while($next and $next->depth() > 0) { - $children->data[$next->id()] = $next; - $next = $next->parent(); - } - - return $this->cache['parents'] = $children; - - } - - /** - * Returns the full root of the page folder - * - * @return string - */ - public function root() { - return $this->root; - } - - /** - * Returns the name of the directory - * - * @return string - */ - public function dirname() { - return $this->dirname; - } - - /** - * Returns the relative URL for the directory. - * Relative to the base content directory - * - * @return string - */ - public function diruri() { - if(isset($this->cache['diruri'])) return $this->cache['diruri']; - return $this->cache['diruri'] = ltrim($this->parent()->diruri() . '/' . $this->dirname(), '/'); - } - - /** - * Returns the full url for the page - * - * @return string - */ - public function url() { - - if(isset($this->cache['url'])) return $this->cache['url']; - - // Kirby is trying to remove the home folder name from the url - if($this->isHomePage()) { - // return the base url - return $this->cache['url'] = $this->site->url(); - } else if($this->parent->isHomePage()) { - return $this->cache['url'] = $this->site->url() . '/' . $this->parent->uid . '/' . $this->uid; - } else { - $purl = $this->parent->url(); - return $this->cache['url'] = $purl == '/' ? '/' . $this->uid : $this->parent->url() . '/' . $this->uid; - } - - } - - /** - * Returns the full URL for the content folder - * - * @return string - */ - public function contentUrl() { - return $this->kirby()->urls()->content() . '/' . $this->diruri(); - } - - /** - * Builds and returns the short url for the current page - * - * @return string - */ - public function tinyurl() { - if(!$this->kirby->options['tinyurl.enabled']) { - return $this->url(); - } else { - return url($this->kirby->options['tinyurl.folder'] . '/' . $this->hash()); - } - } - - /** - * Returns a number indicating how deep the page - * is nested within the content folder - * - * @return int - */ - public function depth() { - return $this->depth; - } - - /** - * Returns the uri for the page - * which is being used for the url later - * - * @return string - */ - public function uri() { - return $this->uri; - } - - /** - * Returns the id, which is going to be used for - * Collection keys and things like that - * - * @return string - */ - public function id() { - return $this->id; - } - - /** - * Checks if the page can be cached - * - * @return boolean - */ - public function isCachable() { - - // The error page should not be cached - if($this->isErrorPage()) { - return false; - } - - foreach($this->kirby->option('cache.ignore') as $pattern) { - if(fnmatch($pattern, $this->uri()) === true) { - return false; - } - } - - return true; - - } - - /** - * Returns the page uid, which is the - * folder name without the sorting number - * - * @return string - */ - public function uid() { - return $this->uid; - } - - /** - * Alternative for $this->uid() - * - * @return string - */ - public function slug() { - return $this->uid; - } - - /** - * Returns the sorting number if it exists - * - * @return string - */ - public function num() { - return $this->num; - } - - /** - * Reads the directory and returns an inventory array - * - * @return array - */ - public function inventory() { - - if(isset($this->cache['inventory'])) return $this->cache['inventory']; - - // get all items within the directory - $ignore = array('.', '..', '.DS_Store', '.git', '.svn', 'Thumb.db'); - $items = array_diff(scandir($this->root), array_merge($ignore, (array)$this->kirby->option('content.file.ignore'))); - - // create the inventory - $this->cache['inventory'] = array( - 'children' => array(), - 'content' => array(), - 'meta' => array(), - 'thumbs' => array(), - 'files' => array(), - ); - - // normalize the filename if possible - if($this->kirby->option('content.file.normalize') && class_exists('Normalizer')) { - $items = array_map('Normalizer::normalize', $items); - } - - foreach($items as $item) { - - // skip any invisible files and folders - if(substr($item, 0, 1) === '.') continue; - - $root = $this->root . DS . $item; - - if(is_dir($root)) { - $this->cache['inventory']['children'][] = $item; - } else if(pathinfo($item, PATHINFO_EXTENSION) == $this->kirby->options['content.file.extension']) { - $this->cache['inventory']['content'][] = $item; - } else if(strpos($item, '.thumb.') !== false and preg_match('!\.thumb\.(jpg|jpeg|png|gif)$!i', $item)) { - // get the filename of the original image and use it as the array key - $image = str_replace('.thumb', '', $item); - // this makes it easier to find the corresponding image later - $this->cache['inventory']['thumbs'][$image] = $item; - } else { - $this->cache['inventory']['files'][] = $item; - } - - } - - foreach($this->cache['inventory']['thumbs'] as $key => $thumb) { - // remove invalid thumbs by looking for a matching image file and - if(!in_array($key, $this->cache['inventory']['files'])) { - $this->cache['inventory']['files'][] = $thumb; - unset($this->cache['inventory']['thumbs'][$key]); - } - } - - foreach($this->cache['inventory']['content'] as $key => $content) { - $file = pathinfo($content, PATHINFO_FILENAME); - if(in_array($file, $this->cache['inventory']['files'])) { - $this->cache['inventory']['meta'][$file] = $content; - unset($this->cache['inventory']['content'][$key]); - } - } - - // sort the children - natsort($this->cache['inventory']['children']); - - return $this->cache['inventory']; - - } - - /** - * Returns all children for this page - * - * @return Children - */ - public function children() { - - if(isset($this->cache['children'])) return $this->cache['children']; - - $this->cache['children'] = new Children($this); - - $inventory = $this->inventory(); - - // with page models - if(!empty(static::$models)) { - foreach($inventory['children'] as $dirname) { - $child = new Page($this, $dirname); - // let's create a model if one is defined - if(isset(static::$models[$child->intendedTemplate()])) { - $model = static::$models[$child->intendedTemplate()]; - $child = new $model($this, $dirname); - } - $this->cache['children']->data[$child->id()] = $child; - } - // without page models - } else { - foreach($inventory['children'] as $dirname) { - $child = new Page($this, $dirname); - $this->cache['children']->data[$child->id()] = $child; - } - } - - return $this->cache['children']; - - } - - /** - * Checks if the page has children - * - * @return boolean - */ - public function hasChildren() { - return $this->children()->count(); - } - - /** - * Checks if the page has visible children - * - * @return boolean - */ - public function hasVisibleChildren() { - return $this->children()->visible()->count(); - } - - /** - * Checks if the page has invisible children - * - * @return boolean - */ - public function hasInvisibleChildren() { - return $this->children()->invisible()->count(); - } - - /** - * Returns the grand children of this page - * - * @return Children - */ - public function grandChildren() { - return $this->children()->children(); - } - - /** - * Returns the siblings for this page, not including this page - * - * @param boolean $self - * @return Children - */ - public function siblings($self = true) { - return $self ? $this->parent->children() : $this->parent->children()->not($this); - } - - /** - * Internal method to return the next page - * - * @param object $siblings Children A collection of siblings to search in - * @param string $sort An optional sort field for the siblings - * @param string $direction An optional sort direction - * @return mixed Page or null - */ - protected function _next(Children $siblings, $sort = array(), $visibility = false) { - - if($sort) $siblings = call(array($siblings, 'sortBy'), $sort); - $index = $siblings->indexOf($this); - if($index === false) return null; - if($visibility) { - $siblings = $siblings->offset($index+1); - $siblings = $siblings->{$visibility}(); - return $siblings->first(); - } else { - return $siblings->nth($index + 1); - } - } - - /** - * Internal method to return the previous page - * - * @param object $siblings Children A collection of siblings to search in - * @param string $sort An optional sort field for the siblings - * @param string $direction An optional sort direction - * @return mixed Page or null - */ - protected function _prev(Children $siblings, $sort = array(), $visibility = false) { - if($sort) $siblings = call(array($siblings, 'sortBy'), $sort); - $index = $siblings->indexOf($this); - if($index === false or $index === 0) return null; - if($visibility) { - $siblings = $siblings->limit($index); - $siblings = $siblings->{$visibility}(); - return $siblings->last(); - } else { - return $siblings->nth($index - 1); - } - } - - /** - * Returns the next page element - * - * @return Page - */ - public function next() { - return $this->_next($this->parent->children(), func_get_args()); - } - - /** - * Checks if there's a next page - * - * @param string $sort An optional sort field for the siblings - * @param string $direction An optional sort direction - * @return boolean - */ - public function hasNext() { - return call(array($this, 'next'), func_get_args()) != null; - } - - /** - * Returns the next visible page in the current collection if available - * - * @param string $sort An optional sort field for the siblings - * @param string $direction An optional sort direction - * @return mixed Page or null - */ - public function nextVisible() { - if(!$this->parent) { - return null; - } else { - return $this->_next($this->parent->children(), func_get_args(), 'visible'); - } - } - - /** - * Checks if there's a next visible page - * - * @param string $sort An optional sort field for the siblings - * @param string $direction An optional sort direction - * @return boolean - */ - public function hasNextVisible() { - return call(array($this, 'nextVisible'), func_get_args()) != null; - } - - /** - * Returns the next invisible page in the current collection if available - * - * @param string $sort An optional sort field for the siblings - * @param string $direction An optional sort direction - * @return mixed Page or null - */ - public function nextInvisible() { - if(!$this->parent) { - return null; - } else { - return $this->_next($this->parent->children(), func_get_args(), 'invisible'); - } - } - - /** - * Checks if there's a next invisible page - * - * @param string $sort An optional sort field for the siblings - * @param string $direction An optional sort direction - * @return boolean - */ - public function hasNextInvisible() { - return call(array($this, 'nextInvisible'), func_get_args()) != null; - } - - /** - * Returns the previous page element - * - * @return Page - */ - public function prev() { - return $this->_prev($this->parent->children(), func_get_args()); - } - - /** - * Checks if there's a previous page - * - * @param string $sort An optional sort field for the siblings - * @param string $direction An optional sort direction - * @return boolean - */ - public function hasPrev() { - return call(array($this, 'prev'), func_get_args()) != null; - } - - /** - * Returns the previous visible page in the current collection if available - * - * @param string $sort An optional sort field for the siblings - * @param string $direction An optional sort direction - * @return mixed Page or null - */ - public function prevVisible() { - if(!$this->parent) { - return null; - } else { - return $this->_prev($this->parent->children(), func_get_args(), 'visible'); - } - } - - /** - * Checks if there's a previous visible page - * - * @param string $sort An optional sort field for the siblings - * @param string $direction An optional sort direction - * @return boolean - */ - public function hasPrevVisible() { - return call(array($this, 'prevVisible'), func_get_args()) != null; - } - - /** - * Returns the previous invisible page in the current collection if available - * - * @param string $sort An optional sort field for the siblings - * @param string $direction An optional sort direction - * @return mixed Page or null - */ - public function prevInvisible() { - if(!$this->parent) { - return null; - } else { - return $this->_prev($this->parent->children(), func_get_args(), 'invisible'); - } - } - - /** - * Checks if there's a previous invisible page - * - * @param string $sort An optional sort field for the siblings - * @param string $direction An optional sort direction - * @return boolean - */ - public function hasPrevInvisible() { - return call(array($this, 'prevInvisible'), func_get_args()) != null; - } - - /** - * Find any child or a set of children of this page - * - * @return Page | Children - */ - public function find() { - return call_user_func_array(array($this->children(), 'find'), func_get_args()); - } - - /** - * Find any file or a set of files for this page - * - * @return File | Files - */ - public function file() { - $args = func_get_args(); - if(empty($args)) return $this->files()->first(); - return call_user_func_array(array($this->files(), 'find'), $args); - } - - // file stuff - - /** - * Returns all files for this page - * - * @return Files - */ - public function files() { - if(isset($this->cache['files'])) return $this->cache['files']; - return $this->cache['files'] = new Files($this); - } - - /** - * Checks if this page has attached files - * - * @return boolean - */ - public function hasFiles() { - return $this->files()->count(); - } - - // File filters - public function images() { return $this->files()->filterBy('type', 'image'); } - public function videos() { return $this->files()->filterBy('type', 'video'); } - public function documents() { return $this->files()->filterBy('type', 'document'); } - public function audio() { return $this->files()->filterBy('type', 'audio'); } - public function code() { return $this->files()->filterBy('type', 'code'); } - public function archives() { return $this->files()->filterBy('type', 'archive'); } - - // File checkers - public function hasImages() { return $this->images()->count(); } - public function hasVideos() { return $this->videos()->count(); } - public function hasDocuments() { return $this->documents()->count(); } - public function hasAudio() { return $this->audio()->count(); } - public function hasCode() { return $this->code()->count(); } - public function hasArchives() { return $this->archives()->count(); } - - /** - * Returns a single image - * - * @return File - */ - public function image($filename = null) { - if(is_null($filename)) return $this->images()->first(); - return $this->images()->find($filename); - } - - /** - * Returns a single video - * - * @return File - */ - public function video($filename = null) { - if(is_null($filename)) return $this->videos()->first(); - return $this->videos()->find($filename); - } - - /** - * Returns a single document - * - * @return File - */ - public function document($filename = null) { - if(is_null($filename)) return $this->documents()->first(); - return $this->documents()->find($filename); - } - - - /** - * Returns the content object for this page - * - * @return Content - */ - public function content() { - - if(isset($this->cache['content'])) { - return $this->cache['content']; - } else { - $inventory = $this->inventory(); - return $this->cache['content'] = new Content($this, $this->root() . DS . array_shift($inventory['content'])); - } - - } - - /** - * Returns the title for this page and - * falls back to the uid if no title exists - * - * @return Field - */ - public function title() { - $title = $this->content()->get('title'); - if($title != '') { - return $title; - } else { - $title->value = $this->uid(); - return $title; - } - } - - /** - * Get formatted date fields - * - * @param string $format - * @param string $field - * @return mixed - */ - public function date($format = null, $field = 'date') { - - if($timestamp = strtotime($this->content()->$field())) { - if(is_null($format)) { - return $timestamp; - } else { - return $this->kirby->options['date.handler']($format, $timestamp); - } - } else { - return false; - } - - } - - /** - * Returns a unique hashed version of the uri, - * which is used for the tinyurl for example - * - * @return string - */ - public function hash() { - if(isset($this->cache['hash'])) return $this->cache['hash']; - - // add a unique hash - $checksum = sprintf('%u', crc32($this->uri())); - return $this->cache['hash'] = base_convert($checksum, 10, 36); - } - - /** - * Magic getter for all content fields - * - * @return Field - */ - public function __call($key, $arguments = null) { - if(isset($this->$key)) { - return $this->$key; - } else if(isset(static::$methods[$key])) { - if(!$arguments) $arguments = array(); - array_unshift($arguments, clone $this); - return call(static::$methods[$key], $arguments); - } else { - return $this->content()->get($key, $arguments); - } - } - - /** - * Alternative for $this->equals() - */ - public function is(Page $page) { - return $this->id() == $page->id(); - } - - /** - * Alternative for $this->is() - */ - public function equals(Page $page) { - return $this->is($page); - } - - /** - * Checks if this page object is the main site - * - * @return boolean - */ - public function isSite() { - return false; - } - - /** - * Checks if this is the active page - * - * @return boolean - */ - public function isActive() { - return $this->site->page()->is($this); - } - - /** - * Checks if the page is open - * - * @return boolean - */ - public function isOpen() { - if($this->isActive()) return true; - return $this->site->page()->parents()->has($this); - } - - /** - * Checks if the page is visible - * - * @return boolean - */ - public function isVisible() { - return !is_null($this->num); - } - - /** - * Checks if the page is invisible - * - * @return boolean - */ - public function isInvisible() { - return !$this->isVisible(); - } - - /** - * Checks if this page is the home page - * You can define the uri of the homepage in your config - * file with the home option. By default it's assumed - * that the homepage folder has the name "home" - * - * @return boolean - */ - public function isHomePage() { - return $this->uri === $this->kirby->options['home']; - } - - /** - * Checks if this page is the error page - * You can define the uri of the error page in your config - * file with the error option. By default it's assumed - * that the error page folder has the name "error" - * - * @return boolean - */ - public function isErrorPage() { - return $this->uri === $this->kirby->options['error']; - } - - /** - * Checks if the page is a child of the given page - * - * @param object Page the page object to check - * @return boolean - */ - public function isChildOf(Page $page) { - return $this->is($page) ? false : $this->parent->is($page); - } - - /** - * Checks if the page is the parent of the given page - * - * @param object Page the page object to check - * @return boolean - */ - public function isParentOf(Page $page) { - return $this->is($page) ? false : $page->parent->is($this); - } - - /** - * Checks if the page is a descendant of the given page - * - * @param object Page the page object to check - * @return boolean - */ - public function isDescendantOf(Page $page) { - return $this->is($page) ? false : $this->parents()->has($page); - } - - /** - * Checks if the page is a descendant of the currently active page - * - * @return boolean - */ - public function isDescendantOfActive() { - return $this->isDescendantOf($this->site->page()); - } - - /** - * Checks if the page is an ancestor of the given page - * - * @param object Page the page object to check - * @return boolean - */ - public function isAncestorOf($page) { - return $page->isDescendantOf($this); - } - - /** - * Checks if the page or any of its files are writable - * - * @return boolean - */ - public function isWritable() { - - $folder = new Folder($this->root()); - - if(!$folder->isWritable()) return false; - - foreach($folder->files() as $f) { - if(!$f->isWritable()) return false; - } - - return true; - - } - - /** - * Returns the timestamp when the page - * has been modified - * - * @return int - */ - public function modified($format = null, $handler = null) { - return f::modified($this->root, $format, $handler ? $handler : $this->kirby->options['date.handler']); - } - - /** - * Returns the index starting from this page - * - * @return Children - */ - public function index() { - return $this->children()->index(); - } - - /** - * Search in subpages and all descendants of this page - * - * @param string $query - * @param array $params - * @return Children - */ - public function search($query, $params = array()) { - return $this->children()->index()->search($query, $params); - } - - // template stuff - - /** - * Returns the name of the used template - * The name of the template is defined by the name - * of the content text file. - * - * i.e. text file: project.txt / template name: project - * - * This method returns the name of the default template - * if there's no template with such a name - * - * @return string - */ - public function template() { - - // check for a cached template name - if(isset($this->cache['template'])) return $this->cache['template']; - - // get the template name - $templateName = $this->intendedTemplate(); - - if($this->kirby->registry->get('template', $templateName)) { - return $this->cache['template'] = $templateName; - } else { - return $this->cache['template'] = 'default'; - } - - } - - /** - * Returns the full path to the used template file - * - * @return string - */ - public function templateFile() { - if($template = $this->kirby->registry->get('template', $this->intendedTemplate())) { - return $template; - } else { - return $this->kirby->registry->get('template', 'default'); - } - } - - /** - * Additional data, which will be passed to the template - * - * @return array - */ - public function templateData() { - return array(); - } - - /** - * Returns the name of the content text file / intended template - * So even if there's no such template it will return the intended name. - * - * @return string - */ - public function intendedTemplate() { - if(isset($this->cache['intendedTemplate'])) return $this->cache['intendedTemplate']; - return $this->cache['intendedTemplate'] = $this->content()->exists() ? $this->content()->name() : 'default'; - } - - /** - * Returns the full path to the intended template file - * This template file may not exist. - * - * @return string - */ - public function intendedTemplateFile() { - return $this->kirby->component('template')->file($this->intendedTemplate()); - } - - /** - * Checks if there's a dedicated template for this page - * Will return false when the default template is used - * - * @return boolean - */ - public function hasTemplate() { - return $this->intendedTemplate() == $this->template(); - } - - /** - * Sends all appropriate headers for this page - * Can be configured with the headers config array, - * which should contain all header definitions for each template - */ - public function headers() { - - $template = $this->template(); - if(isset($this->kirby->options['headers'][$template])) { - $headers = $this->kirby->options['headers'][$template]; - - if(is_numeric($headers)) { - header::status($headers); - } else if(is_callable($headers)) { - call($headers, $this); - } - - } else if($this->isErrorPage()) { - header::notfound(); - } - - } - - /** - * Returns the root for the content file - * - * @return string - */ - public function textfile($template = null) { - if(is_null($template)) $template = $this->intendedTemplate(); - return textfile($this->diruri(), $template); - } - - /** - * Private method to create a page directory - */ - static protected function createDirectory($uri) { - - $uid = str::slug(basename($uri)); - $parentURI = dirname($uri); - $parent = ($parentURI == '.' or empty($parentURI) or $parentURI == DS) ? site() : page($parentURI); - - if(!$parent) { - throw new Exception('The parent does not exist'); - } - - // check for an entered sorting number - if(preg_match('!^(\d+)\-(.*)!', $uid, $matches)) { - $num = $matches[1]; - $uid = $matches[2]; - $dir = $num . '-' . $uid; - } else { - $num = false; - $dir = $uid; - } - - // make sure to check a fresh page - $parent->reset(); - - if($parent->children()->findBy('uid', $uid)) { - throw new Exception('The page UID exists'); - } - - if(!dir::make($parent->root() . DS . $dir)) { - throw new Exception('The directory could not be created'); - } - - // make sure the new directory is available everywhere - $parent->reset(); - - return $parent->id() . '/' . $uid; - - } - - /** - * Creates a new page object - * - * @param string $uri - * @param string $template - * @param array $data - */ - static public function create($uri, $template, $data = array()) { - - if(!is_string($template) or empty($template)) { - throw new Exception('Please pass a valid template name as second argument'); - } - - // try to create the new directory - $uri = static::createDirectory($uri); - - // create the path for the textfile - $file = textfile($uri, $template); - - // try to store the data in the text file - if(!data::write($file, $data, 'kd')) { - throw new Exception('The page file could not be created'); - } - - // get the new page object - $page = page($uri); - - if(!is_a($page, 'Page')) { - throw new Exception('The new page object could not be found'); - } - - // let's create a model if one is defined - if(isset(static::$models[$template])) { - $model = static::$models[$template]; - $page = new $model($page->parent(), $page->dirname()); - } - - kirby::instance()->cache()->flush(); - - return $page; - - } - - /** - * Update the page with a new set of data - * - * @param array - */ - public function update($input = array()) { - - $data = a::update($this->content()->toArray(), $input); - - if(!data::write($this->textfile(), $data, 'kd')) { - throw new Exception('The page could not be updated'); - } - - $this->kirby->cache()->flush(); - $this->reset(); - $this->touch(); - return true; - - } - - /** - * Increment a field value by one or a given value - * - * @param string $field - * @param int $by - * @param int $max - * @return Page - */ - public function increment($field, $by = 1, $max = null) { - $this->update(array( - $field => function($value) use($by, $max) { - $new = (int)$value + $by; - return ($max and $new >= $max) ? $max : $new; - } - )); - return $this; - } - - /** - * Decrement a field value by one or a given value - * - * @param string $field - * @param int $by - * @param int $min - * @return Page - */ - public function decrement($field, $by = 1, $min = 0) { - $this->update(array( - $field => function($value) use($by, $min) { - $new = (int)$value - $by; - return $new <= $min ? $min : $new; - } - )); - return $this; - } - - /** - * Changes the uid for the page - * - * @param string $uid - */ - public function move($uid) { - - $uid = str::slug($uid); - - if(empty($uid)) { - throw new Exception('The uid is missing'); - } - - // don't do anything if the uid exists - if($this->uid() === $uid) return true; - - // check for an existing page with the same UID - if($this->siblings()->not($this)->find($uid)) { - throw new Exception('A page with this uid already exists'); - } - - $dir = $this->isVisible() ? $this->num() . '-' . $uid : $uid; - $root = dirname($this->root()) . DS . $dir; - - if(!dir::move($this->root(), $root)) { - throw new Exception('The directory could not be moved'); - } - - $this->dirname = $dir; - $this->root = $root; - $this->uid = $uid; - - // assign a new id and uri - $this->id = $this->uri = ltrim($this->parent->id() . '/' . $this->uid, '/'); - - // clean the cache - $this->kirby->cache()->flush(); - $this->reset(); - return true; - - } - - /** - * Return the prepended number for the page - * or changes it to the number passed as parameter - */ - public function sort($num = null) { - - if(!$num and $num !== 0) return $this->num(); - if($num === $this->num()) return true; - - $dir = $num . '-' . $this->uid(); - $root = dirname($this->root()) . DS . $dir; - - if(!dir::move($this->root(), $root)) { - throw new Exception('The directory could not be moved'); - } - - $this->dirname = $dir; - $this->num = $num; - $this->root = $root; - $this->kirby->cache()->flush(); - $this->reset(); - return true; - - } - - /** - * Make the page invisible by removing the prepended number - */ - public function hide() { - - if($this->isInvisible()) return true; - - $root = dirname($this->root()) . DS . $this->uid(); - - if(!dir::move($this->root(), $root)) { - throw new Exception('The directory could not be moved'); - } - - $this->dirname = $this->uid(); - $this->num = null; - $this->root = $root; - $this->kirby->cache()->flush(); - $this->reset(); - return true; - - } - - public function isDeletable() { - - if($this->isSite()) return false; - if($this->isHomePage()) return false; - if($this->isErrorPage()) return false; - - return true; - - } - - /** - * Deletes the page - * - * @param boolean $force Forces the page to be deleted even if there are subpages - */ - public function delete($force = false) { - - if(!$this->isDeletable()) { - throw new Exception('The page cannot be deleted'); - } - - if($force === false and $this->children()->count()) { - throw new Exception('This page has subpages'); - } - - $parent = $this->parent(); - - if(!dir::remove($this->root())) { - throw new Exception('The page could not be deleted'); - } - - $this->kirby->cache()->flush(); - $parent->reset(); - return true; - - } - - /** - * Converts the entire page object into - * a plain PHP array - * - * @param closure $callback Filter callback - * @return array - */ - public function toArray($callback = null) { - - $data = array( - 'id' => $this->id(), - 'title' => $this->title()->toString(), - 'parent' => $this->parent()->uri(), - 'dirname' => $this->dirname(), - 'diruri' => $this->diruri(), - 'url' => $this->url(), - 'contentUrl' => $this->contentUrl(), - 'tinyUrl' => $this->tinyUrl(), - 'depth' => $this->depth(), - 'uri' => $this->uri(), - 'root' => $this->root(), - 'uid' => $this->uid(), - 'slug' => $this->slug(), - 'num' => $this->num(), - 'hash' => $this->hash(), - 'modified' => $this->modified(), - 'template' => $this->template(), - 'intendedTemplate' => $this->intendedTemplate(), - 'content' => $this->content()->toArray(), - ); - - if(is_null($callback)) { - return $data; - } else if(is_callable($callback)) { - return $callback($this); - } - - } - - /** - * Tries to find a controller for - * the current page and loads the data - * - * @return array - */ - public function controller($arguments = array()) { - - $controller = $this->kirby->registry->get('controller', $this->template()); - - if(is_a($controller, 'Closure')) { - return (array)call_user_func_array($controller, array( - $this->site, - $this->site->children(), - $this, - $arguments - )); - } - - return array(); - - } - - /** - * Converts the entire page array into - * a json string - * - * @param closure $callback Filter callback - * @return string - */ - public function toJson($callback = null) { - return json_encode($this->toArray($callback)); - } - - /** - * Makes it possible to echo the entire object - * - * @return string - */ - public function __toString() { - return (string)$this->id(); - } - -} diff --git a/kirby/core/pages.php b/kirby/core/pages.php deleted file mode 100644 index 2095097..0000000 --- a/kirby/core/pages.php +++ /dev/null @@ -1,330 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class PagesAbstract extends Collection { - - static public $methods = array(); - - /** - * Constructor - */ - public function __construct($data = array()) { - foreach($data as $object) { - $this->add($object); - } - } - - public function __call($method, $arguments) { - - if(isset(static::$methods[$method])) { - array_unshift($arguments, clone $this); - return call(static::$methods[$method], $arguments); - } else { - return $this->get($method); - } - - } - - /** - * Adds a single page object to the - * collection by id or the entire object - * - * @param mixed $page - */ - public function add($page) { - - if(is_a($page, 'Collection')) { - foreach($page as $object) $this->add($object); - } else if(is_string($page) and $object = page($page)) { - $this->data[$object->id()] = $object; - } else if(is_a($page, 'Page')) { - $this->data[$page->id()] = $page; - } - - return $this; - - } - - /** - * Returns a new collection of pages without the given pages - * - * @param args any number of uris or page elements, passed as individual arguments - * @return object a new collection without the pages - */ - public function not() { - $collection = clone $this; - foreach(func_get_args() as $uri) { - if(is_array($uri) or $uri instanceof Traversable) { - foreach($uri as $u) { - $collection = $collection->not($u); - } - } else if(is_a($uri, 'Page')) { - // unset by Page object - unset($collection->data[$uri->id()]); - } else if(isset($collection->data[$uri])) { - // unset by URI - unset($collection->data[$uri]); - } else if($page = $collection->findBy('uid', $uri)) { - // unset by UID - unset($collection->data[$page->id()]); - } - } - return $collection; - } - - public function find() { - - $args = func_get_args(); - - if(!count($args)) { - return false; - } - - if(count($args) === 1 and is_array($args[0])) { - $args = $args[0]; - } - - if(count($args) > 1) { - $pages = new static(); - foreach($args as $id) { - if($page = $this->find($id)) { - $pages->data[$page->id()] = $page; - } - } - return $pages; - } else { - - // get the first argument and remove slashes - $id = trim($args[0], '/'); - - // fast access to direct uris - return isset($this->data[$id]) ? $this->data[$id] : null; - - } - - } - - /** - * Find a single page by a given value - * - * @param string $field - * @param string $value - * @return Page - */ - public function findBy($field, $value) { - foreach($this->data as $page) { - if($page->$field() == $value) return $page; - } - return false; - } - - /** - * Find the open page in a set - * - * @return Page - */ - public function findOpen() { - return $this->findBy('isOpen', true); - } - - /** - * Filters the collection by visible pages - * - * @return Children - */ - public function visible() { - $collection = clone $this; - return $collection->filterBy('isVisible', true); - } - - /** - * Filters the collection by invisible pages - * - * @return Children - */ - public function invisible() { - $collection = clone $this; - return $collection->filterBy('isInvisible', true); - } - - /** - * Checks if a page is in a set of children - * - * @param Page | string $page - * @return boolean - */ - public function has($page) { - $uri = is_string($page) ? $page : $page->id(); - return parent::has($uri); - } - - /** - * Native search method to search for anything within the collection - */ - public function search($query, $params = array()) { - - if(is_string($params)) { - $params = array('fields' => str::split($params, '|')); - } - - $defaults = array( - 'minlength' => 2, - 'fields' => array(), - 'words' => false, - 'score' => array() - ); - - $options = array_merge($defaults, $params); - $collection = clone $this; - $searchwords = preg_replace('/(\s)/u',',', $query); - $searchwords = str::split($searchwords, ',', $options['minlength']); - - if(!empty($options['stopwords'])) { - $searchwords = array_diff($searchwords, $options['stopwords']); - } - - if(empty($searchwords)) return $collection->limit(0); - - $searchwords = array_map(function($value) use($options) { - return $options['words'] ? '\b' . preg_quote($value) . '\b' : preg_quote($value); - }, $searchwords); - - $preg = '!(' . implode('|', $searchwords) . ')!i'; - $results = $collection->filter(function($page) use($query, $searchwords, $preg, $options) { - - $data = $page->content()->toArray(); - $keys = array_keys($data); - - if(!empty($options['fields'])) { - $keys = array_intersect($keys, $options['fields']); - } - - $page->searchHits = 0; - $page->searchScore = 0; - - foreach($keys as $key) { - - $score = a::get($options['score'], $key, 1); - - // check for a match - if($matches = preg_match_all($preg, $data[$key], $r)) { - - $page->searchHits += $matches; - $page->searchScore += $matches * $score; - - // check for full matches - if($matches = preg_match_all('!' . preg_quote($query) . '!i', $data[$key], $r)) { - $page->searchScore += $matches * $score; - } - - } - - } - - return $page->searchHits > 0 ? true : false; - - }); - - $results = $results->sortBy('searchScore', SORT_DESC); - - return $results; - - } - - /** - * Returns files from all pages - * - * @return object A collection of all files of the pages (not of their subpages) - */ - public function files() { - - $files = new Collection(); - - foreach($this->data as $page) { - foreach($page->files() as $file) { - $files->append($page->id() . '/' . strtolower($file->filename()), $file); - } - } - - return $files; - - } - - // File type filters - public function images() { return $this->files()->filterBy('type', 'image'); } - public function videos() { return $this->files()->filterBy('type', 'video'); } - public function documents() { return $this->files()->filterBy('type', 'document'); } - public function audio() { return $this->files()->filterBy('type', 'audio'); } - public function code() { return $this->files()->filterBy('type', 'code'); } - public function archives() { return $this->files()->filterBy('type', 'archive'); } - - /** - * Groups the pages by a given field - * - * @param string $field - * @param bool $i (ignore upper/lowercase for group names) - * @return object A collection with an item for each group and a Pages object for each group - */ - public function groupBy($field, $i = true) { - - $groups = array(); - - foreach($this->data as $key => $item) { - - $value = $item->content()->get($field)->value(); - - // make sure that there's always a proper value to group by - if(!$value) throw new Exception('Invalid grouping value for key: ' . $key); - - // ignore upper/lowercase for group names - if($i) $value = str::lower($value); - - if(!isset($groups[$value])) { - // create a new entry for the group if it does not exist yet - $groups[$value] = new Pages(array($key => $item)); - } else { - // add the item to an existing group - $groups[$value]->set($key, $item); - } - - } - - return new Collection($groups); - - } - - /** - * Converts the pages collection - * into a plain array - * - * @param closure $callback Filter callback for each item - * @return array - */ - public function toArray($callback = null) { - $data = array(); - foreach($this as $page) { - $data[] = is_string($page) ? $page : $page->toArray($callback); - } - return $data; - } - - /** - * Converts the pages collection - * into a json string - * - * @param closure $callback Filter callback for each item - * @return string - */ - public function toJson($callback = null) { - return json_encode($this->toArray($callback)); - } - -} \ No newline at end of file diff --git a/kirby/core/role.php b/kirby/core/role.php deleted file mode 100644 index bbfb897..0000000 --- a/kirby/core/role.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class RoleAbstract { - - protected $id = null; - protected $name = null; - protected $panel = false; - protected $permissions = array( - 'panel.access' => true, - 'panel.site.update' => true, - 'panel.page.create' => true, - 'panel.page.update' => true, - 'panel.page.move' => true, - 'panel.page.sort' => true, - 'panel.page.hide' => true, - 'panel.page.delete' => true, - 'panel.file.upload' => true, - 'panel.file.replace' => true, - 'panel.file.update' => true, - 'panel.file.delete' => true, - 'panel.user.add' => true, - 'panel.user.edit' => true, - 'panel.user.role' => true, - 'panel.user.delete' => true, - ); - - public $default = false; - - public function __construct($data = array()) { - - if(!isset($data['id'])) throw new Exception('The role id is missing'); - if(!isset($data['name'])) throw new Exception('The role name is missing'); - - // required data - $this->id = $data['id']; - $this->name = $data['name']; - - if(isset($data['permissions']) and is_array($data['permissions'])) { - $this->permissions = a::merge($this->permissions, $data['permissions']); - } else if(isset($data['permissions']) and $data['permissions'] === false) { - $this->permissions = array_fill_keys(array_keys($this->permissions), false); - } else { - $this->permissions = $this->permissions; - } - - // fallback permissions support for old 'panel' role variable - if(isset($data['panel']) and is_bool($data['panel'])) { - $this->permissions['panel.access'] = $data['panel']; - } - - // is this role the default role? - if(isset($data['default'])) { - $this->default = $data['default'] === true; - } - - } - - public function id() { - return $this->id; - } - - public function name() { - return $this->name; - } - - // support for old 'panel' role permission - public function hasPanelAccess() { - return $this->hasPermission('panel.access'); - } - - public function hasPermission($target) { - if($this->id == 'admin') { - return true; - } else if(isset($this->permissions[$target]) and $this->permissions[$target] === true) { - return true; - } else { - return false; - } - } - - public function isDefault() { - return $this->default; - } - - public function users() { - return kirby::instance()->site()->users()->filterBy('role', $this->id); - } - - public function __toString() { - return (string)$this->id; - } - -} diff --git a/kirby/core/roles.php b/kirby/core/roles.php deleted file mode 100644 index 2d7ff69..0000000 --- a/kirby/core/roles.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class RolesAbstract extends Collection { - - // cache for the default role - protected $default = null; - - /** - * Constructor - */ - public function __construct() { - - $roles = kirby::instance()->option('roles'); - - // set the default set of roles, if roles are not configured - if(empty($roles)) { - $roles = array( - array( - 'id' => 'admin', - 'name' => 'Admin', - 'default' => true - ), - array( - 'id' => 'editor', - 'name' => 'Editor', - 'permissions' => array( - 'panel.access' => true, - 'panel.site.update' => false, - 'panel.page.create' => true, - 'panel.page.update' => true, - 'panel.page.move' => true, - 'panel.page.sort' => true, - 'panel.page.hide' => true, - 'panel.page.delete' => true, - 'panel.file.upload' => true, - 'panel.file.replace' => true, - 'panel.file.update' => true, - 'panel.file.delete' => true, - 'panel.user.add' => false, - 'panel.user.edit' => false, - 'panel.user.role' => false, - 'panel.user.delete' => false - ) - ) - ); - } - - foreach($roles as $role) { - $role = new Role($role); - $this->data[$role->id()] = $role; - } - - // check for a valid admin role - if(!isset($this->data['admin'])) { - throw new Exception('There must be an admin role'); - } - - // check for a valid default role - if(!$this->findDefault()) { - $this->data['admin']->default = true; - } - - } - - /** - * Returns the default role for new users - * - * @return Role - */ - public function findDefault() { - if(!is_null($this->default)) return $this->default; - return $this->default = $this->findBy('isDefault', true); - } - -} diff --git a/kirby/core/site.php b/kirby/core/site.php deleted file mode 100644 index 1180471..0000000 --- a/kirby/core/site.php +++ /dev/null @@ -1,337 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class SiteAbstract extends Page { - - // the current page - public $page = null; - - /** - * Constructor - * - */ - public function __construct(Kirby $kirby) { - - $this->kirby = $kirby; - $this->url = $kirby->urls()->index(); - $this->depth = 0; - $this->uri = ''; - $this->site = $this; - $this->page = null; - - // build ugly urls if rewriting is disabled - if($this->kirby->options['rewrite'] === false) { - $this->url .= '/index.php'; - } - - $this->root = $kirby->roots()->content(); - $this->dirname = basename($this->root); - - } - - /** - * Cleans the temporary internal cache - */ - public function reset() { - $this->cache = array(); - } - - /** - * The id is an empty string in case of the site object - * - * @return string - */ - public function id() { - return ''; - } - - /** - * The base diruri is bascially just an empty string - * - * @return string - */ - public function diruri() { - return ''; - } - - /** - * Returns the base url for the site - * - * @return string - */ - public function url() { - return $this->url; - } - - /** - * Returns the full URL for the content folder - * - * @return string - */ - public function contentUrl() { - return $this->kirby()->urls()->content(); - } - - /** - * Checks if this object is the main site - * - * @return boolean - */ - public function isSite() { - return true; - } - - /** - * Returns the usable template - * - * @return string - */ - public function template() { - return 'site'; - } - - /** - * The site has no template - * - * @return boolean - */ - public function templateFile() { - return false; - } - - /** - * Returns the intended template - * - * @return string - */ - public function intendedTemplate() { - return 'site'; - } - - /** - * Again, the site has no template! - * - * @return boolean - */ - public function intendedTemplateFile() { - return false; - } - - /** - * There can't be a template for the site - * Didn't you still get it yet? - * - * @return boolean - */ - public function hasTemplate() { - return false; - } - - /** - * Sets the currently active page - * and returns its page object - * - * @param string $uri - * @return Page - */ - public function visit($uri = '') { - - $uri = trim($uri, '/'); - - if(empty($uri)) { - return $this->page = $this->homePage(); - } else { - if($page = $this->children()->find($uri)) { - return $this->page = $page; - } else { - return $this->page = $this->errorPage(); - } - } - - } - - /** - * Returns the currently active page or any other page by uri - * - * @param string $uri Optional uri to get any page on the site - * @return Page - */ - public function page($uri = null) { - if(is_null($uri)) { - return is_null($this->page) ? $this->page = $this->homePage() : $this->page; - } else { - return $this->children()->find($uri); - } - } - - /** - * Alternative for $this->children() - * - * @return Children - */ - public function pages() { - return $this->children(); - } - - /** - * Builds a breadcrumb collection - * - * @return Children - */ - public function breadcrumb() { - - if(isset($this->cache['breadcrumb'])) return $this->cache['breadcrumb']; - - // get all parents and flip the order - $crumb = $this->page()->parents()->flip(); - - // add the home page - $crumb->prepend($this->homePage()->uri(), $this->homePage()); - - // add the active page - $crumb->append($this->page()->uri(), $this->page()); - - return $this->cache['breadcrumb'] = $crumb; - - } - - /** - * Alternative for $this->page() - * - * @return Page - */ - public function activePage() { - return $this->page(); - } - - /** - * Returns the error page object - * - * @return Page - */ - public function errorPage() { - if(isset($this->cache['errorPage'])) return $this->cache['errorPage']; - return $this->cache['errorPage'] = $this->children()->find($this->kirby->options['error']); - } - - /** - * Returns the home page object - * - * @return Page - */ - public function homePage() { - if(isset($this->cache['homePage'])) return $this->cache['homePage']; - return $this->cache['homePage'] = $this->children()->find($this->kirby->options['home']); - } - - /** - * Returns the locale for the site - * - * @return string - */ - public function locale() { - return isset($this->kirby->options['locale']) ? $this->kirby->options['locale'] : 'en_US'; - } - - /** - * Checks if the site is a multi language site - * - * @return boolean - */ - public function multilang() { - return false; - } - - /** - * Placeholder for multilanguage sites - */ - public function languages() { - return null; - } - - /** - * Placeholder for multilanguage sites - */ - public function language() { - return null; - } - - /** - * Placeholder for multilanguage sites - */ - public function defaultLanguage() { - return null; - } - - /** - * Return the detected language - */ - public function detectedLanguage() { - return null; - } - - /** - * Returns a collection of all users - * - * @return Users - */ - public function users() { - return new Users(); - } - - /** - * Returns the current user - * - * @param string $username Optional way to search for a single user - * @return User - */ - public function user($username = null) { - if(is_null($username)) return User::current(); - try { - return new User($username); - } catch(Exception $e) { - return null; - } - } - - /** - * Returns a collection of all roles - * - * @return Roles - */ - public function roles() { - return new Roles(); - } - - /** - * Gets the last modification date of all pages - * in the content folder. - * - * @param mixed $format - * @param mixed $handler - * @return mixed - */ - public function modified($format = null, $handler = null) { - return dir::modified($this->root, $format, $handler ? $handler : $this->kirby->options['date.handler']); - } - - /** - * Checks if any content of the site has been - * modified after the given unix timestamp - * This is mainly used to auto-update the cache - * - * @return boolean - */ - public function wasModifiedAfter($time) { - return dir::wasModifiedAfter($this->root(), $time); - } - -} \ No newline at end of file diff --git a/kirby/core/user.php b/kirby/core/user.php deleted file mode 100644 index f004a14..0000000 --- a/kirby/core/user.php +++ /dev/null @@ -1,349 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class UserAbstract { - - protected $username = null; - protected $cache = array(); - protected $data = null; - - public function __construct($username) { - - $this->username = str::slug(basename($username)); - - // check if the account file exists - if(!file_exists($this->file())) { - throw new Exception('The user account could not be found'); - } - - } - - /** - * Returns the username - * - * @return string - */ - public function username() { - return $this->username; - } - - /** - * get all data for the user - */ - public function data() { - - if(!is_null($this->data)) return $this->data; - - // get all data from the account file - $this->data = data::read($this->file(), 'yaml'); - - // make sure all keys are lowercase - $this->data = array_change_key_case($this->data, CASE_LOWER); - - // remove garbage - unset($this->data[0]); - - // add the username - $this->data['username'] = $this->username; - - // return the data array - return $this->data; - - } - - public function __get($key) { - return a::get($this->data(), strtolower($key)); - } - - public function __call($key, $arguments = null) { - return $this->__get($key); - } - - public function role() { - - $roles = kirby::instance()->site()->roles(); - $data = $this->data(); - - if(empty($data['role'])) { - // apply the default role, if no role is stored for the user - $data['role'] = $roles->findDefault()->id(); - } - - // return the role by id - if($role = $roles->get($data['role'])) { - return $role; - } else { - return $roles->findDefault(); - } - - } - - public function hasRole() { - $roles = func_get_args(); - return in_array($this->role()->id(), $roles); - } - - // support for old 'panel' role permission - public function hasPanelAccess() { - return $this->role()->hasPermission('panel.access'); - } - - public function hasPermission($target) { - return $this->role()->hasPermission($target); - } - - public function isAdmin() { - return $this->role()->id() == 'admin'; - } - - public function avatar() { - - if(isset($this->cache['avatar'])) return $this->cache['avatar']; - - $avatar = new Avatar($this); - - return $this->cache['avatar'] = $avatar->exists() ? $avatar : false; - - } - - public function avatarRoot($extension = 'jpg') { - return kirby::instance()->roots()->avatars() . DS . $this->username() . '.' . $extension; - } - - public function gravatar($size = 256) { - return gravatar($this->email(), $size); - } - - protected function file() { - return kirby::instance()->roots()->accounts() . DS . $this->username() . '.php'; - } - - public function textfile() { - return $this->file(); - } - - public function exists() { - return file_exists($this->file()); - } - - public function generateKey() { - return str::random(64); - } - - public function generateSecret($key) { - return sha1($this->username() . $key); - } - - public function login($password) { - - static::logout(); - - if(!password::match($password, $this->password)) return false; - - // create a new session id - s::regenerateId(); - - $key = $this->generateKey(); - $secret = $this->generateSecret($key); - - s::set('kirby_auth_secret', $secret); - s::set('kirby_auth_username', $this->username()); - - cookie::set( - s::$name . '_auth', - $key, - s::$cookie['lifetime'], - s::$cookie['path'], - s::$cookie['domain'], - s::$cookie['secure'], - s::$cookie['httponly'] - ); - - return true; - - } - - static public function logout() { - s::destroy(); - cookie::remove(s::$name . '_auth'); - } - - public function is($user) { - if(!is_a($user, 'User')) return false; - return $this->username() === $user->username(); - } - - public function isCurrent() { - return $this->is(static::current()); - } - - static public function validate($data = array(), $mode = 'insert') { - - if($mode == 'insert') { - - if(empty($data['username'])) { - throw new Exception('Invalid username'); - } - - if(empty($data['password'])) { - throw new Exception('Invalid password'); - } - - } - - if(!empty($data['email']) and !v::email($data['email'])) { - throw new Exception('Invalid email'); - } - - } - - public function update($data = array()) { - - // sanitize the given data - $data = $this->sanitize($data, 'update'); - - // validate the updated dataset - $this->validate($data, 'update'); - - // don't update the username - unset($data['username']); - - // create a new hash for the password - if(!empty($data['password'])) { - $data['password'] = password::hash($data['password']); - } - - // merge with existing fields - $this->data = array_merge($this->data(), $data); - - foreach($this->data as $key => $value) { - if(is_null($value)) unset($this->data[$key]); - } - - // save the new user data - static::save($this->file(), $this->data); - - // return the updated user project - return $this; - - } - - public function delete() { - - if($avatar = $this->avatar()) { - $avatar->delete(); - } - - if(!f::remove($this->file())) { - throw new Exception('The account could not be deleted'); - } else { - return true; - } - - } - - static public function sanitize($data, $mode = 'insert') { - - // all usernames must be lowercase - $data['username'] = str::slug(a::get($data, 'username')); - - // convert all keys to lowercase - $data = array_change_key_case($data, CASE_LOWER); - - // return the cleaned up data - return $data; - - } - - /** - * Creates a new user - * - * @param array $user - * @return User - */ - static public function create($data = array()) { - - // sanitize the given data for the new user - $data = static::sanitize($data, 'insert'); - - // validate the dataset - static::validate($data, 'insert'); - - // create the file root - $file = kirby::instance()->roots()->accounts() . DS . $data['username'] . '.php'; - - // check for an existing username - if(file_exists($file)) { - throw new Exception('The username is taken'); - } - - // create a new hash for the password - if(!empty($data['password'])) { - $data['password'] = password::hash($data['password']); - } - - static::save($file, $data); - - // return the created user project - return new static($data['username']); - - } - - static protected function save($file, $data) { - - $yaml = '' . PHP_EOL . PHP_EOL; - $yaml .= data::encode($data, 'yaml'); - - if(!f::write($file, $yaml)) { - throw new Exception('The user account could not be saved'); - } else { - return true; - } - - } - - static public function unauthorize() { - s::remove('kirby_auth_secret'); - s::remove('kirby_auth_username'); - cookie::remove('kirby_auth'); - } - - static public function current() { - - $cookey = cookie::get(s::$name . '_auth'); - $username = s::get('kirby_auth_username'); - - if(empty($cookey)) { - static::unauthorize(); - return false; - } - - if(s::get('kirby_auth_secret') !== sha1($username . $cookey)) { - static::unauthorize(); - return false; - } - - // find the logged in user by token - try { - $user = new static($username); - return $user; - } catch(Exception $e) { - static::unauthorize(); - return false; - } - - } - - public function __toString() { - return (string)$this->username; - } - -} \ No newline at end of file diff --git a/kirby/core/users.php b/kirby/core/users.php deleted file mode 100644 index f0e1f31..0000000 --- a/kirby/core/users.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -abstract class UsersAbstract extends Collection { - - public function __construct() { - - $root = kirby::instance()->roots()->accounts(); - - foreach(dir::read($root) as $file) { - - // skip invalid account files - if(f::extension($file) != 'php') continue; - - $user = new User(f::name($file)); - $this->append($user->username(), $user); - - } - - } - - public function create($data) { - return user::create($data); - } - - public function find($username) { - return $this->findBy('username', $username); - } - -} \ No newline at end of file diff --git a/kirby/extensions/methods.php b/kirby/extensions/methods.php deleted file mode 100644 index 33034f4..0000000 --- a/kirby/extensions/methods.php +++ /dev/null @@ -1,279 +0,0 @@ -value = html($field->value, $keepTags); - return $field; -}; - -/** - * Escapes unwanted characters in the field value - * to protect from possible xss attacks or other - * unwanted side effects in your html code - * @param Field $field The calling Kirby Field instance - * @param string $context html|attr|css|js|url - * @return Field - */ -field::$methods['escape'] = field::$methods['esc'] = function($field, $context = 'html') { - $field->value = esc($field->value, $context); - return $field; -}; - -/** - * Converts html entities and specialchars in the field - * value to valid xml entities - * @param Field $field The calling Kirby Field instance - * @return Field - */ -field::$methods['xml'] = field::$methods['x'] = function($field) { - $field->value = xml($field->value); - return $field; -}; - -/** - * Parses the field value as kirbytext - * @param Field $field The calling Kirby Field instance - * @return Field - */ -field::$methods['kirbytext'] = field::$methods['kt'] = function($field) { - $field->value = kirbytext($field); - return $field; -}; - -/** - * Parses the field value as markdown - * @param Field $field The calling Kirby Field instance - * @return Field - */ -field::$methods['markdown'] = field::$methods['md'] = function($field) { - $field->value = markdown($field->value); - return $field; -}; - -/** - * Converts the field value to lower case - * @param Field $field The calling Kirby Field instance - * @return Field - */ -field::$methods['lower'] = function($field) { - $field->value = str::lower($field->value); - return $field; -}; - -/** - * Converts the field value to upper case - * @param Field $field The calling Kirby Field instance - * @return Field - */ -field::$methods['upper'] = function($field) { - $field->value = str::upper($field->value); - return $field; -}; - -/** - * Applies the widont rule to avoid single - * words on the last line - * @param Field $field The calling Kirby Field instance - * @return Field - */ -field::$methods['widont'] = function($field) { - $field->value = widont($field->value); - return $field; -}; - -/** - * Creates a simple text excerpt without formats - * @param Field $field The calling Kirby Field instance - * @param integer $chars The desired excerpt length - * @return string - */ -field::$methods['excerpt'] = function($field, $chars = 140, $mode = 'chars') { - return excerpt($field, $chars, $mode); -}; - -/** - * Shortens the field value by the given length - * @param Field $field The calling Kirby Field instance - * @param integer $length The desired string length - * @param string $rep The attached ellipsis character if the string is longer - * @return string - */ -field::$methods['short'] = function($field, $length, $rep = '…') { - return str::short($field->value, $length, $rep); -}; - -/** - * Returns the string length of the field value - * @param Field $field The calling Kirby Field instance - * @return integer - */ -field::$methods['length'] = function($field) { - return str::length($field->value); -}; - -/** - * Returns the word count for the field value - * @param Field $field The calling Kirby Field instance - * @return integer - */ -field::$methods['words'] = function($field) { - return str_word_count(strip_tags($field->value)); -}; - -/** - * Splits the field value by the given separator - * @param Field $field The calling Kirby Field instance - * @param string $separator The string to split the field value by - * @return array - */ -field::$methods['split'] = function($field, $separator = ',') { - return str::split($field->value, $separator); -}; - -/** - * Parses the field value as yaml and returns an array - * @param Field $field The calling Kirby Field instance - * @return array - */ -field::$methods['yaml'] = function($field) { - return yaml($field->value); -}; - -/** - * Checks if the field value is empty - * @param Field $field The calling Kirby Field instance - * @return boolean - */ -field::$methods['empty'] = field::$methods['isEmpty'] = function($field) { - return empty($field->value); -}; - -/** - * Checks if the field value is not empty - * @param Field $field The calling Kirby Field instance - * @return boolean - */ -field::$methods['isNotEmpty'] = function($field) { - return !$field->isEmpty(); -}; - -/** - * Returns a page object from a uri in a field - * @param Field $field The calling Kirby Field instance - * @return Collection - */ -field::$methods['toPage'] = function($field) { - return page($field->value); -}; - -/** - * Returns all page objects from a yaml list or a $sep separated string in a field - * @param Field $field The calling Kirby Field instance - * @return Collection - */ -field::$methods['pages'] = field::$methods['toPages'] = function($field, $sep = null) { - - if($sep !== null) { - $array = $field->split($sep); - } else { - $array = $field->yaml(); - } - - return $field->site()->pages()->find($array); - -}; - -/** - * Returns a file object from a filename in a field - * @param Field $field The calling Kirby Field instance - * @return Collection - */ -field::$methods['toFile'] = function($field) { - return $field->page()->file($field->value); -}; - -/** - * Adds 'or' method to Field objects, which allows getting a field - * value or getting back a default value if the field is empty. - * @author fvsch - * @param Field $field The calling Kirby Field instance - * @param mixed $fallback Fallback value returned if field is empty - * @return mixed - */ -field::$methods['or'] = function($field, $fallback = null) { - return $field->empty() ? $fallback : $field; -}; - -/** - * Filter the Field value, or a fallback value if the Field is empty, - * to get a boolean value. '1', 'on', 'true' or 'yes' will be true, - * and everything else will be false. - * @author fvsch - * @param Field $field The calling Kirby Field instance - * @param boolean $default Default value returned if field is empty - * @return boolean - */ -field::$methods['bool'] = field::$methods['isTrue'] = function($field, $default = false) { - $val = $field->empty() ? $default : $field->value; - return filter_var($val, FILTER_VALIDATE_BOOLEAN); -}; - -/** - * Checks if the field content is false - * @param Field $field The calling Kirby Field instance - * @return boolean - */ -field::$methods['isFalse'] = function($field) { - return !$field->bool(); -}; - -/** - * Get an integer value for the Field. - * @author fvsch - * @param Object(Field) [$field] The calling Kirby Field instance - * @param integer [$default] Default value returned if field is empty - * @return integer - */ -field::$methods['int'] = function($field, $default = 0) { - $val = $field->empty() ? $default : $field->value; - return intval($val); -}; - -/** - * Get a float value for the Field - * @param Field $field The calling Kirby Field instance - * @param int $default Default value returned if field is empty - * @return float - */ -field::$methods['float'] = function($field, $default = 0) { - $val = $field->empty() ? $default : $field->value; - return floatval($val); -}; - -field::$methods['toStructure'] = field::$methods['structure'] = function($field) { - return structure($field->yaml(), $field->page()); -}; - -field::$methods['link'] = function($field, $attr1 = array(), $attr2 = array()) { - $a = new Brick('a', $field->value()); - - if(is_string($attr1)) { - $a->attr('href', url($attr1)); - $a->attr($attr2); - } else { - $a->attr('href', $field->page()->url()); - $a->attr($attr1); - } - - return $a; - -}; - -field::$methods['toUrl'] = field::$methods['url'] = function($field) { - return url($field->value()); -}; \ No newline at end of file diff --git a/kirby/extensions/tags.php b/kirby/extensions/tags.php deleted file mode 100644 index 3c96550..0000000 --- a/kirby/extensions/tags.php +++ /dev/null @@ -1,309 +0,0 @@ - array(), - 'html' => function($tag) { - return strtolower($tag->attr('date')) == 'year' ? date('Y') : date($tag->attr('date')); - } -); - -// email tag -kirbytext::$tags['email'] = array( - 'attr' => array( - 'class', - 'title', - 'text', - 'rel' - ), - 'html' => function($tag) { - return html::email($tag->attr('email'), html($tag->attr('text')), array( - 'class' => $tag->attr('class'), - 'title' => $tag->attr('title'), - 'rel' => $tag->attr('rel'), - )); - } -); - -// file tag -kirbytext::$tags['file'] = array( - 'attr' => array( - 'text', - 'class', - 'title', - 'rel', - 'target', - 'popup' - ), - 'html' => function($tag) { - - // build a proper link to the file - $file = $tag->file($tag->attr('file')); - $text = $tag->attr('text'); - - if(!$file) return $text; - - // use filename if the text is empty and make sure to - // ignore markdown italic underscores in filenames - if(empty($text)) $text = str_replace('_', '\_', $file->name()); - - return html::a($file->url(), html($text), array( - 'class' => $tag->attr('class'), - 'title' => html($tag->attr('title')), - 'rel' => $tag->attr('rel'), - 'target' => $tag->target(), - )); - - } -); - -// image tag -kirbytext::$tags['image'] = array( - 'attr' => array( - 'width', - 'height', - 'alt', - 'text', - 'title', - 'class', - 'imgclass', - 'linkclass', - 'caption', - 'link', - 'target', - 'popup', - 'rel' - ), - 'html' => function($tag) { - - $url = $tag->attr('image'); - $alt = $tag->attr('alt'); - $title = $tag->attr('title'); - $link = $tag->attr('link'); - $caption = $tag->attr('caption'); - $file = $tag->file($url); - - // use the file url if available and otherwise the given url - $url = $file ? $file->url() : url($url); - - // alt is just an alternative for text - if($text = $tag->attr('text')) $alt = $text; - - // try to get the title from the image object and use it as alt text - if($file) { - - if(empty($alt) and $file->alt() != '') { - $alt = $file->alt(); - } - - if(empty($title) and $file->title() != '') { - $title = $file->title(); - } - - } - - // at least some accessibility for the image - if(empty($alt)) $alt = ' '; - - // link builder - $_link = function($image) use($tag, $url, $link, $file) { - - if(empty($link)) return $image; - - // build the href for the link - if($link == 'self') { - $href = $url; - } else if($file and $link == $file->filename()) { - $href = $file->url(); - } else if($tag->file($link)) { - $href = $tag->file($link)->url(); - } else { - $href = $link; - } - - return html::a(url($href), $image, array( - 'rel' => $tag->attr('rel'), - 'class' => $tag->attr('linkclass'), - 'title' => $tag->attr('title'), - 'target' => $tag->target() - )); - - }; - - // image builder - $_image = function($class) use($tag, $url, $alt, $title) { - return html::img($url, array( - 'width' => $tag->attr('width'), - 'height' => $tag->attr('height'), - 'class' => $class, - 'title' => $title, - 'alt' => $alt - )); - }; - - if(kirby()->option('kirbytext.image.figure') or !empty($caption)) { - $image = $_link($_image($tag->attr('imgclass'))); - $figure = new Brick('figure'); - $figure->addClass($tag->attr('class')); - $figure->append($image); - if(!empty($caption)) { - $figure->append('
' . html($caption) . '
'); - } - return $figure; - } else { - $class = trim($tag->attr('class') . ' ' . $tag->attr('imgclass')); - return $_link($_image($class)); - } - - } -); - -// link tag -kirbytext::$tags['link'] = array( - 'attr' => array( - 'text', - 'class', - 'title', - 'rel', - 'lang', - 'target', - 'popup' - ), - 'html' => function($tag) { - - $link = url($tag->attr('link'), $tag->attr('lang')); - $text = $tag->attr('text'); - - if(empty($text)) { - $text = $link; - } - - if(str::isURL($text)) { - $text = url::short($text); - } - - return html::a($link, $text, array( - 'rel' => $tag->attr('rel'), - 'class' => $tag->attr('class'), - 'title' => $tag->attr('title'), - 'target' => $tag->target(), - )); - - } -); - -// tel tag -kirbytext::$tags['tel'] = array( - 'attr' => array( - 'text', - 'class', - 'title' - ), - 'html' => function($tag) { - - $text = $tag->attr('text'); - $tel = str_replace(array('/', ' ', '-'), '', $tag->attr('tel')); - - if(empty($text)) $text = $tag->attr('tel'); - - return html::a('tel:' . $tel, html($text), array( - 'rel' => $tag->attr('rel'), - 'class' => $tag->attr('class'), - 'title' => html($tag->attr('title')) - )); - } -); - - -// twitter tag -kirbytext::$tags['twitter'] = array( - 'attr' => array( - 'class', - 'title', - 'text', - 'rel', - 'target', - 'popup', - ), - 'html' => function($tag) { - - // get and sanitize the username - $username = str_replace('@', '', $tag->attr('twitter')); - - // build the profile url - $url = 'https://twitter.com/' . $username; - - // sanitize the link text - $text = $tag->attr('text', '@' . $username); - - // build the final link - return html::a($url, $text, array( - 'class' => $tag->attr('class'), - 'title' => $tag->attr('title'), - 'rel' => $tag->attr('rel'), - 'target' => $tag->target(), - )); - - } -); - -kirbytext::$tags['youtube'] = array( - 'attr' => array( - 'width', - 'height', - 'class', - 'caption' - ), - 'html' => function($tag) { - - $caption = $tag->attr('caption'); - - if(!empty($caption)) { - $figcaption = '
' . escape::html($caption) . '
'; - } else { - $figcaption = null; - } - - return '
' . embed::youtube($tag->attr('youtube'), array( - 'width' => $tag->attr('width', kirby()->option('kirbytext.video.width')), - 'height' => $tag->attr('height', kirby()->option('kirbytext.video.height')), - 'options' => kirby()->option('kirbytext.video.youtube.options') - )) . $figcaption . '
'; - - } -); - -kirbytext::$tags['vimeo'] = array( - 'attr' => array( - 'width', - 'height', - 'class', - 'caption' - ), - 'html' => function($tag) { - - $caption = $tag->attr('caption'); - - if(!empty($caption)) { - $figcaption = '
' . escape::html($caption) . '
'; - } else { - $figcaption = null; - } - - return '
' . embed::vimeo($tag->attr('vimeo'), array( - 'width' => $tag->attr('width', kirby()->option('kirbytext.video.width')), - 'height' => $tag->attr('height', kirby()->option('kirbytext.video.height')), - 'options' => kirby()->option('kirbytext.video.vimeo.options') - )) . $figcaption . '
'; - - } -); - -kirbytext::$tags['gist'] = array( - 'attr' => array( - 'file' - ), - 'html' => function($tag) { - return embed::gist($tag->attr('gist'), $tag->attr('file')); - } -); diff --git a/kirby/helpers.php b/kirby/helpers.php deleted file mode 100644 index 229d6be..0000000 --- a/kirby/helpers.php +++ /dev/null @@ -1,327 +0,0 @@ -component('snippet')->render($file, $data, $return); -} - -/** - * Builds a css link tag for relative or absolute urls - * - * @param string $url - * @param string $media - * @return string - */ -function css() { - return call([kirby::instance()->component('css'), 'tag'], func_get_args()); -} - -/** - * Builds a script tag for relative or absolute links - * - * @param string $src - * @param boolean $async - * @return string - */ -function js($src, $async = false) { - return call([kirby::instance()->component('js'), 'tag'], func_get_args()); -} - -/** - * Global markdown parser shortcut - * - * @param string $text - * @return string - */ -function markdown($text) { - return kirby::instance()->component('markdown')->parse($text); -} - -/** - * Global smartypants parser shortcut - * - * @param string $text - * @return string - */ -function smartypants($text) { - return kirby::instance()->component('smartypants')->parse($text); -} - -/** - * Converts a string to Kirbytext - * - * @param Field $field - * @return string - */ -function kirbytext($field) { - return (string)new Kirbytext($field); -} - -/** - * Returns the Kirby class singleton - * - * @return Kirby - */ -function kirby($class = null) { - return kirby::instance($class); -} - -/** - * Returns the site object - * - * @return Site - */ -function site() { - return kirby::instance()->site(); -} - -/** - * Returns either the current page or any page for a given uri - * - * @return Page - */ -function page() { - return call_user_func_array(array(kirby::instance()->site(), 'page'), func_get_args()); -} - -/** - * Helper to build page collections - * - * @param array $data - */ -function pages($data = array()) { - return new Pages($data); -} - -/** - * Creates an excerpt without html and kirbytext - * - * @param mixed $text Variable object or string - * @param int $length The number of characters which should be included in the excerpt - * @param array $params an array of options for kirbytext: array('markdown' => true, 'smartypants' => true) - * @return string The shortened text - */ -function excerpt($text, $length = 140, $mode = 'chars') { - - if(strtolower($mode) == 'words') { - $text = str::excerpt(kirbytext($text), 0); - - if(str_word_count($text, 0) > $length) { - $words = str_word_count($text, 2); - $pos = array_keys($words); - $text = str::substr($text, 0, $pos[$length]) . '...'; - } - return $text; - - } else { - return str::excerpt(kirbytext($text), $length); - } - -} - -/** - * Helper to create correct text file names for content files - * - * @param string $uri - * @param string $template - * @param string $lang - * @return string - */ -function textfile($uri, $template, $lang = null) { - - $curi = ''; - $parts = str::split($uri, '/'); - $parent = site(); - - foreach($parts as $p) { - - if($parent and $child = $parent->children()->find($p)) { - $curi .= '/' . $child->dirname(); - $parent = $child; - } else { - $curi .= '/' . $p; - $parent = null; - } - - } - - $uri = ltrim($curi, '/'); - $root = kirby::instance()->roots()->content(); - $ext = kirby::instance()->option('content.file.extension', 'txt'); - return $root . DS . r(!empty($uri), str_replace('/', DS, $uri) . DS) . $template . r($lang, '.' . $lang) . '.' . $ext; - -} - -/** - * Renders a kirbytag - * - * @param array $attr - * @return Kirbytag - */ -function kirbytag($attr) { - return new Kirbytag(null, key($attr), $attr); -} - -/** - * Builds a Youtube video iframe - * - * @param string $url - * @param mixed $width - * @param mixed $height - * @param string $class - * @return string - */ -function youtube($url, $width = null, $height = null, $class = null) { - return kirbytag(array( - 'youtube' => $url, - 'width' => $width, - 'height' => $height, - 'class' => $class - )); -} - -/** - * Builds a Vimeo video iframe - * - * @param string $url - * @param mixed $width - * @param mixed $height - * @param string $class - * @return string - */ -function vimeo($url, $width = null, $height = null, $class = null) { - return kirbytag(array( - 'vimeo' => $url, - 'width' => $width, - 'height' => $height, - 'class' => $class - )); -} - -/** - * Builds a Twitter link - * - * @param string $username - * @param string $text - * @param string $title - * @param string $class - * @return string - */ -function twitter($username, $text = null, $title = null, $class = null) { - return kirbytag(array( - 'twitter' => $username, - 'text' => $text, - 'title' => $title, - 'class' => $class - )); -} - -/** - * Embeds a Github Gist - * - * @param string $url - * @param string $file - * @return string - */ -function gist($url, $file = null) { - return kirbytag(array( - 'gist' => $url, - 'file' => $file, - )); -} - -/** - * Returns the current url - * - * @return string - */ -function thisUrl() { - return url::current(); -} - -/** - * Give this any kind of array - * to get some kirby style structure - * - * @param mixed $data - * @param mixed $page - * @param mixed $key - * @return mixed - */ -function structure($data, $page = null, $key = null) { - - if(is_null($page)) { - $page = page(); - } - - if(is_array($data)) { - $result = new Structure(); - $result->page = $page; - foreach($data as $key => $value) { - $result->append($key, structure($value, $page, $key)); - } - return $result; - } else if(is_a($data, 'Field')) { - return $data; - } else { - return new Field($page, $key, $data); - } - -}; - - -/** - * Return an image from any page - * specified by the path - * - * Example: - * - * - * @param string $path - * @return File|null - */ -function image($path = null) { - - if($path === null) { - return page()->image(); - } - - $uri = dirname($path); - $filename = basename($path); - - if($uri == '.') { - $uri = null; - } - - $page = $uri == '/' ? site() : page($uri); - - if($page) { - return $page->image($filename); - } else { - return null; - } - -} - -/** - * Shortcut to create a new thumb object - * - * @param mixed Either a file path or a Media object - * @param array An array of additional params for the thumb - * @return object Thumb - */ -function thumb($image, $params = array(), $obj = true) { - if(is_a($image, 'File') || is_a($image, 'Asset')) { - return $obj ? $image->thumb($params) : $image->thumb($params)->url(); - } else { - $class = new Thumb($image, $params); - return $obj ? $class : $class->url(); - } -} \ No newline at end of file diff --git a/kirby/kirby.php b/kirby/kirby.php deleted file mode 100644 index 0e5b0cc..0000000 --- a/kirby/kirby.php +++ /dev/null @@ -1,785 +0,0 @@ -roots = new Roots(dirname(__DIR__)); - $this->urls = new Urls(); - $this->registry = new Registry($this); - $this->options = array_merge($this->defaults(), $options); - $this->path = implode('/', (array)url::fragments(detect::path())); - - // make sure the instance is stored / overwritten - static::$instance = $this; - } - - public function defaults() { - - $defaults = array( - 'url' => false, - 'timezone' => 'UTC', - 'license' => null, - 'rewrite' => true, - 'error' => 'error', - 'home' => 'home', - 'locale' => 'en_US.UTF8', - 'routes' => array(), - 'headers' => array(), - 'languages' => array(), - 'roles' => array(), - 'cache' => false, - 'debug' => 'env', - 'ssl' => false, - 'cache.driver' => 'file', - 'cache.options' => array(), - 'cache.ignore' => array(), - 'cache.autoupdate' => true, - 'date.handler' => 'date', - 'kirbytext.video.class' => 'video', - 'kirbytext.video.width' => false, - 'kirbytext.video.height' => false, - 'kirbytext.video.youtube.options' => array(), - 'kirbytext.video.vimeo.options' => array(), - 'kirbytext.image.figure' => true, - 'content.file.extension' => 'txt', - 'content.file.ignore' => array(), - 'content.file.normalize' => false, - 'email.service' => 'mail', - 'email.to' => null, - 'email.replyTo' => null, - 'email.subject' => null, - 'email.body' => null, - 'email.options' => array(), - ); - - return $defaults; - - } - - public function roots() { - return $this->roots; - } - - public function urls() { - return $this->urls; - } - - public function registry() { - return $this->registry; - } - - public function url() { - return $this->urls->index(); - } - - public function options() { - return $this->options; - } - - public function option($key, $default = null) { - return a::get($this->options, $key, $default); - } - - public function path() { - return $this->path; - } - - public function page() { - return $this->page; - } - - public function response() { - return $this->response; - } - - /** - * Install a new entry in the registry - */ - public function set() { - return call_user_func_array([$this->registry, 'set'], func_get_args()); - } - - /** - * Retrieve an entry from the registry - */ - public function get() { - return call_user_func_array([$this->registry, 'get'], func_get_args()); - } - - public function configure() { - - // load all available config files - $root = $this->roots()->config(); - $configs = array( - 'main' => 'config.php', - 'host' => 'config.' . server::get('SERVER_NAME') . '.php', - 'addr' => 'config.' . server::get('SERVER_ADDR') . '.php', - ); - - $allowed = array_filter(dir::read($root), function($file) { - return substr($file, 0, 7) === 'config.' and substr($file, -4) === '.php'; - }); - - foreach($configs as $config) { - $file = $root . DS . $config; - if(in_array($config, $allowed, true) and file_exists($file)) include_once($file); - } - - // apply the options - $this->options = array_merge($this->options, c::$data); - - // overwrite the autodetected url - if($this->options['url']) { - $this->urls->index = $this->options['url']; - } - - // connect the url class with its handlers - url::$home = $this->urls()->index(); - url::$to = $this->option('url.to', function($url = '', $lang = null) { - - if(url::isAbsolute($url)) return $url; - - $start = substr($url, 0, 1); - switch($start) { - case '#': - return $url; - break; - case '.': - return page()->url() . '/' . $url; - break; - default: - if($page = page($url)) { - // use the "official" page url - return $page->url($lang); - } else { - // don't convert absolute urls - return url::makeAbsolute($url); - } - break; - } - - }); - - // setup the pagination redirect to the error page - pagination::$defaults['redirect'] = $this->option('error'); - - // setting up the email class - email::$defaults['service'] = $this->option('email.service'); - email::$defaults['from'] = $this->option('email.from'); - email::$defaults['to'] = $this->option('email.to'); - email::$defaults['replyTo'] = $this->option('email.replyTo'); - email::$defaults['subject'] = $this->option('email.subject'); - email::$defaults['body'] = $this->option('email.body'); - email::$defaults['options'] = $this->option('email.options'); - - // simple error handling - if($this->options['debug'] === true) { - error_reporting(E_ALL); - ini_set('display_errors', 1); - } else if($this->options['debug'] === false) { - error_reporting(0); - ini_set('display_errors', 0); - } - - } - - /** - * Registers all routes - * - * @param array $routes New routes - * @return array - */ - public function routes($routes = array()) { - - // extend the existing routes - if(!empty($routes) and is_array($routes)) { - return $this->options['routes'] = array_merge($this->options['routes'], $routes); - } - - $routes = $this->options['routes']; - $kirby = $this; - $site = $this->site(); - - if($site->multilang()) { - - foreach($site->languages() as $lang) { - - $routes[] = array( - 'pattern' => ltrim($lang->url . '/(:all?)', '/'), - 'method' => 'ALL', - 'lang' => $lang, - 'action' => function($path = null) use($kirby, $site) { - return $site->visit($path, $kirby->route->lang->code()); - } - ); - - } - - // fallback for the homepage - $routes[] = array( - 'pattern' => '/', - 'method' => 'ALL', - 'action' => function() use($kirby, $site) { - - // check if the language detector is activated - if($kirby->option('language.detect')) { - - if(s::get('language') and $language = $kirby->site()->sessionLanguage()) { - // $language is already set but the user wants to - // select the default language - $referer = r::referer(); - if(!empty($referer) && str::startsWith($referer, $this->urls()->index())) { - $language = $kirby->site()->defaultLanguage(); - } - } else { - // detect the user language - $language = $kirby->site()->detectedLanguage(); - } - - } else { - // always use the default language if the detector is disabled - $language = $kirby->site()->defaultLanguage(); - } - - // redirect to the language homepage if necessary - if($language->url != '/' and $language->url != '') { - go($language->url()); - } - - // plain home pages - return $site->visit('/', $language->code()); - - } - ); - - } - - // tinyurl handling - $routes['tinyurl'] = $this->component('tinyurl')->route(); - - // home redirect - $routes['homeRedirect'] = array( - 'pattern' => $this->options['home'], - 'action' => function() { - redirect::send(page('home')->url(), 307); - } - ); - - // plugin assets - $routes['pluginAssets'] = array( - 'pattern' => 'assets/plugins/(:any)/(:all)', - 'method' => 'GET', - 'action' => function($plugin, $path) use($kirby) { - $root = $kirby->roots()->plugins() . DS . $plugin . DS . 'assets' . DS . $path; - $file = new Media($root); - - if($file->exists()) { - return new Response(f::read($root), f::extension($root)); - } else { - return new Response('The file could not be found', f::extension($path), 404); - } - - - } - ); - - // all other urls - $routes['others'] = array( - 'pattern' => '(:all)', - 'method' => 'ALL', - 'action' => function($path = null) use($site, $kirby) { - - // visit the currently active page - $page = $site->visit($path); - - // react on errors for invalid URLs - if($page->isErrorPage() and $page->uri() != $path) { - - // get the filename - $filename = rawurldecode(basename($path)); - $pagepath = dirname($path); - - // check if there's a page for the parent path - if($page = $site->find($pagepath)) { - // check if there's a file for the last element of the path - if($file = $page->file($filename)) { - go($file->url()); - } - } - - // return the error page if there's no such page - return $site->errorPage(); - - } - - return $page; - - } - - ); - - return $routes; - - } - - /** - * Loads all available plugins for the site - * - * @return array - */ - public function plugins() { - - // check for a cached plugins array - if(!is_null($this->plugins)) return $this->plugins; - - // get the plugins root - $root = $this->roots->plugins(); - - // start the plugin registry - $this->plugins = array(); - - // check for an existing plugins dir - if(!is_dir($root)) return $this->plugins; - - foreach(array_diff(scandir($root), array('.', '..')) as $file) { - if(is_dir($root . DS . $file)) { - $this->plugin($file, 'dir'); - } else if(f::extension($file) == 'php') { - $this->plugin(f::name($file), 'file'); - } - } - - return $this->plugins; - - } - - /** - * Loads a single plugin - * - * @param string $name - * @param string $mode - * @return mixed - */ - public function plugin($name, $mode = 'dir') { - - if(isset($this->plugins[$name])) return $this->plugins[$name]; - - if($mode == 'dir') { - $file = $this->roots->plugins() . DS . $name . DS . $name . '.php'; - } else { - $file = $this->roots->plugins() . DS . $name . '.php'; - } - - // make the kirby variable available in plugin files - $kirby = $this; - - if(file_exists($file)) return $this->plugins[$name] = include_once($file); - - return false; - - } - - /** - * Load all default extensions - */ - public function extensions() { - - // load all kirby tags and field methods - include_once(__DIR__ . DS . 'extensions' . DS . 'tags.php'); - include_once(__DIR__ . DS . 'extensions' . DS . 'methods.php'); - - // install additional kirby tags - kirbytext::install($this->roots->tags()); - - } - - /** - * Autoloads all page models - */ - public function models() { - - if(!is_dir($this->roots()->models())) return false; - - $root = $this->roots()->models(); - $files = dir::read($root); - $load = array(); - - foreach($files as $file) { - if(f::extension($file) != 'php') continue; - $name = f::name($file); - $classname = str_replace(array('.', '-', '_'), '', $name . 'page'); - $load[$classname] = $root . DS . $file; - - // register the model - page::$models[$name] = $classname; - } - - // start the autoloader - if(!empty($load)) { - load($load); - } - - } - - public function localize() { - - $site = $this->site(); - - if($site->multilang() and !$site->language()) { - $site->language = $site->languages()->findDefault(); - } - - // set the local for the specific language - if(is_array($site->locale())) { - foreach($site->locale() as $key => $value) { - setlocale($key, $value); - } - } else { - setlocale(LC_ALL, $site->locale()); - } - - // additional language variables for multilang sites - if($site->multilang()) { - // path for the language file - $file = $this->roots()->languages() . DS . $site->language()->code() . '.php'; - // load the file if it exists - if(file_exists($file)) include_once($file); - } - - } - - /** - * Returns the branch file - * - * @return string - */ - public function branch() { - - // which branch? - $branch = count($this->options['languages']) > 0 ? 'multilang' : 'default'; - - // build the path for the branch file - return __DIR__ . DS . 'branches' . DS . $branch . '.php'; - - } - - /** - * Initializes and returns the site object - * depending on the appropriate branch - * - * @return Site - */ - public function site() { - - // check for a cached version of the site object - if(!is_null($this->site)) return $this->site; - - // load all options - $this->configure(); - - // setup the cache - $this->cache(); - - // load the main branch file - include_once($this->branch()); - - // create the site object - return $this->site = new Site($this); - - } - - /** - * Cache setup - * - * @return Cache - */ - public function cache() { - - if(!is_null($this->cache)) return $this->cache; - - // cache setup - if($this->options['cache']) { - if($this->options['cache.driver'] == 'file' and empty($this->options['cache.options'])) { - $this->options['cache.options'] = array( - 'root' => $this->roots()->cache() - ); - } - return $this->cache = cache::setup($this->options['cache.driver'], $this->options['cache.options']); - } else { - return $this->cache = cache::setup('mock'); - } - - } - - /** - * Renders the HTML for the page or fetches it from the cache - * - * @param Page $page - * @param boolean $headers - * @return string - */ - public function render(Page $page, $data = array(), $headers = true) { - - // register the currently rendered page - $this->page = $page; - - // send all headers for the page - if($headers) $page->headers(); - - // configure pagination urls - $query = (string)$this->request()->query(); - $params = (string)$this->request()->params() . r($query, '?') . $query; - - pagination::$defaults['url'] = $page->url() . r($params, '/') . $params; - - // cache the result if possible - if($this->options['cache'] and $page->isCachable()) { - - // try to read the cache by cid (cache id) - $cacheId = md5(url::current()); - - // check for modified content within the content folder - // and auto-expire the page cache in such a case - if($this->options['cache.autoupdate'] and $this->cache()->exists($cacheId)) { - - // get the creation date of the cache file - $created = $this->cache()->created($cacheId); - - // make sure to kill the cache if the site has been modified - if($this->site->wasModifiedAfter($created)) { - $this->cache()->remove($cacheId); - } - - } - - // try to fetch the template from cache - $template = $this->cache()->get($cacheId); - - // fetch fresh content if the cache is empty - if(empty($template)) { - $template = $this->template($page, $data); - // store the result for the next round - $this->cache()->set($cacheId, $template); - } - - return $template; - - } - - // return a fresh template - return $this->template($page, $data); - - } - - /** - * Template configuration - * - * @param Page $page - * @param array $data - * @return string - */ - public function template(Page $page, $data = array()) { - return $this->component('template')->render($page, $data); - } - - public function request() { - if(!is_null($this->request)) return $this->request; - return $this->request = new Request($this); - } - - public function router() { - return $this->router; - } - - public function route() { - return $this->route; - } - - /** - * Starts the router, renders the page and returns the response - * - * @return mixed - */ - public function launch() { - - // this will trigger the configuration - $site = $this->site(); - - // force secure connections if enabled - if($this->option('ssl') and !r::secure()) { - // rebuild the current url with https - go(url::build(array('scheme' => 'https'))); - } - - // set the timezone for all date functions - date_default_timezone_set($this->options['timezone']); - - // load all extensions - $this->extensions(); - - // load all plugins - $this->plugins(); - - // load all models - $this->models(); - - // start the router - $this->router = new Router($this->routes()); - $this->route = $this->router->run($this->path()); - - // check for a valid route - if(is_null($this->route)) { - header::status('500'); - header::type('json'); - die(json_encode(array( - 'status' => 'error', - 'message' => 'Invalid route or request method' - ))); - } - - // call the router action with all arguments from the pattern - $response = call($this->route->action(), $this->route->arguments()); - - // load all language variables - // this can only be loaded once the router action has been called - // otherwise the current language is not yet available - $this->localize(); - - // build the response - $this->response = $this->component('response')->make($response); - - // store the current language in the session - if($this->site()->multilang() && $language = $this->site()->language()) { - s::set('language', $language->code()); - } - - return $this->response; - - } - - /** - * Register a new hook - * - * @param string $hook The name of the hook - * @param closure $callback - */ - public function hook($hook, $callback) { - - if(isset(static::$hooks[$hook]) and is_array(static::$hooks[$hook])) { - static::$hooks[$hook][] = $callback; - } else { - static::$hooks[$hook] = array($callback); - } - - } - - /** - * Trigger a hook - * - * @param string $hook The name of the hook - * @param mixed $args Additional arguments for the hook - * @return mixed - */ - public function trigger($hook, $args = null) { - - if(isset(static::$hooks[$hook]) and is_array(static::$hooks[$hook])) { - foreach(static::$hooks[$hook] as $key => $callback) { - - if(array_key_exists($hook, static::$triggered) && in_array($key, static::$triggered[$hook])) continue; - - static::$triggered[$hook] = $key; - - try { - call($callback, $args); - } catch(Exception $e) { - // caught callback error - } - } - } - } - - static public function start() { - return kirby()->launch(); - } - - /** - * Register and fetch core components - */ - public function component($name, $component = null) { - if(is_null($component)) { - if(!isset($this->components[$name])) { - // load the default component if it exists - if(file_exists(__DIR__ . DS . 'kirby' . DS . 'component' . DS . strtolower($name) . '.php')) { - $this->component($name, 'Kirby\\Component\\' . $name); - } else { - throw new Exception('The component "' . $name . '" does not exist'); - } - } - return $this->components[$name]; - } else { - - if(!is_string($component)) { - throw new Exception('Please provide a valid component name'); - } - - // init the component - $object = new $component($this); - - if(!is_a($object, 'Kirby\\Component')) { - throw new Exception('The component "' . $name . '" must be an instance of the Kirby\\Component class'); - } - - if(!is_a($object, 'Kirby\\Component\\' . $name)) { - throw new Exception('The component "' . $name . '" must be an instance of the Kirby\\Component\\' . ucfirst($name) . ' class'); - } - - // add the component defaults - $this->options = array_merge($object->defaults(), $this->options); - - // configure the component - $object->configure(); - - // register the component - $this->components[$name] = $object; - - } - } - -} \ No newline at end of file diff --git a/kirby/kirby/component.php b/kirby/kirby/component.php deleted file mode 100644 index 6ffe1f0..0000000 --- a/kirby/kirby/component.php +++ /dev/null @@ -1,27 +0,0 @@ -kirby = $kirby; - } - - public function defaults() { - return []; - } - - public function configure() { - - } - - public function kirby() { - return $this->kirby; - } - -} \ No newline at end of file diff --git a/kirby/kirby/component/css.php b/kirby/kirby/component/css.php deleted file mode 100644 index fc811b3..0000000 --- a/kirby/kirby/component/css.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class CSS extends \Kirby\Component { - - /** - * Builds the html link tag for the given css file - * - * @param string $url - * @param null|string $media - * @return string - */ - public function tag($url, $media = null) { - - if(is_array($url)) { - $css = array(); - foreach($url as $u) $css[] = $this->tag($u, $media); - return implode(PHP_EOL, $css) . PHP_EOL; - } - - // auto template css files - if($url == '@auto') { - - $file = $this->kirby->site()->page()->template() . '.css'; - $root = $this->kirby->roots()->autocss() . DS . $file; - $url = $this->kirby->urls()->autocss() . '/' . $file; - - if(!file_exists($root)) return false; - - } - - return html::tag('link', null, array( - 'rel' => 'stylesheet', - 'href' => url($url), - 'media' => $media - )); - - } - -} \ No newline at end of file diff --git a/kirby/kirby/component/js.php b/kirby/kirby/component/js.php deleted file mode 100644 index 6322c9f..0000000 --- a/kirby/kirby/component/js.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class JS extends \Kirby\Component { - - /** - * Builds the html script tag for the given javascript file - * - * @param string $src - * @param boolean async - * @return string - */ - public function tag($src, $async = false) { - - if(is_array($src)) { - $js = array(); - foreach($src as $s) $js[] = $this->tag($s, $async); - return implode(PHP_EOL, $js) . PHP_EOL; - } - - // auto template css files - if($src == '@auto') { - - $file = $this->kirby->site()->page()->template() . '.js'; - $root = $this->kirby->roots()->autojs() . DS . $file; - $src = $this->kirby->urls()->autojs() . '/' . $file; - - if(!file_exists($root)) return false; - - } - - return html::tag('script', '', array( - 'src' => url($src), - 'async' => $async - )); - - } - -} \ No newline at end of file diff --git a/kirby/kirby/component/markdown.php b/kirby/kirby/component/markdown.php deleted file mode 100644 index 8314958..0000000 --- a/kirby/kirby/component/markdown.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Markdown extends \Kirby\Component { - - /** - * Returns the default options for the component - * - * @return array - */ - public function defaults() { - return [ - 'markdown' => true, - 'markdown.extra' => false, - 'markdown.breaks' => true, - ]; - } - - /** - * Initializes the Parsedown parser and - * transforms the given markdown to HTML - * - * @param string $markdown - * @return string - */ - public function parse($markdown) { - - if(!$this->kirby->options['markdown']) { - return $markdown; - } else { - // initialize the right markdown class - $parsedown = $this->kirby->options['markdown.extra'] ? new ParsedownExtra() : new Parsedown(); - - // set markdown auto-breaks - $parsedown->setBreaksEnabled($this->kirby->options['markdown.breaks']); - - // parse it! - return $parsedown->text($markdown); - } - - } - -} \ No newline at end of file diff --git a/kirby/kirby/component/response.php b/kirby/kirby/component/response.php deleted file mode 100644 index 5a90927..0000000 --- a/kirby/kirby/component/response.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Response extends \Kirby\Component { - - /** - * Builds and return the response by various input - * - * @param mixed $response - * @return mixed - */ - public function make($response) { - - if(is_string($response)) { - return $this->kirby->render(page($response)); - } else if(is_array($response)) { - return $this->kirby->render(page($response[0]), $response[1]); - } else if(is_a($response, 'Page')) { - return $this->kirby->render($response); - } else if(is_a($response, 'Response')) { - return $response; - } else { - return null; - } - - } - -} \ No newline at end of file diff --git a/kirby/kirby/component/smartypants.php b/kirby/kirby/component/smartypants.php deleted file mode 100644 index 0f74ae4..0000000 --- a/kirby/kirby/component/smartypants.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Smartypants extends \Kirby\Component { - - /** - * Returns the default options for - * the smartypants parser - * - * @return array - */ - public function defaults() { - return [ - 'smartypants' => false, - 'smartypants.attr' => 1, - 'smartypants.doublequote.open' => '“', - 'smartypants.doublequote.close' => '”', - 'smartypants.space.emdash' => ' ', - 'smartypants.space.endash' => ' ', - 'smartypants.space.colon' => ' ', - 'smartypants.space.semicolon' => ' ', - 'smartypants.space.marks' => ' ', - 'smartypants.space.frenchquote' => ' ', - 'smartypants.space.thousand' => ' ', - 'smartypants.space.unit' => ' ', - 'smartypants.skip' => 'pre|code|kbd|script|style|math', - ]; - } - - /** - * Initializes the parser and transforms - * the given text. - * - * @param string $text - * @return string - */ - public function parse($text) { - if(!$this->kirby->options['smartypants']) { - return $text; - } else { - // prepare the text - $text = str_replace('"', '"', $text); - // run the parser - $parser = new SmartyPantsTypographer_Parser($this->kirby->options['smartypants.attr']); - return $parser->transform($text); - } - } - -} \ No newline at end of file diff --git a/kirby/kirby/component/snippet.php b/kirby/kirby/component/snippet.php deleted file mode 100644 index 57356d9..0000000 --- a/kirby/kirby/component/snippet.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Snippet extends \Kirby\Component { - - /** - * Returns a snippet file path by name - * - * @param string $name - * @return string - */ - public function file($name) { - return $this->kirby->roots()->snippets() . DS . str_replace('/', DS, $name) . '.php'; - } - - /** - * Renders the snippet with the given data - * - * @param string $name - * @param array $data - * @param boolean $return - * @return string - */ - public function render($name, $data = [], $return = false) { - if(is_object($data)) $data = ['item' => $data]; - return tpl::load($this->kirby->registry->get('snippet', $name), $data, $return); - } - -} \ No newline at end of file diff --git a/kirby/kirby/component/template.php b/kirby/kirby/component/template.php deleted file mode 100644 index 21f5ffd..0000000 --- a/kirby/kirby/component/template.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Template extends \Kirby\Component { - - /** - * Collects all template data by page - * - * @param mixed $page - * @param array $data - * @return array - */ - public function data($page, $data = []) { - - if($page instanceof Page) { - $data = array_merge( - $page->templateData(), - $data, - $page->controller($data) - ); - } - - // apply the basic template vars - return array_merge(array( - 'kirby' => $this->kirby, - 'site' => $this->kirby->site(), - 'pages' => $this->kirby->site()->children(), - 'page' => $page - ), $data); - - } - - /** - * Returns a template file path by name - * - * @param string $name - * @return string - */ - public function file($name) { - return $this->kirby->roots()->templates() . DS . str_replace('/', DS, $name) . '.php'; - } - - /** - * Renders the template by page with the additional data - * - * @param Page|string $template - * @param array $data - * @param boolean $return - * @return string - */ - public function render($template, $data = [], $return = true) { - - if($template instanceof Page) { - $page = $template; - $file = $page->templateFile(); - $data = $this->data($page, $data); - } else { - $file = $template; - $data = $this->data(null, $data); - } - - // check for an existing template - if(!file_exists($file)) { - throw new Exception('The template could not be found'); - } - - // merge and register the template data globally - tpl::$data = array_merge(tpl::$data, $data); - - // load the template - return tpl::load($file, null, $return); - - } - -} \ No newline at end of file diff --git a/kirby/kirby/component/thumb.php b/kirby/kirby/component/thumb.php deleted file mode 100644 index 8532007..0000000 --- a/kirby/kirby/component/thumb.php +++ /dev/null @@ -1,206 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Thumb extends Component { - - /** - * Returns the default options for the thumb component - * - * @return array - */ - public function defaults() { - - $self = $this; - - return [ - 'thumbs.driver' => 'gd', - 'thumbs.bin' => 'convert', - 'thumbs.interlace' => false, - 'thumbs.quality' => 90, - 'thumbs.memory' => '128M', - 'thumbs.filename' => false, - 'thumbs.destination' => function($thumb) use($self) { - - $path = $self->path($thumb); - - return new Obj([ - 'root' => $self->kirby->roots()->thumbs() . DS . str_replace('/', DS, $path), - 'url' => $self->kirby->urls()->thumbs() . '/' . $path, - ]); - - } - ]; - } - - /** - * Configures the thumb driver - */ - public function configure() { - - $self = $this; - - // setup the thumbnail location - generator::$defaults['root'] = $this->kirby->roots->thumbs(); - generator::$defaults['url'] = $this->kirby->urls->thumbs(); - - // setup the default thumbnail options - generator::$defaults['driver'] = $this->kirby->option('thumbs.driver'); - generator::$defaults['bin'] = $this->kirby->option('thumbs.bin'); - generator::$defaults['quality'] = $this->kirby->option('thumbs.quality'); - generator::$defaults['interlace'] = $this->kirby->option('thumbs.interlace'); - generator::$defaults['memory'] = $this->kirby->option('thumbs.memory'); - generator::$defaults['destination'] = $this->kirby->option('thumbs.destination'); - generator::$defaults['filename'] = $this->kirby->option('thumbs.filename'); - - } - - public function create($file, $params) { - - if(!$file->isWebsafe()) { - return $file; - } - - $thumb = new Generator($file, $params); - $asset = new Asset($thumb->result); - - // store a reference to the original file - $asset->original($file); - - return $thumb->exists() ? $asset : $file; - - } - - /** - * Returns the clean path for a thumbnail - * - * @param Generator $thumb - * @return string - */ - protected function path(Generator $thumb) { - return ltrim($this->dir($thumb) . '/' . $this->filename($thumb), '/'); - } - - /** - * @param Generator $thumb - * @return string - */ - protected function dir(Generator $thumb) { - if(is_a($thumb->source, 'File')) { - return $thumb->source->page()->id(); - } else { - return str_replace($this->kirby->urls()->index(), '', dirname($thumb->source->url())); - } - } - - /** - * Returns the filename for a thumb including the - * identifying option hash - * - * @param Generator $thumb - * @return string - */ - protected function filename(Generator $thumb) { - - $dimensions = $this->dimensions($thumb); - $wh = $dimensions->width() . 'x' . $dimensions->height(); - $safeName = f::safeName($thumb->source->name()); - $options = $this->options($thumb); - $extension = $thumb->source->extension(); - - if($thumb->options['filename'] === false) { - return $safeName . '-' . $wh . r($options, '-' . $options) . '.' . $extension; - } else { - return str::template($thumb->options['filename'], [ - 'extension' => $extension, - 'name' => $thumb->source->name(), - 'filename' => $thumb->source->filename(), - 'safeName' => $safeName, - 'safeFilename' => $safeName . '.' . $extension, - 'width' => $dimensions->width(), - 'height' => $dimensions->height(), - 'dimensions' => $wh, - 'options' => $options, - 'hash' => md5($thumb->source->root() . $thumb->settingsIdentifier()), - ]); - } - - } - - /** - * Returns an identifying option hash for thumb filenames - * - * @param Generator $thumb - * @return string - */ - protected function options(Generator $thumb) { - - $keys = [ - 'blur' => 'blur', - 'grayscale' => 'bw', - 'quality' => 'q', - ]; - - $string = []; - - foreach($keys as $long => $key) { - - $value = a::get($thumb->options, $long); - - if($value === true) { - $string[] = $key; - } else if($value === false) { - continue; - } else if($key === 'q' && $value == generator::$defaults['quality']) { - // ignore the default quality setting - continue; - } else { - $string[] = $key . $value; - } - - } - - return implode('-', array_filter($string)); - - } - - /** - * @param Generator $thumb - * @return string - */ - protected function dimensions(Generator $thumb) { - - $dimensions = clone $thumb->source->dimensions(); - - if(isset($thumb->options['crop']) && $thumb->options['crop']) { - $dimensions->crop(a::get($thumb->options, 'width'), a::get($thumb->options, 'height')); - } else { - $dimensions->resize(a::get($thumb->options, 'width'), a::get($thumb->options, 'height'), a::get($thumb->options, 'upscale')); - } - - return $dimensions; - - } - -} diff --git a/kirby/kirby/component/tinyurl.php b/kirby/kirby/component/tinyurl.php deleted file mode 100644 index 6575c4e..0000000 --- a/kirby/kirby/component/tinyurl.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class TinyUrl extends \Kirby\Component { - - /** - * Returns the default options for the tinyurl component - * - * @return array - */ - public function defaults() { - return [ - 'tinyurl.enabled' => true, - 'tinyurl.folder' => 'x', - ]; - } - - /** - * Returns the tinyurl fetching route - * - * @return array - */ - public function route() { - if(!$this->kirby->options['tinyurl.enabled']) { - return false; - } else { - return [ - 'pattern' => $this->kirby->options['tinyurl.folder'] . '/(:any)/(:any?)', - 'action' => function($hash, $lang = null) { - // get the site object - $site = site(); - // make sure the language is set - $site->visit('/', $lang); - // find the page by it's tiny hash - if($page = $site->index()->findBy('hash', $hash)) { - go($page->url($lang)); - } else { - return $site->errorPage(); - } - } - ]; - } - } -} \ No newline at end of file diff --git a/kirby/kirby/registry.php b/kirby/kirby/registry.php deleted file mode 100644 index e420cb1..0000000 --- a/kirby/kirby/registry.php +++ /dev/null @@ -1,118 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Registry { - - /** - * Kirby Instance - * - * @var Kirby - */ - protected $kirby; - - /** - * @param Kirby $kirby - */ - public function __construct(Kirby $kirby) { - - $this->kirby = $kirby; - - // start the registry entry autoloader - load([ - 'kirby\\registry\\entry' => __DIR__ . DS . 'registry' . DS . 'entry.php', - 'kirby\\registry\\blueprint' => __DIR__ . DS . 'registry' . DS . 'blueprint.php', - 'kirby\\registry\\component' => __DIR__ . DS . 'registry' . DS . 'component.php', - 'kirby\\registry\\controller' => __DIR__ . DS . 'registry' . DS . 'controller.php', - 'kirby\\registry\\hook' => __DIR__ . DS . 'registry' . DS . 'hook.php', - 'kirby\\registry\\field' => __DIR__ . DS . 'registry' . DS . 'field.php', - 'kirby\\registry\\method' => __DIR__ . DS . 'registry' . DS . 'method.php', - 'kirby\\registry\\model' => __DIR__ . DS . 'registry' . DS . 'model.php', - 'kirby\\registry\\option' => __DIR__ . DS . 'registry' . DS . 'option.php', - 'kirby\\registry\\route' => __DIR__ . DS . 'registry' . DS . 'route.php', - 'kirby\\registry\\snippet' => __DIR__ . DS . 'registry' . DS . 'snippet.php', - 'kirby\\registry\\template' => __DIR__ . DS . 'registry' . DS . 'template.php', - 'kirby\\registry\\tag' => __DIR__ . DS . 'registry' . DS . 'tag.php', - 'kirby\\registry\\widget' => __DIR__ . DS . 'registry' . DS . 'widget.php', - ]); - - } - - /** - * Returns the Kirby instance - * - * @return Kirby - */ - public function kirby() { - return $this->kirby; - } - - /** - * Returns a registry entry object by type - * - * @param string $type - * @param string $subtype - * @return Kirby\Registry\Entry - */ - public function entry($type, $subtype = null) { - - $class = 'kirby\\registry\\' . $type; - - if(!class_exists('kirby\\registry\\' . $type)) { - - if(str::contains($type, '::')) { - $parts = str::split($type, '::'); - $subtype = $parts[0]; - $type = $parts[1]; - return $this->entry($type, $subtype); - } - - throw new Exception('Unsupported registry entry type: ' . $type); - - } - - return new $class($this, $subtype); - - } - - /** - * Adds a new entry to the registry - * This will initialize a registry object - * and call the set method of it - * with the passed arguments - */ - public function set() { - $args = func_get_args(); - $type = strtolower(array_shift($args)); - return $this->entry($type)->call('set', $args); - } - - /** - * Retrieves an entry from the registry - * - * This will initialize a registry object - * and call the get method of it - * with the passed arguments - * - * @return Entry - */ - public function get() { - $args = func_get_args(); - $type = array_shift($args); - return $this->entry($type)->call('get', $args); - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/blueprint.php b/kirby/kirby/registry/blueprint.php deleted file mode 100644 index 351e69c..0000000 --- a/kirby/kirby/registry/blueprint.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Blueprint extends Entry { - - /** - * Blueprint store - * - * @var array $blueprints - */ - protected static $blueprints = []; - - /** - * Adds a new blueprint entry - * - * Pass a path to an existing blueprint file - * to add it to the registry - * - * @param string $name - * @param string $path - * @return $path - */ - public function set($name, $path) { - - if(!$this->kirby->option('debug') || file_exists($path)) { - return static::$blueprints[$name] = $path; - } - - throw new Exception('The blueprint does not exist at the specified path: ' . $path); - - } - - /** - * Retreives a registered blueprint file path - * - * @param string $name - * @return string - */ - public function get($name = null) { - - if(is_null($name)) { - return static::$blueprints; - } - - $file = f::resolve($this->kirby->roots()->blueprints() . DS . str_replace('/', DS, $name), ['php', 'yml', 'yaml']); - - if(file_exists($file)) { - return $file; - } else { - return a::get(static::$blueprints, $name); - } - - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/component.php b/kirby/kirby/registry/component.php deleted file mode 100644 index 3679773..0000000 --- a/kirby/kirby/registry/component.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Component extends Entry { - - /** - * Adds a new core component to Kirby - * - * This will directly call the component method of the - * Kirby instance to register the component - * - * @param string $name The name of the component - * @param string $class A valid component classname. Must be extend the according Kirby component type class - */ - public function set($name, $class) { - return $this->kirby->component($name, $class); - } - - /** - * Retreives a component from the Kirby component registry - * - * @param string $name - * @return Kirby\Component - */ - public function get($name) { - return $this->kirby->component($name); - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/controller.php b/kirby/kirby/registry/controller.php deleted file mode 100644 index 3fd39a2..0000000 --- a/kirby/kirby/registry/controller.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Controller extends Entry { - - /** - * Store of registered controllers - * - * @var array $controllers - */ - protected static $controllers = []; - - /** - * Adds a new controller to the registry - * - * @param string $name - * @param Closure $callback Must be a valid controller callback - * @return Closure - */ - public function set($name, $callback) { - - $name = strtolower($name); - - if($name === 'site') { - throw new Exception('You are not allowed to set the site controller'); - } - - if(!$this->kirby->option('debug') || is_a($callback, 'Closure') || file_exists($callback)) { - return static::$controllers[$name] = $callback; - } else { - throw new Exception('Invalid controller. You must pass a closure or an existing file'); - } - - } - - /** - * Retreives a controller from the registry - * - * @param string $name - * @return Closure - */ - public function get($name) { - - $name = strtolower($name); - $file = $this->kirby->roots()->controllers() . DS . $name . '.php'; - - if(file_exists($file)) { - return include_once $file; - } - - if(isset(static::$controllers[$name])) { - if(is_a(static::$controllers[$name], 'Closure')) { - return static::$controllers[$name]; - } else if(file_exists(static::$controllers[$name])) { - return include_once static::$controllers[$name]; - } - } - - if(file_exists($this->kirby->roots()->controllers() . DS . 'site.php')) { - return include_once $this->kirby->roots()->controllers() . DS . 'site.php'; - } - - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/entry.php b/kirby/kirby/registry/entry.php deleted file mode 100644 index 9d14009..0000000 --- a/kirby/kirby/registry/entry.php +++ /dev/null @@ -1,98 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Entry { - - /** - * Kirby instance - * - * @var Kirby - */ - protected $kirby; - - /** - * Kirby Registry instance - * - * @var Kirby\Registry - */ - protected $registry; - - /** - * Optional subtype for something - * like $kirby->set('field::method', '…') - * where `field` is the subtype of type `method`. - * - * @param string $subtype - */ - protected $subtype; - - /** - * @param Kirby $kirby - * @param Kirby\Registry $registry - * @param string $subtype - */ - public function __construct(Registry $registry, $subtype = null) { - $this->registry = $registry; - $this->kirby = $registry->kirby(); - $this->subtype = $subtype; - } - - /** - * Interface to call any registry entry method - * - * Mostly used for set() and get() - * - * @param string $method - * @param array $args - * @return mixed - */ - public function call($method, $args) { - return call([$this, $method], $args); - } - - /** - * Returns the Kirby instance - * - * @return Kirby - */ - public function kirby() { - return $this->kirby; - } - - /** - * Returns the Registry instance - * - * @return Kirby\Registry - */ - public function registry() { - return $this->registry; - } - - /** - * Returns the optional subtype - * - * @return string - */ - public function subtype() { - return $this->subtype; - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/field.php b/kirby/kirby/registry/field.php deleted file mode 100644 index 1c60f72..0000000 --- a/kirby/kirby/registry/field.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Field extends Entry { - - /** - * Store for registered fields - * - * @var array $fields - */ - protected static $fields = []; - - /** - * Adds a new field to the registry - * - * @param string $name - * @param string $root valid field directory path - * @return Obj generic Kirby object with info about the field - */ - public function set($name, $root) { - - $name = strtolower($name); - $file = $root . DS . $name . '.php'; - - if(!$this->kirby->option('debug') || (is_dir($root) && is_file($file))) { - return static::$fields[$name] = new Obj([ - 'root' => $root, - 'file' => $file, - 'name' => $name, - 'class' => $name . 'field', - ]); - } - - throw new Exception('The field does not exist at the specified path: ' . $root); - - } - - /** - * Retreives a field info object from the registry - * - * @param string|null $name If null, all registered fields will be returned as array - * @param Obj|null|array - */ - public function get($name = null) { - - if(is_null($name)) { - return static::$fields; - } - - return a::get(static::$fields, $name); - - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/hook.php b/kirby/kirby/registry/hook.php deleted file mode 100644 index 970ef96..0000000 --- a/kirby/kirby/registry/hook.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Hook extends Entry { - - /** - * Registers a new hook - * - * This will directly call the $kirby->hook() method - * A hook has to be a valid closure - * - * @param string $name - * @param Closure $callback - * @return Closure - */ - public function set($name, $callback) { - return $this->kirby->hook($name, $callback); - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/method.php b/kirby/kirby/registry/method.php deleted file mode 100644 index d91dec3..0000000 --- a/kirby/kirby/registry/method.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Method extends Entry { - - /** - * List of allowed subtypes - * - * @var array $subtypes - */ - protected $subtypes = ['site', 'page', 'pages', 'file', 'files', 'field']; - - /** - * @param Kirby\Registry $registry - * @param string $subtype - */ - public function __construct(Registry $registry, $subtype) { - parent::__construct($registry, $subtype); - if(!in_array($this->subtype, $this->subtypes)) { - throw new Exception('Invalid method type: ' . $this->subtype . '::method'); - } - } - - /** - * Adds a new method to the registry - * - * A method can be registered for any of the allowed - * subtypes, by using the static method syntax: - * $kirby->set('page::method') - * $kirby->set('field::method') - * etc. - * - * The first part of the name is the subtype. - * The second part of the name is the main type (`method` in this case) - * - * @param string $name - * @param Closure $callback - * @return Closure - */ - public function set($name, $callback) { - $class = $this->subtype; - return $class::$methods[$name] = $callback; - } - - /** - * Retrieves a registered method - * - * @param string $name - * @return Closure - */ - public function get($name) { - $class = $this->subtype; - return a::get($class::$methods, $name); - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/model.php b/kirby/kirby/registry/model.php deleted file mode 100644 index 09cd72d..0000000 --- a/kirby/kirby/registry/model.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Model extends Entry { - - /** - * List of allowed subtypes - * - * @var array $subtypes - */ - protected $subtypes = ['page']; - - /** - * @param Kirby\Registry $registry - * @param string $subtype - */ - public function __construct(Registry $registry, $subtype) { - parent::__construct($registry, $subtype); - if(!in_array($this->subtype, $this->subtypes)) { - throw new Exception('Invalid model type: ' . $this->subtype . '::model'); - } - } - - /** - * Adds a new model to the registry - * - * A model can be registered for any of the allowed - * subtypes, by using the static method syntax: - * - * $kirby->set('page::model') - * - * The first part of the name is the subtype. - * The second part of the name is the main type (`model` in this case) - * - * @param string $name - * @param string $classname Must be a valid classname of a loaded/auto-loaded class - * @return string - */ - public function set($name, $classname) { - - $class = $this->subtype; - - if(!class_exists($classname)) { - throw new Exception('The model class does not exist: ' . $classname); - } - - return $class::$models[$name] = $classname; - - } - - /** - * Retrieves a registered model - * - * @param string $name - * @return string - */ - public function get($name) { - $class = $this->subtype; - return a::get($class::$models, $name); - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/option.php b/kirby/kirby/registry/option.php deleted file mode 100644 index 03cd176..0000000 --- a/kirby/kirby/registry/option.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Option extends Entry { - - /** - * Sets a Kirby option - * - * This directly adds passed options to the - * $kirby->options array and is just a convenient - * way to do this through the registry - * - * @param string $key - * @param mixed $value - * @return mixed - */ - public function set($key, $value) { - return $this->kirby->options[$key] = $value; - } - - /** - * Retreives an option from the $kirby->$options array - * - * @param string $key - * @param mixed $default - * @return mixed - */ - public function get($key, $default = null) { - return $this->kirby->option($key, $default); - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/route.php b/kirby/kirby/registry/route.php deleted file mode 100644 index e812c2d..0000000 --- a/kirby/kirby/registry/route.php +++ /dev/null @@ -1,28 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Route extends Entry { - - /** - * Registers a new route - * - * This will directly add a route to - * Kirby's route system, by calling $kirby->routes() - * - * @param string $attr - */ - public function set($attr) { - $this->kirby->routes([$attr]); - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/snippet.php b/kirby/kirby/registry/snippet.php deleted file mode 100644 index 9158fe5..0000000 --- a/kirby/kirby/registry/snippet.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Snippet extends Entry { - - /** - * List of registered snippet files - * - * @var array $snippets - */ - protected static $snippets = []; - - /** - * Registers a new snippet file - * - * You must pass an existing file in order - * to register it as a valid snippet - * - * @param string $name The name of the snippet. Can contain slashes (i.e. form/field) - * @param string $path - * @return string - */ - public function set($name, $path) { - - if(!$this->kirby->option('debug') || file_exists($path)) { - return static::$snippets[$name] = $path; - } - - throw new Exception('The snippet does not exist at the specified path: ' . $path); - - } - - /** - * Retrieve the file path for a registered snippet - * - * @param string $name - * @return string - */ - public function get($name) { - - $file = $this->kirby->component('snippet')->file($name); - - if(file_exists($file)) { - return $file; - } else { - return a::get(static::$snippets, $name); - } - - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/tag.php b/kirby/kirby/registry/tag.php deleted file mode 100644 index 740d84a..0000000 --- a/kirby/kirby/registry/tag.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Tag extends Entry { - - /** - * Registers a new kirby tag array - * - * This will directly add the tag to the - * kirbytext::$tags array. - * - * @param string $name - * @param array $tag - */ - public function set($name, $tag) { - kirbytext::$tags[$name] = $tag; - } - - /** - * Retreives a registered kirby tag - * - * @param string $name - * @return array - */ - public function get($name) { - return a::get(kirbytext::$tags, $name); - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/template.php b/kirby/kirby/registry/template.php deleted file mode 100644 index b1d1df0..0000000 --- a/kirby/kirby/registry/template.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Template extends Entry { - - /** - * List of registered template files - * - * @var array $templates - */ - protected static $templates = []; - - /** - * Registers a new template file - * - * Must be an existing file - * - * @param string $name - * @param string $path - */ - public function set($name, $path) { - - if(!$this->kirby->option('debug') || file_exists($path)) { - return static::$templates[$name] = $path; - } - - throw new Exception('The template does not exist at the specified path: ' . $path); - - } - - /** - * Retrieves a registered template file - * - * @param string $name - * @return string - */ - public function get($name) { - - $file = $this->kirby->component('template')->file($name); - - if(file_exists($file)) { - return $file; - } else { - return a::get(static::$templates, $name); - } - - } - -} \ No newline at end of file diff --git a/kirby/kirby/registry/widget.php b/kirby/kirby/registry/widget.php deleted file mode 100644 index 4d1ff85..0000000 --- a/kirby/kirby/registry/widget.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://getkirby.com/license - */ -class Widget extends Entry { - - /** - * List of registered widget directories - * - * @var array $widgets - */ - protected static $widgets = []; - - /** - * Registers a new widget - * - * You must pass an existing widget directory - * - * @param string $name - * @param string $path - * @return string - */ - public function set($name, $path) { - - if(!$this->kirby->option('debug') || is_dir($path)) { - return static::$widgets[$name] = $path; - } - - throw new Exception('The widget does not exist at the specified path: ' . $path); - - } - - /** - * Retreives a registered widget directory - * - * @param string|null $name If null, all registered widgets will be returned as array - * @return string|array - */ - public function get($name = null) { - - if(is_null($name)) { - return static::$widgets; - } - - $file = $this->kirby->roots()->widgets() . DS . str_replace('/', DS, $name) . '.php'; - - if(file_exists($file)) { - return $file; - } else { - return a::get(static::$widgets, $name); - } - - } - -} \ No newline at end of file diff --git a/kirby/kirby/request.php b/kirby/kirby/request.php deleted file mode 100644 index 5b5b0d5..0000000 --- a/kirby/kirby/request.php +++ /dev/null @@ -1,41 +0,0 @@ -kirby = $kirby; - } - - public function url() { - return url::current(); - } - - public function params() { - return new Request\Params(url::params()); - } - - public function query() { - return new Request\Query(url::query()); - } - - public function path() { - return new Request\Path($this->kirby->path()); - } - - public function __call($method, $arguments) { - if(method_exists('r', $method)) { - return call('r::' . $method, $arguments); - } else { - throw new Exception('Invalid method: ' . $method); - } - } - -} diff --git a/kirby/kirby/request/params.php b/kirby/kirby/request/params.php deleted file mode 100644 index ccdb541..0000000 --- a/kirby/kirby/request/params.php +++ /dev/null @@ -1,22 +0,0 @@ - $value) { - $params[] = $key . url::paramSeparator() . $value; - } - - return implode('/', $params); - - } - -} \ No newline at end of file diff --git a/kirby/kirby/request/path.php b/kirby/kirby/request/path.php deleted file mode 100644 index dda2af0..0000000 --- a/kirby/kirby/request/path.php +++ /dev/null @@ -1,18 +0,0 @@ -data); - } - -} \ No newline at end of file diff --git a/kirby/kirby/request/query.php b/kirby/kirby/request/query.php deleted file mode 100644 index bd58f8b..0000000 --- a/kirby/kirby/request/query.php +++ /dev/null @@ -1,13 +0,0 @@ -index = $index; - } - - public function content() { - return isset($this->content) ? $this->content : $this->index . DS . 'content'; - } - - public function site() { - return isset($this->site) ? $this->site : $this->index . DS . 'site'; - } - - public function kirby() { - return isset($this->kirby) ? $this->kirby : $this->index . DS . 'kirby'; - } - - public function thumbs() { - return isset($this->thumbs) ? $this->thumbs : $this->index . DS . 'thumbs'; - } - - public function assets() { - return isset($this->assets) ? $this->assets : $this->index . DS . 'assets'; - } - - public function autocss() { - return isset($this->autocss) ? $this->autocss : $this->assets() . DS . 'css' . DS . 'templates'; - } - - public function autojs() { - return isset($this->autojs) ? $this->autojs : $this->assets() . DS . 'js' . DS . 'templates'; - } - - public function avatars() { - return isset($this->avatars) ? $this->avatars : $this->assets() . DS . 'avatars'; - } - - public function config() { - return $this->site() . DS . 'config'; - } - - public function accounts() { - return isset($this->accounts) ? $this->accounts : $this->site() . DS . 'accounts'; - } - - public function blueprints() { - return $this->site() . DS . 'blueprints'; - } - - public function plugins() { - return $this->site() . DS . 'plugins'; - } - - public function cache() { - return isset($this->cache) ? $this->cache : $this->site() . DS . 'cache'; - } - - public function tags() { - return $this->site() . DS . 'tags'; - } - - public function fields() { - return $this->site() . DS . 'fields'; - } - - public function widgets() { - return $this->site() . DS . 'widgets'; - } - - public function controllers() { - return $this->site() . DS . 'controllers'; - } - - public function models() { - return $this->site() . DS . 'models'; - } - - public function templates() { - return $this->site() . DS . 'templates'; - } - - public function snippets() { - return $this->site() . DS . 'snippets'; - } - - public function languages() { - return $this->site() . DS . 'languages'; - } - -} diff --git a/kirby/kirby/traits/image.php b/kirby/kirby/traits/image.php deleted file mode 100644 index 5cd43a4..0000000 --- a/kirby/kirby/traits/image.php +++ /dev/null @@ -1,207 +0,0 @@ -original; - } else { - $this->original = $original; - return $this; - } - } - - /** - * Creates a thumbnail for the image - * - * @param array $params - * @return Asset - */ - public function thumb($params = []) { - // don't scale thumbs further down - if($this->original()) { - throw new Exception('Thumbnails cannot be modified further'); - } else { - return $this->kirby->component('thumb')->create($this, $params); - } - } - - /** - * Scales the image if possible - * - * @param int $width - * @param mixed $height - * @param mixed $quality - * @return Asset - */ - public function resize($width, $height = null, $quality = null) { - - $params = ['width' => $width]; - - if($height) $params['height'] = $height; - if($quality) $params['quality'] = $quality; - - return $this->thumb($params); - - } - - /** - * Scales and crops the image if possible - * - * @param int $width - * @param mixed $height - * @param mixed $quality - * @return Asset - */ - public function crop($width, $height = null, $quality = null) { - - $params = ['width' => $width, 'crop' => true]; - - if($height) $params['height'] = $height; - if($quality) $params['quality'] = $quality; - - return $this->thumb($params); - - } - - /** - * Scales the width of the image - * - * @param int $width - * @param mixed $quality - * @return Asset - */ - public function width($width = null, $quality = null) { - - if($width === null) { - return parent::width(); - } - - $params = ['width' => $width]; - - if($quality) $params['quality'] = $quality; - - return $this->thumb($params); - - } - - /** - * Scales the height of the image - * - * @param int $height - * @param mixed $quality - * @return Asset - */ - public function height($height = null, $quality = null) { - - if($height === null) { - return parent::height(); - } - - $params = ['height' => $height]; - - if($quality) $params['quality'] = $quality; - - return $this->thumb($params); - - } - - /** - * - */ - public function ratio($ratio = null) { - - if($ratio === null) { - return parent::ratio(); - } - - if($this->isLandscape() || $this->isSquare()) { - $width = $this->width(); - $height = round($width / $ratio); - } else { - $height = $this->height(); - $width = round($height * $ratio); - } - - return $this->crop($width, $height); - - } - - /** - * - */ - public function scale($value) { - return $this->thumb(['width' => $this->width() * $value, 'upscale' => true]); - } - - /** - * Converts the image to grayscale - * - * @return Asset - */ - public function bw() { - return $this->thumb(['grayscale' => true]); - } - - /** - * Blurs the image - * - * @return Asset - */ - public function blur() { - return $this->thumb(['blur' => true]); - } - - /** - * Checks if the asset is a thumbnail - * - * @return boolean - */ - public function isThumb() { - return str::startsWith($this->url(), $this->kirby->urls()->thumbs()); - } - - /** - * Check if the file/image has a websafe format - * - * @return boolean - */ - public function isWebsafe() { - return in_array(strtolower($this->extension()), ['jpg', 'jpeg', 'gif', 'png']); - } - - /** - * Makes it possible to echo the entire object - * - * @return string - */ - public function __toString() { - if($this->isWebsafe()) { - return (string)$this->html(); - } else { - return (string)$this->root; - } - } - -} \ No newline at end of file diff --git a/kirby/kirby/urls.php b/kirby/kirby/urls.php deleted file mode 100644 index 1da8565..0000000 --- a/kirby/kirby/urls.php +++ /dev/null @@ -1,47 +0,0 @@ -index)) return $this->index; - - if(r::cli()) { - return $this->index = '/'; - } else { - return $this->index = url::base() . preg_replace('!\/index\.php$!i', '', server::get('SCRIPT_NAME')); - } - - } - - public function content() { - return isset($this->content) ? $this->content : url::makeAbsolute('content', $this->index); - } - - public function thumbs() { - return isset($this->thumbs) ? $this->thumbs : url::makeAbsolute('thumbs', $this->index); - } - - public function assets() { - return isset($this->assets) ? $this->assets : url::makeAbsolute('assets', $this->index); - } - - public function autocss() { - return isset($this->autocss) ? $this->autocss : $this->assets() . '/css/templates'; - } - - public function autojs() { - return isset($this->autojs) ? $this->autojs : $this->assets() . '/js/templates'; - } - - public function avatars() { - return isset($this->avatars) ? $this->avatars : $this->assets() . '/avatars'; - } - -} \ No newline at end of file diff --git a/kirby/lib/pageextension.php b/kirby/lib/pageextension.php deleted file mode 100644 index 4517394..0000000 --- a/kirby/lib/pageextension.php +++ /dev/null @@ -1,17 +0,0 @@ -parent(), $page->dirname()); - } else { - throw new Exception('The page could not be found'); - } - } -} \ No newline at end of file diff --git a/kirby/lib/structure.php b/kirby/lib/structure.php deleted file mode 100644 index 4d8ff81..0000000 --- a/kirby/lib/structure.php +++ /dev/null @@ -1,42 +0,0 @@ -data[$key])) { - return $this->data[$key]; - } else { - $lowerkeys = array_change_key_case($this->data, CASE_LOWER); - $lowerkey = strtolower($key); - if(isset($lowerkeys[$lowerkey])) { - return $lowerkeys[$lowerkey]; - } - } - - return new Field($this->page, $key, null); - - } - - /** - * Get formatted date fields - * - * @param string $format - * @param string $field - * @return string - */ - public function date($format = null, $field = 'date') { - - if($timestamp = strtotime($this->get($field))) { - if(is_null($format)) { - return $timestamp; - } else { - return kirby()->options['date.handler']($format, $timestamp); - } - } - - } - -} \ No newline at end of file diff --git a/kirby/readme.md b/kirby/readme.md deleted file mode 100644 index 78ec751..0000000 --- a/kirby/readme.md +++ /dev/null @@ -1,18 +0,0 @@ -# Kirby Core - -This is the Kirby Core submodule. - -Please refer to the [Kirby Starterkit](http://github.com/getkirby/starterkit) -for a complete installation of Kirby - -![Build Status](https://travis-ci.org/getkirby/kirby.svg?branch=master) - -## Author -Bastian Allgeier - - -## Website - - -## License - diff --git a/kirby/system.php b/kirby/system.php deleted file mode 100644 index 2338915..0000000 --- a/kirby/system.php +++ /dev/null @@ -1,21 +0,0 @@ -roots->index = $root; -$kirby->roots->site = $rootSite; -$kirby->roots->content = $rootContent; - -// render -echo $kirby->launch(); \ No newline at end of file diff --git a/kirby/toolkit/bootstrap.php b/kirby/toolkit/bootstrap.php deleted file mode 100644 index 6aeb70a..0000000 --- a/kirby/toolkit/bootstrap.php +++ /dev/null @@ -1,97 +0,0 @@ - __DIR__ . DS . 'lib' . DS . 'a.php', - 'bitmask' => __DIR__ . DS . 'lib' . DS . 'bitmask.php', - 'brick' => __DIR__ . DS . 'lib' . DS . 'brick.php', - 'c' => __DIR__ . DS . 'lib' . DS . 'c.php', - 'cookie' => __DIR__ . DS . 'lib' . DS . 'cookie.php', - 'cache' => __DIR__ . DS . 'lib' . DS . 'cache.php', - 'cache\\driver' => __DIR__ . DS . 'lib' . DS . 'cache' . DS . 'driver.php', - 'cache\\driver\\apc' => __DIR__ . DS . 'lib' . DS . 'cache' . DS . 'driver' . DS . 'apc.php', - 'cache\\driver\\file' => __DIR__ . DS . 'lib' . DS . 'cache' . DS . 'driver' . DS . 'file.php', - 'cache\\driver\\memcached' => __DIR__ . DS . 'lib' . DS . 'cache' . DS . 'driver' . DS . 'memcached.php', - 'cache\\driver\\mock' => __DIR__ . DS . 'lib' . DS . 'cache' . DS . 'driver' . DS . 'mock.php', - 'cache\\driver\\session' => __DIR__ . DS . 'lib' . DS . 'cache' . DS . 'driver' . DS . 'session.php', - 'cache\\value' => __DIR__ . DS . 'lib' . DS . 'cache' . DS . 'value.php', - 'collection' => __DIR__ . DS . 'lib' . DS . 'collection.php', - 'crypt' => __DIR__ . DS . 'lib' . DS . 'crypt.php', - 'data' => __DIR__ . DS . 'lib' . DS . 'data.php', - 'database' => __DIR__ . DS . 'lib' . DS . 'database.php', - 'database\\query' => __DIR__ . DS . 'lib' . DS . 'database' . DS . 'query.php', - 'db' => __DIR__ . DS . 'lib' . DS . 'db.php', - 'detect' => __DIR__ . DS . 'lib' . DS . 'detect.php', - 'dimensions' => __DIR__ . DS . 'lib' . DS . 'dimensions.php', - 'dir' => __DIR__ . DS . 'lib' . DS . 'dir.php', - 'email' => __DIR__ . DS . 'lib' . DS . 'email.php', - 'embed' => __DIR__ . DS . 'lib' . DS . 'embed.php', - 'error' => __DIR__ . DS . 'lib' . DS . 'error.php', - 'errorreporting' => __DIR__ . DS . 'lib' . DS . 'errorreporting.php', - 'escape' => __DIR__ . DS . 'lib' . DS . 'escape.php', - 'exif' => __DIR__ . DS . 'lib' . DS . 'exif.php', - 'exif\\camera' => __DIR__ . DS . 'lib' . DS . 'exif' . DS . 'camera.php', - 'exif\\location' => __DIR__ . DS . 'lib' . DS . 'exif' . DS . 'location.php', - 'f' => __DIR__ . DS . 'lib' . DS . 'f.php', - 'folder' => __DIR__ . DS . 'lib' . DS . 'folder.php', - 'header' => __DIR__ . DS . 'lib' . DS . 'header.php', - 'html' => __DIR__ . DS . 'lib' . DS . 'html.php', - 'i' => __DIR__ . DS . 'lib' . DS . 'i.php', - 'l' => __DIR__ . DS . 'lib' . DS . 'l.php', - 'media' => __DIR__ . DS . 'lib' . DS . 'media.php', - 'obj' => __DIR__ . DS . 'lib' . DS . 'obj.php', - 'pagination' => __DIR__ . DS . 'lib' . DS . 'pagination.php', - 'password' => __DIR__ . DS . 'lib' . DS . 'password.php', - 'r' => __DIR__ . DS . 'lib' . DS . 'r.php', - 'redirect' => __DIR__ . DS . 'lib' . DS . 'redirect.php', - 'remote' => __DIR__ . DS . 'lib' . DS . 'remote.php', - 'response' => __DIR__ . DS . 'lib' . DS . 'response.php', - 'router' => __DIR__ . DS . 'lib' . DS . 'router.php', - 's' => __DIR__ . DS . 'lib' . DS . 's.php', - 'server' => __DIR__ . DS . 'lib' . DS . 'server.php', - 'silo' => __DIR__ . DS . 'lib' . DS . 'silo.php', - 'sql' => __DIR__ . DS . 'lib' . DS . 'sql.php', - 'str' => __DIR__ . DS . 'lib' . DS . 'str.php', - 'system' => __DIR__ . DS . 'lib' . DS . 'system.php', - 'thumb' => __DIR__ . DS . 'lib' . DS . 'thumb.php', - 'timer' => __DIR__ . DS . 'lib' . DS . 'timer.php', - 'toolkit' => __DIR__ . DS . 'lib' . DS . 'toolkit.php', - 'tpl' => __DIR__ . DS . 'lib' . DS . 'tpl.php', - 'upload' => __DIR__ . DS . 'lib' . DS . 'upload.php', - 'url' => __DIR__ . DS . 'lib' . DS . 'url.php', - 'v' => __DIR__ . DS . 'lib' . DS . 'v.php', - 'visitor' => __DIR__ . DS . 'lib' . DS . 'visitor.php', - 'xml' => __DIR__ . DS . 'lib' . DS . 'xml.php', - 'yaml' => __DIR__ . DS . 'lib' . DS . 'yaml.php', - - // vendors - 'spyc' => __DIR__ . DS . 'vendors' . DS . 'yaml' . DS . 'yaml.php', - 'abeautifulsite\\simpleimage' => __DIR__ . DS . 'vendors' . DS . 'abeautifulsite' . DS . 'SimpleImage.php', - 'mimereader' => __DIR__ . DS . 'vendors' . DS . 'mimereader' . DS . 'mimereader.php', - -)); - -// load all helpers -include(__DIR__ . DS . 'helpers.php'); \ No newline at end of file diff --git a/kirby/toolkit/helpers.php b/kirby/toolkit/helpers.php deleted file mode 100644 index cf39329..0000000 --- a/kirby/toolkit/helpers.php +++ /dev/null @@ -1,353 +0,0 @@ -' . print_r($variable, true) . ''; - } - if($echo === true) echo $output; - return $output; -} - -/** - * Generates a single attribute or a list of attributes - * - * @see html::attr(); - * @param string $name mixed string: a single attribute with that name will be generated. array: a list of attributes will be generated. Don't pass a second argument in that case. - * @param string $value if used for a single attribute, pass the content for the attribute here - * @return string the generated html - */ -function attr($name, $value = null) { - return html::attr($name, $value); -} - -/** - * Creates safe html by encoding special characters - * - * @param string $text unencoded text - * @param bool $keepTags - * @return string - */ -function html($text, $keepTags = true) { - return html::encode($text, $keepTags); -} - -/** - * Shortcut for html() - * - * @see html() - * @param $text - * @param bool $keepTags - * @return string - */ -function h($text, $keepTags = true) { - return html::encode($text, $keepTags); -} - -/** - * Shortcut for xml::encode() - * - * @param $text - * @return string - */ -function xml($text) { - return xml::encode($text); -} - -/** - * Escape context specific output - * - * @param string $string Untrusted data - * @param string $context Location of output - * @param boolean $strict Whether to escape an extended set of characters (HTML attributes only) - * @return string Escaped data - */ -function esc($string, $context = 'html', $strict = false) { - if (method_exists('escape', $context)) { - return escape::$context($string, $strict); - } -} - -/** - * The widont function makes sure that there are no - * typographical widows at the end of a paragraph – - * that's a single word in the last line - * - * @param string $string - * @return string - */ -function widont($string = '') { - return str::widont($string); -} - -/** - * Convert a text to multiline text - * - * @param string $text - * @return string - */ -function multiline($text) { - return nl2br(html($text)); -} - -/** - * Returns the memory usage in a readable format - * - * @return string - */ -function memory() { - return f::niceSize(memory_get_usage()); -} - -/** - * Determines the size/length of numbers, strings, arrays and files - * - * @param mixed $value - * @return int - */ -function size($value) { - if(is_numeric($value)) return $value; - if(is_string($value)) return str::length(trim($value)); - if(is_array($value)) return count($value); - if(f::exists($value)) return f::size($value) / 1024; -} - -/** - * Generates a gravatar image link - * - * @param string $email - * @param int $size - * @param string $default - * @return string - */ -function gravatar($email, $size = 256, $default = 'mm') { - return 'https://gravatar.com/avatar/' . md5(strtolower(trim($email))) . '?d=' . urlencode($default) . '&s=' . $size; -} - -/** - * Checks / returns a csrf token - * - * @param string $check Pass a token here to compare it to the one in the session - * @return mixed Either the token or a boolean check result - */ -function csrf($check = null) { - - // make sure a session is started - s::start(); - - if(is_null($check)) { - $token = str::random(64); - s::set('csrf', $token); - return $token; - } - - return ($check === s::get('csrf')) ? true : false; - -} - -/** - * Facepalm typo alias - * @see csrf() - */ -function csfr($check = null) { - return csrf($check); -} - -/** - * Shortcut for call_user_func_array with a better handling of arguments - * - * @param mixed $function - * @param mixed $arguments - * @return mixed - */ -function call($function, $arguments = array()) { - if(!is_callable($function)) return false; - if(!is_array($arguments)) $arguments = array($arguments); - return call_user_func_array($function, $arguments); -} - -/** - * Parses yaml structured text - * - * @param $string - * @return array - */ -function yaml($string) { - return yaml::decode($string); -} - -/** - * Simple email sender helper - * - * @param array $params - * @return Email - */ -function email($params = array()) { - return new Email($params); -} - -/** - * Shortcut for the upload class - * - * @param $to - * @param array $params - * @return Upload - */ -function upload($to, $params = array()) { - return new Upload($to, $params); -} - -/** - * Checks for invalid data - * - * @param array $data - * @param array $rules - * @param array $messages - * @return mixed - */ -function invalid($data, $rules, $messages = array()) { - $errors = array(); - foreach($rules as $field => $validations) { - foreach($validations as $method => $options) { - if(is_numeric($method)) $method = $options; - if($method == 'required') { - if(!isset($data[$field]) || (empty($data[$field]) && $data[$field] !== 0)) { - $errors[$field] = a::get($messages, $field, $field); - } - } else if(!empty($data[$field]) || $data[$field] === 0) { - if(!is_array($options)) $options = array($options); - array_unshift($options, a::get($data, $field)); - if(!call(array('v', $method), $options)) { - $errors[$field] = a::get($messages, $field, $field); - } - } - } - } - return array_unique($errors); -} - - -/** - * Shortcut for the language variable getter - * - * @param string $key - * @param mixed $default - * @return string - */ -function l($key, $default = null) { - return l::get($key, $default); -} - -/** - * @param $tag - * @param bool $html - * @param array $attr - * @return Brick - */ -function brick($tag, $html = false, $attr = array()) { - return new Brick($tag, $html, $attr); -} diff --git a/kirby/toolkit/lib/a.php b/kirby/toolkit/lib/a.php deleted file mode 100644 index 309649f..0000000 --- a/kirby/toolkit/lib/a.php +++ /dev/null @@ -1,495 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class A { - - /** - * Gets an element of an array by key - * - * - * - * $array = array( - * 'cat' => 'miao', - * 'dog' => 'wuff', - * 'bird' => 'tweet' - * ); - * - * echo a::get($array, 'cat'); - * // output: 'miao' - * - * echo a::get($array, 'elephant', 'shut up'); - * // output: 'shut up' - * - * $catAndDog = a::get(array('cat', 'dog')); - * // result: array( - * // 'cat' => 'miao', - * // 'dog' => 'wuff' - * // ); - * - * - * - * @param array $array The source array - * @param mixed $key The key to look for - * @param mixed $default Optional default value, which should be returned if no element has been found - * @return mixed - */ - public static function get($array, $key, $default = null) { - - // get an array of keys - if(is_array($key)) { - $result = array(); - foreach($key as $k) $result[$k] = static::get($array, $k); - return $result; - - // get a single - } else if(isset($array[$key])) { - return $array[$key]; - - // return the entire array if the key is null - } else if(is_null($key)) { - return $array; - - // get the default value if nothing else worked out - } else { - return $default; - } - - } - - /** - * Shows an entire array or object in a human readable way - * This is perfect for debugging - * - * - * - * $array = array( - * 'cat' => 'miao', - * 'dog' => 'wuff', - * 'bird' => 'tweet' - * ); - * - * a::show($array); - * - * // output: - * // Array - * // ( - * // [cat] => miao - * // [dog] => wuff - * // [bird] => tweet - * // ) - * - * - * - * @param array $array The source array - * @param boolean $echo By default the result will be echoed instantly. You can switch that off here. - * @return mixed If echo is false, this will return the generated array output. - */ - public static function show($array, $echo = true) { - return dump($array, $echo); - } - - /** - * Converts an array to a JSON string - * It's basically a shortcut for json_encode() - * - * - * - * $array = array( - * 'cat' => 'miao', - * 'dog' => 'wuff', - * 'bird' => 'tweet' - * ); - * - * echo a::json($array); - * // output: {"cat":"miao","dog":"wuff","bird":"tweet"} - * - * - * - * @param array $array The source array - * @return string The JSON string - */ - public static function json($array) { - return json_encode((array)$array); - } - - /** - * Converts an array to a XML string - * - * - * - * $array = array( - * 'cat' => 'miao', - * 'dog' => 'wuff', - * 'bird' => 'tweet' - * ); - * - * echo a::xml($array, 'animals'); - * // output: - * // - * // miao - * // wuff - * // tweet - * // - * - * - * - * @param array $array The source array - * @param string $tag The name of the root element - * @param boolean $head Include the xml declaration head or not - * @param string $charset The charset, which should be used for the header - * @param int $level The indendation level - * @return string The XML string - */ - public static function xml($array, $tag = 'root', $head = true, $charset = 'utf-8', $tab = ' ', $level = 0) { - return xml::create($array, $tag, $head, $charset, $tab, $level); - } - - /** - * Extracts a single column from an array - * - * - * - * $array[0] = array( - * 'id' => 1, - * 'username' => 'bastian', - * ); - * - * $array[1] = array( - * 'id' => 2, - * 'username' => 'peter', - * ); - * - * $array[3] = array( - * 'id' => 3, - * 'username' => 'john', - * ); - * - * $extract = a::extract($array, 'username'); - * - * // result: array( - * // 'bastian', - * // 'peter', - * // 'john' - * // ); - * - * - * - * @param array $array The source array - * @param string $key The key name of the column to extract - * @return array The result array with all values from that column. - */ - public static function extract($array, $key) { - $output = array(); - foreach($array AS $a) if(isset($a[$key])) $output[] = $a[ $key ]; - return $output; - } - - /** - * Shuffles an array and keeps the keys - * - * - * - * $array = array( - * 'cat' => 'miao', - * 'dog' => 'wuff', - * 'bird' => 'tweet' - * ); - * - * $shuffled = a::shuffle($array); - * // output: array( - * // 'dog' => 'wuff', - * // 'cat' => 'miao', - * // 'bird' => 'tweet' - * // ); - * - * - * - * @param array $array The source array - * @return array The shuffled result array - */ - public static function shuffle($array) { - - $keys = array_keys($array); - $new = array(); - - shuffle($keys); - - // resort the array - foreach($keys as $key) $new[$key] = $array[$key]; - return $new; - - } - - /** - * Returns the first element of an array - * - * I always have to lookup the names of that function - * so I decided to make this shortcut which is - * easier to remember. - * - * - * - * $array = array( - * 'cat', - * 'dog', - * 'bird', - * ); - * - * $first = a::first($array); - * // first: 'cat' - * - * - * - * @param array $array The source array - * @return mixed The first element - */ - public static function first($array) { - return array_shift($array); - } - - /** - * Returns the last element of an array - * - * I always have to lookup the names of that function - * so I decided to make this shortcut which is - * easier to remember. - * - * - * - * $array = array( - * 'cat', - * 'dog', - * 'bird', - * ); - * - * $last = a::last($array); - * // first: 'bird' - * - * - * - * @param array $array The source array - * @return mixed The last element - */ - public static function last($array) { - return array_pop($array); - } - - /** - * Fills an array up with additional elements to certain amount. - * - * - * - * $array = array( - * 'cat', - * 'dog', - * 'bird', - * ); - * - * $result = a::fill($array, 5, 'elephant'); - * - * // result: array( - * // 'cat', - * // 'dog', - * // 'bird', - * // 'elephant', - * // 'elephant', - * // ); - * - * - * - * @param array $array The source array - * @param int $limit The number of elements the array should contain after filling it up. - * @param mixed $fill The element, which should be used to fill the array - * @return array The filled-up result array - */ - public static function fill($array, $limit, $fill='placeholder') { - if(count($array) < $limit) { - $diff = $limit-count($array); - for($x=0; $x<$diff; $x++) $array[] = $fill; - } - return $array; - } - - /** - * Checks for missing elements in an array - * - * This is very handy to check for missing - * user values in a request for example. - * - * - * - * $array = array( - * 'cat' => 'miao', - * 'dog' => 'wuff', - * 'bird' => 'tweet' - * ); - * - * $required = array('cat', 'elephant'); - * - * $missng = a::missing($array, $required); - * // missing: array( - * // 'elephant' - * // ); - * - * - * - * @param array $array The source array - * @param array $required An array of required keys - * @return array An array of missing fields. If this is empty, nothing is missing. - */ - public static function missing($array, $required=array()) { - $missing = array(); - foreach($required AS $r) { - if(empty($array[$r])) $missing[] = $r; - } - return $missing; - } - - /** - * Sorts a multi-dimensional array by a certain column - * - * - * - * $array[0] = array( - * 'id' => 1, - * 'username' => 'bastian', - * ); - * - * $array[1] = array( - * 'id' => 2, - * 'username' => 'peter', - * ); - * - * $array[3] = array( - * 'id' => 3, - * 'username' => 'john', - * ); - * - * $sorted = a::sort($array, 'username ASC'); - * // Array - * // ( - * // [0] => Array - * // ( - * // [id] => 1 - * // [username] => bastian - * // ) - * // [1] => Array - * // ( - * // [id] => 3 - * // [username] => john - * // ) - * // [2] => Array - * // ( - * // [id] => 2 - * // [username] => peter - * // ) - * // ) - * - * - * - * @param array $array The source array - * @param string $field The name of the column - * @param string $direction desc (descending) or asc (ascending) - * @param const $method A PHP sort method flag or 'natural' for natural sorting, which is not supported in PHP by sort flags - * @return array The sorted array - */ - public static function sort($array, $field, $direction = 'desc', $method = SORT_REGULAR) { - - $direction = strtolower($direction) == 'desc' ? SORT_DESC : SORT_ASC; - $helper = array(); - $result = array(); - - // build the helper array - foreach($array as $key => $row) $helper[$key] = $row[$field]; - - // natural sorting - if($method === SORT_NATURAL) { - natsort($helper); - if($direction === SORT_DESC) $helper = array_reverse($helper); - } else if($direction === SORT_DESC) { - arsort($helper, $method); - } else { - asort($helper, $method); - } - - // rebuild the original array - foreach($helper as $key => $val) $result[$key] = $array[$key]; - - return $result; - - } - - /** - * Checks wether an array is associative or not (experimental) - * - * @param array $array The array to analyze - * @return boolean true: The array is associative false: It's not - */ - public static function isAssociative($array) { - return !ctype_digit(implode(NULL, array_keys($array))); - } - - /** - * Returns the average value of an array - * - * @param array $array The source array - * @param int $decimals The number of decimals to return - * @return int The average value - */ - public static function average($array, $decimals = 0) { - return round(array_sum($array), $decimals) / sizeof($array); - } - - /** - * Merges arrays recursively - * - * @param array $array1 - * @param array $array2 - * @return array - */ - public static function merge($array1, $array2) { - $merged = $array1; - foreach($array2 as $key => $value) { - if(is_array($value) && isset($merged[$key]) && is_array($merged[$key])) { - $merged[$key] = static::merge($merged[$key], $value); - } else { - $merged[$key] = $value; - } - } - return $merged; - } - - /** - * Update an array with a second array - * The second array can contain callbacks as values, - * which will get the original values as argument - * - * @param array $array - * @param array $update - */ - public static function update($array, $update) { - - foreach($update as $key => $value) { - if(is_a($value, 'Closure')) { - $array[$key] = call($value, static::get($array, $key)); - } else { - $array[$key] = $value; - } - } - - return $array; - - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/bitmask.php b/kirby/toolkit/lib/bitmask.php deleted file mode 100644 index db5e7f7..0000000 --- a/kirby/toolkit/lib/bitmask.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @link http://getkirby.com - * @copyright Lukas Bestle - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Bitmask { - - /** - * Checks if a value can be used as bitmask value (checks for a power of two) - * - * @param mixed $value The value to check for - * @return boolean - */ - public static function validValue($value) { - return is_int($value) && ($value & ($value - 1)) == 0; - } - - /** - * Checks if a bitmask includes a value - * - * @param int $value The value to check for - * @param int $bitmask The bitmask to check in - * @return boolean - */ - public static function includes($value, $bitmask) { - if(!static::validValue($value)) return false; - - return ($bitmask & $value) !== 0; - } - - /** - * Adds a value to a bitmask - * - * @param int $value The value to add - * @param int $bitmask The bitmask to add the value to - * @return int - */ - public static function add($value, $bitmask) { - if(!static::validValue($value)) { - throw new Exception('The value "' . $value . '" is not appropriate for usage in bitmasks.'); - } - - // check if the bitmask already includes the value - if(static::includes($value, $bitmask)) return $bitmask; - - return $bitmask | $value; - } - - /** - * Removes a value from a bitmask - * - * @param int $value The value to remove - * @param int $bitmask The bitmask to remove the value from - * @return int - */ - public static function remove($value, $bitmask) { - if(!static::validValue($value)) { - throw new Exception('The value "' . $value . '" is not appropriate for usage in bitmasks.'); - } - - // check if the bitmask even includes the value - if(!static::includes($value, $bitmask)) return $bitmask; - - return $bitmask ^ $value; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/brick.php b/kirby/toolkit/lib/brick.php deleted file mode 100644 index e83e97f..0000000 --- a/kirby/toolkit/lib/brick.php +++ /dev/null @@ -1,204 +0,0 @@ -tag($tag); - $this->html($html); - $this->attr($attr); - - } - - public function __set($attr, $value) { - $this->attr($attr, $value); - } - - public function on($event, $callback) { - if(!isset($this->events[$event])) $this->events[$event] = array(); - $this->events[$event][] = $callback; - return $this; - } - - public function trigger($event, $args = array()) { - if(isset($this->events[$event])) { - array_unshift($args, $this); - foreach($this->events[$event] as $e) { - call_user_func_array($e, $args); - } - } - } - - public function tag($tag = null) { - if(is_null($tag)) return $this->tag; - $this->tag = $tag; - return $this; - } - - public function attr($key = null, $value = null) { - if(is_null($key)) { - return $this->attr; - } else if(is_array($key)) { - foreach($key as $k => $v) { - $this->attr($k, $v); - } - return $this; - } else if(is_null($value)) { - return a::get($this->attr, $key); - } else if($key == 'class') { - $this->addClass($value); - return $this; - } else { - $this->attr[$key] = $value; - return $this; - } - } - - public function data($key = null, $value = null) { - if(is_null($key)) { - $data = array(); - foreach($this->attr as $key => $val) { - if(str::startsWith($key, 'data-')) { - $data[$key] = $val; - } - } - return $data; - } else if(is_array($key)) { - foreach($key as $k => $v) { - $this->data($k, $v); - } - return $this; - } else if(is_null($value)) { - return a::get($this->attr, 'data-' . $key); - } else { - $this->attr['data-' . $key] = $value; - return $this; - } - } - - - public function removeAttr($key) { - unset($this->attr[$key]); - } - - public function classNames() { - - if(!isset($this->attr['class'])) { - $this->attr['class'] = array(); - } else if(is_string($this->attr['class'])) { - $raw = $this->attr['class']; - $this->attr['class'] = array(); - $this->addClass($raw); - } - - return $this->attr['class']; - - } - - public function val($value = null) { - return $this->attr('value', $value); - } - - public function addClass($class) { - - $classNames = $this->classNames(); - $classIndex = array_map('strtolower', $classNames); - - foreach(str::split($class, ' ') as $c) { - if(!in_array(strtolower($c), $classIndex)) { - $classNames[] = $c; - } - } - - $this->attr['class'] = $classNames; - - return $this; - - } - - public function removeClass($class) { - - $classNames = $this->classNames(); - - foreach(str::split($class, ' ') as $c) { - $classNames = array_filter($classNames, function($e) use($c) { - return (strtolower($e) !== strtolower($c)); - }); - } - - $this->attr['class'] = $classNames; - - return $this; - - } - - public function replaceClass($classA, $classB) { - return $this->removeClass($classA)->addClass($classB); - } - - public function text($text = null) { - if(is_null($text)) return trim(strip_tags($this->html)); - $this->html = html($text, false); - return $this; - } - - public function html($html = null) { - if(is_null($html)) { - return $this->html = $this->isVoid() ? null : $this->html; - } - $this->html = $html; - return $this; - } - - public function prepend($html) { - if(is_callable($html)) $html = $html(); - $this->html = $html . $this->html; - return $this; - } - - public function append($html) { - if(is_callable($html)) $html = $html(); - $this->html = $this->html . $html; - return $this; - } - - public function isVoid() { - return html::isVoid($this->tag()); - } - - public function toString() { - $this->attr['class'] = implode(' ', $this->classNames()); - return html::tag($this->tag(), $this->html(), $this->attr()); - } - - public function __toString() { - try { - return $this->toString(); - } catch(Exception $e) { - return 'Error: ' . $e->getMessage(); - } - } - - public static function make($id, $callback) { - static::$bricks[$id] = $callback; - } - - public static function get($id) { - if(!isset(static::$bricks[$id])) return false; - $args = array_slice(func_get_args(), 1); - return call_user_func_array(static::$bricks[$id], $args); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/c.php b/kirby/toolkit/lib/c.php deleted file mode 100644 index cdb9b73..0000000 --- a/kirby/toolkit/lib/c.php +++ /dev/null @@ -1,17 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class C extends Silo { - public static $data = array(); -} \ No newline at end of file diff --git a/kirby/toolkit/lib/cache.php b/kirby/toolkit/lib/cache.php deleted file mode 100644 index 6f449e4..0000000 --- a/kirby/toolkit/lib/cache.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Cache { - - const ERROR_INVALID_DRIVER = 0; - const ERROR_INVALID_DRIVER_INSTANCE = 1; - const ERROR_UNKNOWN_METHOD = 2; - - public static $driver = null; - - /** - * Setup simplifier for the current driver - * - * @param string $driver - * @param mixed $args - * @return Cache\Driver - */ - public static function setup($driver, $args = null) { - $ref = new ReflectionClass('Cache\\Driver\\' . $driver); - return static::$driver = $ref->newInstanceArgs(array($args)); - } - - /** - * Accessor for all static driver methods - * - * @param string $method - * @param mixed $args - * @return mixed - */ - public static function __callStatic($method, $args) { - - if(is_null(static::$driver)) { - throw new Error('Please define a cache driver', static::ERROR_INVALID_DRIVER); - } - - if(!is_a(static::$driver, 'Cache\\Driver')) { - throw new Error('The cache driver must be an instance of the Cache\\Driver class', static::ERROR_INVALID_DRIVER_INSTANCE); - } - - if(method_exists(static::$driver, $method)) { - return call(array(static::$driver, $method), $args); - } else { - throw new Error('Invalid cache method: ' . $method, static::ERROR_UNKNOWN_METHOD); - } - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/cache/driver.php b/kirby/toolkit/lib/cache/driver.php deleted file mode 100755 index be6f4ae..0000000 --- a/kirby/toolkit/lib/cache/driver.php +++ /dev/null @@ -1,190 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -abstract class Driver { - - // stores all options for the driver - protected $options = array(); - - /** - * Set all parameters which are needed to connect to the cache storage - * - * @param array $params - */ - public function __construct($params = array()) {} - - /** - * Write an item to the cache for a given number of minutes. - * - * - * // Put an item in the cache for 15 minutes - * Cache::set('value', 'my value', 15); - * - * - * @param string $key - * @param mixed $value - * @param int $minutes - * @return void - */ - public abstract function set($key, $value, $minutes = null); - - /** - * Private method to retrieve the cache value - * This needs to be defined by the driver - * - * @param string $key - * @return object Value - */ - public abstract function retrieve($key); - - /** - * Get an item from the cache. - * - * - * // Get an item from the cache driver - * $value = Cache::get('value'); - * - * // Return a default value if the requested item isn't cached - * $value = Cache::get('value', 'default value'); - * - * - * @param string $key - * @param mixed $default - * @return mixed - */ - public function get($key, $default = null) { - - // get the Value - $value = $this->retrieve($key); - - // check for a valid cache value - if(!is_a($value, 'Cache\\Value')) return $default; - - // remove the item if it is expired - if(time() > $value->expires()) { - $this->remove($key); - return $default; - } - - // get the pure value - $cache = $value->value(); - - // return the cache value or the default - return (!is_null($cache)) ? $cache : $default; - - } - - /** - * Calculates the expiration timestamp - * - * @param int $minutes - * @return int - */ - protected function expiration($minutes = null) { - // keep forever if minutes are not defined - if(is_null($minutes)) $minutes = 2628000; - - // calculate the time - return time() + ($minutes * 60); - } - - /** - * Checks when an item in the cache expires - * - * @param string $key - * @return mixed - */ - public function expires($key) { - // get the Value object - $value = $this->retrieve($key); - - // check for a valid Value object - if(!is_a($value, 'Cache\\Value')) return false; - - // return the expires timestamp - return $value->expires(); - } - - /** - * Checks if an item in the cache is expired - * - * @param string $key - * @return int - */ - public function expired($key) { - return $this->expires($key) <= time(); - } - - /** - * Checks when the cache has been created - * - * @param string $key - * @return mixed - */ - public function created($key) { - // get the Value object - $value = $this->retrieve($key); - - // check for a valid Value object - if(!is_a($value, 'Cache\\Value')) return false; - - // return the expires timestamp - return $value->created(); - } - - /** - * Alternate version for cache::created($key) - */ - public function modified($key) { - return static::created($key); - } - - /** - * An array with value, created timestamp and expires timestamp - * - * @param mixed $value The value, which should be cached - * @param int $minutes The number of minutes before expiration - * @return array - */ - protected function value($value, $minutes) { - return new Value($value, $minutes); - } - - /** - * Determine if an item exists in the cache. - * - * @param string $key - * @return boolean - */ - public function exists($key) { - return !$this->expired($key); - } - - /** - * Remove an item from the cache - * - * @param string $key - * @return boolean - */ - public abstract function remove($key); - - /** - * Flush the entire cache - * - * @return boolean - */ - public abstract function flush(); - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/cache/driver/apc.php b/kirby/toolkit/lib/cache/driver/apc.php deleted file mode 100644 index ec7603b..0000000 --- a/kirby/toolkit/lib/cache/driver/apc.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Apc extends Driver { - - /** - * Write an item to the cache for a given number of minutes. - * - * - * // Put an item in the cache for 15 minutes - * Cache::set('value', 'my value', 15); - * - * - * @param string $key - * @param mixed $value - * @param int $minutes - * @return void - */ - public function set($key, $value, $minutes = null) { - return apc_store($key, $this->value($value, $minutes), $this->expiration($minutes)); - } - - /** - * Retrieve an item from the cache. - * - * @param string $key - * @return mixed - */ - public function retrieve($key) { - return apc_fetch($key); - } - - /** - * Checks if the current key exists in cache - * - * @param string $key - * @return boolean - */ - public function exists($key) { - return apc_exists($key); - } - - /** - * Remove an item from the cache - * - * @param string $key - * @return boolean - */ - public function remove($key) { - return apc_delete($key); - } - - /** - * Flush the entire cache directory - * - * @return boolean - */ - public function flush() { - return apc_clear_cache('user'); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/cache/driver/file.php b/kirby/toolkit/lib/cache/driver/file.php deleted file mode 100644 index 7563bd4..0000000 --- a/kirby/toolkit/lib/cache/driver/file.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class File extends Driver { - - const ERROR_MISSING_CACHE_DIRECTORY = 0; - - /** - * Set all parameters which are needed for the file cache - * see defaults for available parameters - * - * @param array $params - */ - public function __construct($params = array()) { - - if(is_string($params)) { - $params = array('root' => $params); - } - - $defaults = array( - 'root' => null, - 'extension' => null - ); - - $this->options = array_merge($defaults, $params); - - // check for a valid cache directory - if(!is_dir($this->options['root'])) { - throw new Error('The cache directory does not exist', static::ERROR_MISSING_CACHE_DIRECTORY); - } - - } - - /** - * Returns the full path to a file for a given key - * - * @param string $key - * @return string - */ - protected function file($key) { - return $this->options['root'] . DS . $key . r($this->options['extension'], '.' . $this->options['extension']); - } - - /** - * Write an item to the cache for a given number of minutes. - * - * - * // Put an item in the cache for 15 minutes - * Cache::set('value', 'my value', 15); - * - * - * @param string $key - * @param mixed $value - * @param int $minutes - * @return void - */ - public function set($key, $value, $minutes = null) { - return f::write($this->file($key), serialize($this->value($value, $minutes))); - } - - /** - * Retrieve an item from the cache. - * - * @param string $key - * @return object CacheValue - */ - public function retrieve($key) { - // unserialized value array (see $this->value()) - return unserialize(f::read($this->file($key))); - } - - /** - * Checks when the cache has been created - * - * @param string $key - * @return int - */ - public function created($key) { - // use the modification timestamp - // as indicator when the cache has been created/overwritten - clearstatcache(); - // get the file for this cache key - $file = $this->file($key); - return file_exists($file) ? filemtime($this->file($key)) : 0; - } - - /** - * Remove an item from the cache - * - * @param string $key - * @return boolean - */ - public function remove($key) { - return f::remove($this->file($key)); - } - - /** - * Flush the entire cache directory - * - * @return boolean - */ - public function flush() { - return dir::clean($this->options['root']); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/cache/driver/memcached.php b/kirby/toolkit/lib/cache/driver/memcached.php deleted file mode 100644 index 8320467..0000000 --- a/kirby/toolkit/lib/cache/driver/memcached.php +++ /dev/null @@ -1,128 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Memcached extends Driver { - - // store for the memache connection - protected $connection = null; - - /** - * Set all parameters which are needed for the memcache client - * see defaults for available parameters - * - * @param array $params - */ - public function __construct($params = array()) { - - $defaults = array( - 'host' => 'localhost', - 'port' => 11211, - 'prefix' => null, - ); - - $this->options = array_merge($defaults, (array)$params); - $this->connection = new \Memcached(); - $this->connection->addServer($this->options['host'], $this->options['port']); - - } - - /** - * Write an item to the cache for a given number of minutes. - * - * - * // Put an item in the cache for 15 minutes - * Cache::set('value', 'my value', 15); - * - * - * @param string $key - * @param mixed $value - * @param int $minutes - * @return void - */ - public function set($key, $value, $minutes = null) { - return $this->connection->set($this->key($key), $this->value($value, $minutes), $this->expiration($minutes)); - } - - /** - * Returns the full keyname - * including the prefix (if set) - * - * @param string $key - * @return string - */ - public function key($key) { - return $this->options['prefix'] . $key; - } - - /** - * Retrieve the CacheValue object from the cache. - * - * @param string $key - * @return object CacheValue - */ - public function retrieve($key) { - return $this->connection->get($this->key($key)); - } - - /** - * Remove an item from the cache - * - * @param string $key - * @return boolean - */ - public function remove($key) { - return $this->connection->delete($this->key($key)); - } - - /** - * Checks when an item in the cache expires - * - * @param string $key - * @return int - */ - public function expires($key) { - return parent::expires($this->key($key)); - } - - /** - * Checks if an item in the cache is expired - * - * @param string $key - * @return int - */ - public function expired($key) { - return parent::expired($this->key($key)); - } - - /** - * Checks when the cache has been created - * - * @param string $key - * @return int - */ - public function created($key) { - return parent::created($this->key($key)); - } - - /** - * Flush the entire cache directory - * - * @return boolean - */ - public function flush() { - return $this->connection->flush(); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/cache/driver/mock.php b/kirby/toolkit/lib/cache/driver/mock.php deleted file mode 100644 index 0c95484..0000000 --- a/kirby/toolkit/lib/cache/driver/mock.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Mock extends Driver { - - /** - * Write an item to the cache for a given number of minutes. - * - * - * // Put an item in the cache for 15 minutes - * Cache::set('value', 'my value', 15); - * - * - * @param string $key - * @param mixed $value - * @param int $minutes - * @return void - */ - public function set($key, $value, $minutes = null) { - return true; - } - - /** - * Retrieve an item from the cache. - * - * @param string $key - * @return mixed - */ - public function retrieve($key) { - return null; - } - - /** - * Checks if the current key exists in cache - * - * @param string $key - * @return boolean - */ - public function exists($key) { - return null; - } - - /** - * Remove an item from the cache - * - * @param string $key - * @return boolean - */ - public function remove($key) { - return true; - } - - /** - * Flush the entire cache directory - * - * @return boolean - */ - public function flush() { - return true; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/cache/driver/session.php b/kirby/toolkit/lib/cache/driver/session.php deleted file mode 100644 index 5971c8f..0000000 --- a/kirby/toolkit/lib/cache/driver/session.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Session extends Driver { - - /** - * Make sure the session is started within the constructor - */ - public function __construct() { - s::start(); - if(!isset($_SESSION['_cache'])) { - $_SESSION['_cache'] = array(); - } - } - - /** - * Write an item to the cache for a given number of minutes. - * - * - * // Put an item in the cache for 15 minutes - * Cache::set('value', 'my value', 15); - * - * - * @param string $key - * @param mixed $value - * @param int $minutes - * @return void - */ - public function set($key, $value, $minutes = null) { - return $_SESSION['_cache'][$key] = $this->value($value, $minutes); - } - - /** - * Retrieve an item from the cache. - * - * @param string $key - * @return object CacheValue - */ - public function retrieve($key) { - return a::get($_SESSION['_cache'], $key); - } - - /** - * Remove an item from the cache - * - * @param string $key - * @return boolean - */ - public function remove($key) { - unset($_SESSION['_cache'][$key]); - } - - /** - * Flush the entire cache directory - * - * @return boolean - */ - public function flush() { - $_SESSION['_cache'] = array(); - return true; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/cache/value.php b/kirby/toolkit/lib/cache/value.php deleted file mode 100644 index f2bfc8a..0000000 --- a/kirby/toolkit/lib/cache/value.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Value { - - // the cached value - protected $value; - - // the expiration timestamp - protected $expires; - - // the creation timestamp - protected $created; - - /** - * Constructor - * - * @param mixed $value - * @param int $minutes the number of minutes until the value expires - */ - public function __construct($value, $minutes = null) { - - // keep forever if minutes are not defined - if(is_null($minutes)) $minutes = 2628000; - - // take the current time - $time = time(); - - $this->value = $value; - $this->expires = $time + ($minutes * 60); - $this->created = $time; - - } - - /** - * Returns the value - * - * @return mixed - */ - public function value() { - return $this->value; - } - - /** - * Returns the expiration date as UNIX timestamp - * - * @return int - */ - public function expires() { - return $this->expires; - } - - /** - * Returns the creation date as UNIX timestamp - * - * @return int - */ - public function created() { - return $this->created; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/collection.php b/kirby/toolkit/lib/collection.php deleted file mode 100644 index 79b88af..0000000 --- a/kirby/toolkit/lib/collection.php +++ /dev/null @@ -1,652 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Collection extends I { - - public static $filters = array(); - - protected $pagination; - - /** - * Returns a slice of the collection - * - * @param int $offset The optional index to start the slice from - * @param int $limit The optional number of elements to return - * @return Collection - */ - public function slice($offset = null, $limit = null) { - if($offset === null && $limit === null) return $this; - $collection = clone $this; - $collection->data = array_slice($collection->data, $offset, $limit); - return $collection; - } - - /** - * Returns a new combined collection - * - * @return Collection - */ - - public function merge($collection2) { - $collection = clone $this; - $collection->data = a::merge($collection->data, $collection2->data); - return $collection; - } - - /** - * Returns a new collection with a limited number of elements - * - * @param int $limit The number of elements to return - * @return Collection - */ - public function limit($limit) { - return $this->slice(0, $limit); - } - - /** - * Returns a new collection starting from the given offset - * - * @param int $offset The index to start from - * @return Collection - */ - public function offset($offset) { - return $this->slice($offset); - } - - /** - * Returns the array in reverse order - * - * @return Collection - */ - public function flip() { - $collection = clone $this; - $collection->data = array_reverse($collection->data, true); - return $collection; - } - - /** - * Counts all elements in the array - * - * @return int - */ - public function count() { - return count($this->data); - } - - /** - * Returns the first element from the array - * - * @return mixed - */ - public function first() { - $array = $this->data; - return array_shift($array); - } - - /** - * Checks if an element is in the collection by key. - * - * @param string $key - * @return boolean - */ - public function has($key) { - return isset($this->data[$key]); - } - - /** - * Returns the last element from the array - * - * @return mixed - */ - public function last() { - $array = $this->data; - return array_pop($array); - } - - /** - * Returns the nth element from the array - * - * @return mixed - */ - public function nth($n) { - $array = array_values($this->data); - return (isset($array[$n])) ? $array[$n] : false; - } - - /** - * Converts the current object into an array - * - * @return array - */ - public function toArray($callback = null) { - if(is_null($callback)) return $this->data; - return array_map($callback, $this->data); - } - - /** - * Converts the current object into a json string - * - * @return string - */ - public function toJson() { - return json_encode($this->data); - } - - /** - * Appends an element to the data array - * - * @param string $key - * @param mixed $object - * @return Collection - */ - public function append($key, $object) { - $this->data = $this->data + array($key => $object); - return $this; - } - - /** - * Prepends an element to the data array - * - * @param string $key - * @param mixed $object - * @return Collection - */ - public function prepend($key, $object) { - $this->data = array($key => $object) + $this->data; - return $this; - } - - /** - * Returns a new collection without the given element(s) - * - * @param args any number of keys, passed as individual arguments - * @return Collection - */ - public function not() { - $collection = clone $this; - foreach(func_get_args() as $kill) { - unset($collection->data[$kill]); - } - return $collection; - } - - /** - * Returns a new collection without the given element(s) - * - * @param args any number of keys, passed as individual arguments - * @return Collection - */ - public function without() { - return call_user_func_array(array($this, 'not'), func_get_args()); - } - - /** - * Shuffle all elements in the array - * - * @return object a new shuffled collection - */ - public function shuffle() { - $collection = clone $this; - $keys = array_keys($collection->data); - shuffle($keys); - $collection->data = array_merge(array_flip($keys), $collection->data); - return $collection; - } - - /** - * Returns an array of all keys in the collection - * - * @return array - */ - public function keys() { - return array_keys($this->data); - } - - /** - * Tries to find the key for the given element - * - * @param mixed $needle the element to search for - * @return mixed the name of the key or false - */ - public function keyOf($needle) { - return array_search($needle, $this->data); - } - - /** - * Tries to find the index number for the given element - * - * @param mixed $needle the element to search for - * @return mixed the name of the key or false - */ - public function indexOf($needle) { - return array_search($needle, array_values($this->data)); - } - - /** - * Filter the elements in the array by a callback function - * - * @param func $callback the callback function - * @return Collection - */ - public function filter($callback) { - $collection = clone $this; - $collection->data = array_filter($collection->data, $callback); - return $collection; - } - - /** - * Find a single item by a key and value pair - * - * @param string $key - * @param mixed $value - * @return mixed - */ - public function findBy($key, $value) { - foreach($this->data as $item) { - if($this->extractValue($item, $key) == $value) return $item; - } - } - - /** - * Filters the current collection by a field, operator and search value - * - * @return Collection - */ - public function filterBy() { - - $args = func_get_args(); - $operator = '=='; - $field = @$args[0]; - $value = @$args[1]; - $split = @$args[2]; - $collection = clone $this; - - if(is_string($value) && array_key_exists($value, static::$filters)) { - $operator = $value; - $value = @$args[2]; - $split = @$args[3]; - } - - if(is_object($value)) { - $value = (string)$value; - } - - if(array_key_exists($operator, static::$filters)) { - - $collection = call_user_func_array(static::$filters[$operator], array( - $collection, - $field, - $value, - $split - )); - - } - - return $collection; - - } - - /** - * Makes sure to provide a valid value for each filter method - * no matter if an object or an array is given - * - * @param mixed $item - * @param string $field - * @return mixed - */ - static public function extractValue($item, $field) { - if(is_array($item) && isset($item[$field])) { - return $item[$field]; - } else if(is_object($item)) { - return $item->$field(); - } else { - return false; - } - } - - /** - * Sorts the collection by any number of fields - * - * @return Collection - */ - public function sortBy() { - - $args = func_get_args(); - $collection = clone $this; - $array = $collection->data; - $params = array(); - - if(empty($array)) return $collection; - - foreach($args as $i => $param) { - if(is_string($param)) { - if(strtolower($param) === 'desc') { - ${"param_$i"} = SORT_DESC; - } else if(strtolower($param) === 'asc') { - ${"param_$i"} = SORT_ASC; - } else { - ${"param_$i"} = array(); - foreach($array as $index => $row) { - ${"param_$i"}[$index] = is_array($row) ? str::lower($row[$param]) : str::lower($row->$param()); - } - } - } else { - ${"param_$i"} = $args[$i]; - } - $params[] = &${"param_$i"}; - } - - $params[] = &$array; - - call_user_func_array('array_multisort', $params); - - $collection->data = $array; - - return $collection; - - } - - /** - * Add pagination - * - * @param int $limit the number of items per page - * @param array $options and optional array with options for the pagination class - * @return object a sliced set of data - */ - public function paginate($limit, $options = array()) { - - if(is_a($limit, 'Pagination')) { - $this->pagination = $limit; - return $this; - } - - $pagination = new Pagination($this->count(), $limit, $options); - $pages = $this->slice($pagination->offset(), $pagination->limit()); - $pages->pagination = $pagination; - - return $pages; - - } - - /** - * Get the previously added pagination object - * - * @return object - */ - public function pagination() { - return $this->pagination; - } - - /** - * Map a function to each item in the collection - * - * @param function $callback - * @return Collection - */ - public function map($callback) { - $this->data = array_map($callback, $this->data); - return $this; - } - - /** - * Extracts all values for a single field into - * a new array - * - * @param string $field - * @return array - */ - public function pluck($field, $split = null, $unique = false) { - - $result = array(); - - foreach($this->data as $item) { - $row = $this->extractValue($item, $field); - - if($split) { - $result = array_merge($result, str::split($row, $split)); - } else { - $result[] = $row; - } - - } - - if($unique) { - $result = array_unique($result); - } - - return array_values($result); - - } - - /** - * Groups the collection by a given callback - * - * @param callable $callback - * @return object A new collection with an item for each group and a subcollection in each group - */ - public function group($callback) { - - if (!is_callable($callback)) throw new Exception($callback . ' is not callable. Did you mean to use groupBy()?'); - - $groups = array(); - - foreach($this->data as $key => $item) { - - // get the value to group by - $value = call_user_func($callback, $item); - - // make sure that there's always a proper value to group by - if(!$value) throw new Exception('Invalid grouping value for key: ' . $key); - - // make sure we have a proper key for each group - if(is_array($value)) { - throw new Exception('You cannot group by arrays or objects'); - } else if(is_object($value)) { - if(!method_exists($value, '__toString')) { - throw new Exception('You cannot group by arrays or objects'); - } else { - $value = (string)$value; - } - } - - if(!isset($groups[$value])) { - // create a new entry for the group if it does not exist yet - $groups[$value] = new static(array($key => $item)); - } else { - // add the item to an existing group - $groups[$value]->set($key, $item); - } - - } - - return new Collection($groups); - - } - - /** - * Groups the collection by a given field - * - * @param string $field - * @return object A new collection with an item for each group and a subcollection in each group - */ - public function groupBy($field, $i = true) { - - if (!is_string($field)) throw new Exception('Cannot group by non-string values. Did you mean to call group()?'); - - return $this->group(function($item) use ($field, $i) { - - $value = $this->extractValue($item, $field); - - // ignore upper/lowercase for group names - return ($i == true) ? str::lower($value) : $value; - - }); - - } - - public function set($key, $value) { - if(is_array($key)) { - $this->data = array_merge($this->data, $key); - return $this; - } - $this->data[$key] = $value; - return $this; - } - - public function __set($key, $value) { - $this->set($key, $value); - } - - public function get($key, $default = null) { - if(isset($this->data[$key])) { - return $this->data[$key]; - } else { - $lowerkeys = array_change_key_case($this->data, CASE_LOWER); - if(isset($lowerkeys[strtolower($key)])) { - return $lowerkeys[$key]; - } else { - return $default; - } - } - } - - public function __get($key) { - return $this->get($key); - } - - public function __call($key, $arguments) { - return $this->get($key); - } - - /** - * Makes it possible to echo the entire object - * - * @return string - */ - public function __toString() { - return implode('
', array_map(function($item) { - return (string)$item; - }, $this->data)); - } - -} - - -/** - * Add all available collection filters - * Those can be extended by creating your own: - * collection::$filters['your operator'] = function($collection, $field, $value, $split = false) { - * // your filter code - * }; - */ - -// take all matching elements -collection::$filters['=='] = function($collection, $field, $value, $split = false) { - - foreach($collection->data as $key => $item) { - - if($split) { - $values = str::split((string)collection::extractValue($item, $field), $split); - if(!in_array($value, $values)) unset($collection->$key); - } else if(collection::extractValue($item, $field) != $value) { - unset($collection->$key); - } - - } - - return $collection; - -}; - -// take all elements that won't match -collection::$filters['!='] = function($collection, $field, $value, $split = false) { - - foreach($collection->data as $key => $item) { - if($split) { - $values = str::split((string)collection::extractValue($item, $field), $split); - if(in_array($value, $values)) unset($collection->$key); - } else if(collection::extractValue($item, $field) == $value) { - unset($collection->$key); - } - } - - return $collection; - -}; - -// take all elements that partly match -collection::$filters['*='] = function($collection, $field, $value, $split = false) { - - foreach($collection->data as $key => $item) { - if($split) { - $values = str::split((string)collection::extractValue($item, $field), $split); - foreach($values as $val) { - if(strpos($val, $value) === false) { - unset($collection->$key); - break; - } - } - } else if(strpos(collection::extractValue($item, $field), $value) === false) { - unset($collection->$key); - } - } - - return $collection; - -}; - -// greater than -collection::$filters['>'] = function($collection, $field, $value) { - - foreach($collection->data as $key => $item) { - if(collection::extractValue($item, $field) > $value) continue; - unset($collection->$key); - } - - return $collection; - -}; - -// greater and equals -collection::$filters['>='] = function($collection, $field, $value) { - - foreach($collection->data as $key => $item) { - if(collection::extractValue($item, $field) >= $value) continue; - unset($collection->$key); - } - - return $collection; - -}; - -// less than -collection::$filters['<'] = function($collection, $field, $value) { - - foreach($collection->data as $key => $item) { - if(collection::extractValue($item, $field) < $value) continue; - unset($collection->$key); - } - - return $collection; - -}; - -// less and equals -collection::$filters['<='] = function($collection, $field, $value) { - - foreach($collection->data as $key => $item) { - if(collection::extractValue($item, $field) <= $value) continue; - unset($collection->$key); - } - - return $collection; - -}; diff --git a/kirby/toolkit/lib/cookie.php b/kirby/toolkit/lib/cookie.php deleted file mode 100644 index f3b685a..0000000 --- a/kirby/toolkit/lib/cookie.php +++ /dev/null @@ -1,168 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Cookie { - - // configuration - public static $salt = 'KirbyToolkitCookieSalt'; - - /** - * Set a new cookie - * - * - * - * cookie::set('mycookie', 'hello', 60); - * // expires in 1 hour - * - * - * - * @param string $key The name of the cookie - * @param string $value The cookie content - * @param int $lifetime The number of minutes until the cookie expires - * @param string $path The path on the server to set the cookie for - * @param string $domain the domain - * @param boolean $secure only sets the cookie over https - * @param boolean $httpOnly avoids the cookie to be accessed via javascript - * @return boolean true: the cookie has been created, false: cookie creation failed - */ - public static function set($key, $value, $lifetime = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true) { - - // convert array values to json - if(is_array($value)) $value = a::json($value); - - // hash the value - $value = static::hash($value) . '+' . $value; - - // store that thing in the cookie global - $_COOKIE[$key] = $value; - - // store the cookie - return setcookie($key, $value, static::lifetime($lifetime), $path, $domain, $secure, $httpOnly); - - } - - /** - * Calculates the lifetime for a cookie - * - * @return int - */ - public static function lifetime($minutes) { - return $minutes > 0 ? (time() + ($minutes * 60)) : 0; - } - - /** - * Stores a cookie forever - * - * - * - * cookie::forever('mycookie', 'hello'); - * // never expires - * - * - * - * @param string $key The name of the cookie - * @param string $value The cookie content - * @param string $path The path on the server to set the cookie for - * @param string $domain the domain - * @param boolean $secure only sets the cookie over https - * @return boolean true: the cookie has been created, false: cookie creation failed - */ - public static function forever($key, $value, $path = '/', $domain = null, $secure = false) { - return static::set($key, $value, 2628000, $path, $domain, $secure); - } - - /** - * Get a cookie value - * - * - * - * cookie::get('mycookie', 'peter'); - * // sample output: 'hello' or if the cookie is not set 'peter' - * - * - * - * @param string $key The name of the cookie - * @param string $default The default value, which should be returned if the cookie has not been found - * @return mixed The found value - */ - public static function get($key = null, $default = null) { - if(is_null($key)) return $_COOKIE; - $value = isset($_COOKIE[$key]) ? $_COOKIE[$key] : null; - return empty($value) ? $default : static::parse($value); - } - - /** - * Checks if a cookie exists - * - * @return boolean - */ - public static function exists($key) { - return !is_null(static::get($key)); - } - - /** - * Creates a hash for the cookie value - * salted with the secret cookie salt string from the defaults - * - * @param string $value - * @return string - */ - protected static function hash($value) { - return sha1($value . static::$salt); - } - - /** - * Parses the hashed value from a cookie - * and tries to extract the value - * - * @param string $string - * @return mixed - */ - protected static function parse($string) { - - // extract hash and value - $parts = str::split($string, '+'); - $hash = a::first($parts); - $value = a::last($parts); - - // if the hash or the value is missing at all return null - if(empty($hash) || empty($value)) return null; - - // compare the extracted hash with the hashed value - if($hash !== static::hash($value)) return null; - - return $value; - - } - - /** - * Remove a cookie - * - * - * - * cookie::remove('mycookie'); - * // mycookie is now gone - * - * - * - * @param string $key The name of the cookie - * @return mixed true: the cookie has been removed, false: the cookie could not be removed - */ - public static function remove($key) { - if(isset($_COOKIE[$key])) { - unset($_COOKIE[$key]); - return setcookie($key, '', time() - 3600, '/'); - } - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/crypt.php b/kirby/toolkit/lib/crypt.php deleted file mode 100644 index 9399f7f..0000000 --- a/kirby/toolkit/lib/crypt.php +++ /dev/null @@ -1,86 +0,0 @@ -, Arno Richter - * @link http://getkirby.com - * @copyright Bastian Allgeier, Arno Richter - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Crypt { - - // encryption salt - should be changed - public static $salt = '-'; - - // all available encryption modes - public static $encryption = array( - 'rijndael-128', - 'rijndael-256', - 'blowfish', - 'twofish', - 'des' - ); - - /** - * Encodes a string - * - * @param string $text - * @param string $key An optional encryption key - * @param string $mode Check out the $encryption array for available modes - * @return string - */ - public static function encode($text, $key = null, $mode = 'blowfish') { - - // check for mcrypt support - if(!function_exists('mcrypt_get_iv_size')) { - throw new Exception('The mcrypt extension is missing'); - } - - // all modes are lowercase so we try to avoid errors here - $mode = strtolower($mode); - - // check for a valid encryption mode - if(!in_array($mode, static::$encryption)) throw new Exception('Invalid encryption mode: ' . $mode); - - $size = mcrypt_get_iv_size($mode, MCRYPT_MODE_ECB); - $iv = mcrypt_create_iv($size, MCRYPT_RAND); - $result = mcrypt_encrypt($mode, static::$salt . $key, $text, MCRYPT_MODE_ECB, $iv); - - return trim($result); - - } - - /** - * Decodes a string - * - * @param string $text - * @param string $key An optional encryption key - * @param string $mode Check out the $encryption array for available modes - * @return string - */ - public static function decode($text, $key = null, $mode = 'blowfish') { - - // check for mcrypt support - if(!function_exists('mcrypt_get_iv_size')) { - throw new Exception('The mcrypt extension is missing'); - } - - // all modes are lowercase so we try to avoid errors here - $mode = strtolower($mode); - - // check for a valid encryption mode - if(!in_array($mode, static::$encryption)) throw new Exception('Invalid encryption mode: ' . $mode); - - $size = mcrypt_get_iv_size($mode, MCRYPT_MODE_ECB); - $iv = mcrypt_create_iv($size, MCRYPT_RAND); - $result = mcrypt_decrypt($mode, static::$salt . $key, $text, MCRYPT_MODE_ECB, $iv); - - return trim($result); - - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/data.php b/kirby/toolkit/lib/data.php deleted file mode 100644 index 4cab0f0..0000000 --- a/kirby/toolkit/lib/data.php +++ /dev/null @@ -1,175 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Data { - - const ERROR_INVALID_ADAPTER = 0; - - public static $adapters = array(); - - public static function adapter($type) { - - if(isset(static::$adapters[$type])) return static::$adapters[$type]; - - foreach(static::$adapters as $adapter) { - if(is_array($adapter['extension']) && in_array($type, $adapter['extension'])) { - return $adapter; - } else if($adapter['extension'] == $type) { - return $adapter; - } - } - - throw new Error('Invalid adapter type', static::ERROR_INVALID_ADAPTER); - - } - - public static function encode($data, $type) { - $adapter = static::adapter($type); - return call_user_func($adapter['encode'], $data); - } - - public static function decode($data, $type) { - $adapter = static::adapter($type); - return call_user_func($adapter['decode'], $data); - } - - public static function read($file, $type = null) { - - // type autodetection - if(is_null($type)) $type = f::extension($file); - - // get the adapter - $adapter = static::adapter($type); - - if(isset($adapter['read'])) { - return call($adapter['read'], $file); - } else { - return data::decode(f::read($file), $type); - } - - - } - - public static function write($file, $data, $type = null) { - // type autodetection - if(is_null($type)) $type = f::extension($file); - return f::write($file, data::encode($data, $type)); - } - -} - - -/** - * Json adapter - */ -data::$adapters['json'] = array( - 'extension' => 'json', - 'encode' => function($data) { - return json_encode($data); - }, - 'decode' => function($string) { - return json_decode($string, true); - } -); - - -/** - * Kirby data adapter - */ -data::$adapters['kd'] = array( - 'extension' => array('md', 'txt'), - 'encode' => function($data) { - - $result = array(); - foreach($data AS $key => $value) { - $key = str::ucfirst(str::slug($key)); - - if(empty($key) || is_null($value)) continue; - - // avoid problems with arrays - if(is_array($value)) { - $value = ''; - } - - // escape accidental dividers within a field - $value = preg_replace('!(\n|^)----(.*?\R*)!', "$1\\----$2", $value); - - // multi-line content - if(preg_match('!\R!', $value, $matches)) { - $result[$key] = $key . ": \n\n" . trim($value); - // single-line content - } else { - $result[$key] = $key . ': ' . trim($value); - } - - } - return implode("\n\n----\n\n", $result); - - }, - 'decode' => function($string) { - - // remove BOM - $string = str_replace(BOM, '', $string); - // explode all fields by the line separator - $fields = preg_split('!\n----\s*\n*!', $string); - // start the data array - $data = array(); - - // loop through all fields and add them to the content - foreach($fields as $field) { - $pos = strpos($field, ':'); - $key = str_replace(array('-', ' '), '_', strtolower(trim(substr($field, 0, $pos)))); - - // Don't add fields with empty keys - if(empty($key)) continue; - $data[$key] = trim(substr($field, $pos+1)); - - } - - return $data; - - } -); - - -/** - * PHP serializer adapter - */ -data::$adapters['php'] = array( - 'extension' => array('php'), - 'encode' => function($array) { - return ''; - }, - 'decode' => function() { - throw new Error('Decoding PHP strings is not supported'); - }, - 'read' => function($file) { - $array = require $file; - return $array; - } -); - - -/** - * YAML adapter - */ -data::$adapters['yaml'] = array( - 'extension' => array('yaml', 'yml'), - 'encode' => function($data) { - return yaml::encode($data); - }, - 'decode' => function($string) { - return yaml::decode($string); - } -); \ No newline at end of file diff --git a/kirby/toolkit/lib/database.php b/kirby/toolkit/lib/database.php deleted file mode 100644 index 2570b1e..0000000 --- a/kirby/toolkit/lib/database.php +++ /dev/null @@ -1,496 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Database { - - public static $connectors = array(); - - // a global array of started connections - public static $connections = array(); - - // the established connection - protected $connection; - - // dsn - protected $dsn; - - // the database type (mysql, sqlite) - protected $type; - - // the connection id - protected $id; - - // the optional prefix for table names - protected $prefix; - - // the PDO query statement - protected $statement; - - // whitelists for tables and their columns - protected $tableWhitelist; - protected $columnWhitelist = array(); - - // the number of affected rows for the last query - protected $affected; - - // the last insert id - protected $lastId; - - // the last query - protected $lastQuery; - - // the last result set - protected $lastResult; - - // the last error - protected $lastError; - - // set to true to throw exceptions on failed queries - protected $fail = false; - - // an array with all queries which are being made - protected $trace = array(); - - /** - * Constructor - */ - public function __construct($params = null) { - $this->connect($params); - } - - /** - * Returns one of the started instance - * - * @param string $id - * @return object - */ - public static function instance($id = null) { - return (is_null($id)) ? a::last(static::$connections) : a::get(static::$connections, $id); - } - - /** - * Returns all started instances - * - * @return array - */ - public static function instances() { - return static::$connections; - } - - /** - * Connects to a database - * - * @param mixed $params This can either be a config key or an array of parameters for the connection - * @return object - */ - public function connect($params = null) { - - $defaults = array( - 'database' => null, - 'type' => 'mysql', - 'prefix' => null, - 'user' => null, - 'password' => null, - 'id' => uniqid() - ); - - $options = array_merge($defaults, $params); - - // store the database information - $this->database = $options['database']; - $this->type = $options['type']; - $this->prefix = $options['prefix']; - $this->id = $options['id']; - - if(!isset(static::$connectors[$this->type])) { - throw new Exception('Invalid database connector: ' . $this->type); - } - - // fetch the dsn and store it - $this->dsn = call_user_func(static::$connectors[$this->type], $options); - - // try to connect - $this->connection = new PDO($this->dsn, $options['user'], $options['password']); - $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); - - // store the connection - static::$connections[$this->id] = $this; - - // return the connection - return $this->connection; - - } - - /** - * Returns the currently active connection - * - * @return object - */ - public function connection() { - return $this->connection; - } - - /** - * Sets the exception mode for the next query - * - * @param boolean $fail - */ - public function fail($fail = true) { - $this->fail = $fail; - return $this; - } - - /** - * Returns the used database type - * - * @return string - */ - public function type() { - return $this->type; - } - - /** - * Returns the used table name prefix - * - * @return string - */ - public function prefix() { - return $this->prefix; - } - - /** - * Escapes a value to be used for a safe query - * NOTE: Prepared statements using bound parameters are more secure and solid - * - * @param string $value - * @return string - */ - public function escape($value) { - return substr($this->connection()->quote($value), 1, -1); - } - - /** - * Adds a value to the db trace and also returns the entire trace if nothing is specified - * - * @param array $data - * @return array - */ - public function trace($data = null) { - if(is_null($data)) return $this->trace; - $this->trace[] = $data; - } - - /** - * Returns the number of affected rows for the last query - * - * @return int - */ - public function affected() { - return $this->affected; - } - - /** - * Returns the last id if available - * - * @return int - */ - public function lastId() { - return $this->lastId; - } - - /** - * Returns the last query - * - * @return string - */ - public function lastQuery() { - return $this->lastQuery; - } - - /** - * Returns the last set of results - * - * @return mixed - */ - public function lastResult() { - return $this->lastResult; - } - - /** - * Returns the last db error (exception object) - * - * @return object - */ - public function lastError() { - return $this->lastError; - } - - /** - * Private method to execute database queries. - * This is used by the query() and execute() methods - * - * @param string $query - * @param array $bindings - * @return mixed - */ - protected function hit($query, $bindings = array()) { - - // try to prepare and execute the sql - try { - - $this->statement = $this->connection->prepare($query); - $this->statement->execute($bindings); - - $this->affected = $this->statement->rowCount(); - $this->lastId = $this->connection->lastInsertId(); - $this->lastError = null; - - // store the final sql to add it to the trace later - $this->lastQuery = $this->statement->queryString; - - } catch(\Exception $e) { - - // store the error - $this->affected = 0; - $this->lastError = $e; - $this->lastId = null; - $this->lastQuery = $query; - - // only throw the extension if failing is allowed - if($this->fail) throw $e; - - } - - // add a new entry to the singleton trace array - $this->trace(array( - 'query' => $this->lastQuery, - 'bindings' => $bindings, - 'error' => $this->lastError - )); - - // reset some stuff - $this->fail = false; - - // return true or false on success or failure - return is_null($this->lastError); - - } - - /** - * Exectues a sql query, which is expected to return a set of results - * - * @param string $query - * @param array $bindings - * @param array $params - * @return mixed - */ - public function query($query, $bindings = array(), $params = array()) { - - $defaults = array( - 'flag' => null, - 'method' => 'fetchAll', - 'fetch' => 'Obj', - 'iterator' => 'Collection', - ); - - $options = array_merge($defaults, $params); - - if(!$this->hit($query, $bindings)) return false; - - // define the default flag for the fetch method - $flags = $options['fetch'] == 'array' ? PDO::FETCH_ASSOC : PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE; - - // add optional flags - if(!empty($options['flag'])) $flags |= $options['flag']; - - // set the fetch mode - if($options['fetch'] == 'array') { - $this->statement->setFetchMode($flags); - } else { - $this->statement->setFetchMode($flags, $options['fetch']); - } - - // fetch that stuff - $results = $this->statement->{$options['method']}(); - - if($options['iterator'] == 'array') return $this->lastResult = $results; - return $this->lastResult = new $options['iterator']($results); - - } - - /** - * Executes a sql query, which is expected to not return a set of results - * - * @param string $query - * @param array $bindings - * @return boolean - */ - public function execute($query, $bindings = array()) { - return $this->lastResult = $this->hit($query, $bindings); - } - - /** - * Sets the current table, which should be queried - * - * @param string $table - * @return object Returns a Query object, which can be used to build a full query for that table - */ - public function table($table) { - return new Database\Query($this, $this->prefix() . $table); - } - - /** - * Checks if a table exists in the current database - * - * @param string $table - * @return boolean - */ - public function validateTable($table) { - if(!$this->tableWhitelist) { - // Get the table whitelist from the database - $sql = new SQL($this); - $query = $sql->tableList($this->database); - $results = $this->query($query, $sql->bindings($query)); - - if($results) { - $this->tableWhitelist = $results->pluck('name'); - } else { - return false; - } - } - - return in_array($table, $this->tableWhitelist); - } - - /** - * Checks if a column exists in a specified table - * - * @param string $table - * @param string $column - * @return boolean - */ - public function validateColumn($table, $column) { - if(!isset($this->columnWhitelist[$table])) { - if(!$this->validateTable($table)) { - $this->columnWhitelist[$table] = array(); - return false; - } - - // Get the column whitelist from the database - $sql = new SQL($this); - $query = $sql->columnList($this->database, $table); - $results = $this->query($query, $sql->bindings($query)); - - if($results) { - $this->columnWhitelist[$table] = $results->pluck('name'); - } else { - return false; - } - } - - return in_array($column, $this->columnWhitelist[$table]); - } - - /** - * Creates a new table - * - * @param string $table - * @param array $columns - * @return boolean - */ - public function createTable($table, $columns = array()) { - $sql = new SQL($this); - $query = $sql->createTable($table, $columns); - $queries = str::split($query, ';'); - - foreach($queries as $query) { - $query = trim($query); - - if(!$this->execute($query, $sql->bindings($query))) return false; - } - - return true; - - } - - /** - * Drops a table - * - * @param string $table - * @return boolean - */ - public function dropTable($table) { - $sql = new SQL($this); - $query = $sql->dropTable($table); - return $this->execute($query, $sql->bindings($query)); - } - - /** - * Magic way to start queries for tables by - * using a method named like the table. - * I.e. $db->users()->all() - */ - public function __call($method, $arguments = null) { - return $this->table($method); - } - -} - - -/** - * MySQL database connector - */ -database::$connectors['mysql'] = function($params) { - - if(!isset($params['host']) && !isset($params['socket'])) { - throw new Error('The mysql connection requires either a "host" or a "socket" parameter'); - } - - if(!isset($params['database'])) { - throw new Error('The mysql connection requires a "database" parameter'); - } - - $parts = array(); - - if(!empty($params['host'])) { - $parts[] = 'host=' . $params['host']; - } - - if(!empty($params['port'])) { - $parts[] = 'port=' . $params['port']; - } - - if(!empty($params['socket'])) { - $parts[] = 'unix_socket=' . $params['socket']; - } - - if(!empty($params['database'])) { - $parts[] = 'dbname=' . $params['database']; - } - - $parts[] = 'charset=' . a::get($params, 'charset', 'utf8'); - - return 'mysql:' . implode(';', $parts); - -}; - - -/** - * SQLite database connector - */ -database::$connectors['sqlite'] = function($params) { - if(!isset($params['database'])) throw new Error('The sqlite connection requires a "database" parameter'); - return 'sqlite:' . $params['database']; -}; diff --git a/kirby/toolkit/lib/database/query.php b/kirby/toolkit/lib/database/query.php deleted file mode 100644 index 8e6d68d..0000000 --- a/kirby/toolkit/lib/database/query.php +++ /dev/null @@ -1,923 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Query { - - const ERROR_INVALID_QUERY_METHOD = 0; - - protected $database = null; - - // The object which should be fetched for each row - protected $fetch = 'Obj'; - - // The iterator class, which should be used for result sets - protected $iterator = 'Collection'; - - // An array of bindings for the final query - protected $bindings = array(); - - // The table name - protected $table; - - // The name of the primary key column - protected $primaryKeyName = 'id'; - - // An array with additional join parameters - protected $join; - - // A list of columns, which should be selected - protected $select; - - // Boolean for distinct select clauses - protected $distinct; - - // Boolean for if exceptions should be thrown on failing queries - protected $fail = false; - - // A list of values for update and insert clauses - protected $values; - - // WHERE clause - protected $where; - - // GROUP BY clause - protected $group; - - // HAVING clause - protected $having; - - // ORDER BY clause - protected $order; - - // The offset, which should be applied to the select query - protected $offset = 0; - - // The limit, which should be applied to the select query - protected $limit; - - // Boolean to enable query debugging - protected $debug = false; - - /** - * Constructor - * - * @param Database $database Database object - * @param string $table Optional name of the table, which should be queried - */ - public function __construct($database, $table) { - $this->database = $database; - - $this->table($table); - if(!$this->table) throw new Error('Invalid table ' . $table); - } - - /** - * Reset the query class after each db hit - */ - protected function reset() { - $this->join = null; - $this->select = null; - $this->distinct = null; - $this->fail = false; - $this->values = null; - $this->where = null; - $this->group = null; - $this->having = null; - $this->order = null; - $this->offset = null; - $this->limit = null; - $this->debug = null; - } - - /** - * Enables query debugging. - * If enabled, the query will return an array with all important info about - * the query instead of actually executing the query and returning results - * - * @param boolean $debug - * @return object - */ - public function debug($debug = true) { - $this->debug = $debug; - return $this; - } - - /** - * Enables distinct select clauses. - * - * @param boolean $distinct - * @return object - */ - public function distinct($distinct = true) { - $this->distinct = $distinct; - return $this; - } - - /** - * Enables failing queries. - * If enabled queries will no longer fail silently but throw an exception - * - * @param boolean $fail - * @return object - */ - public function fail($fail = true) { - $this->fail = $fail; - return $this; - } - - /** - * Sets the object class, which should be fetched - * Set this to array to get a simple array instead of an object - * - * @param string $fetch - * @return object - */ - public function fetch($fetch) { - if(!is_null($fetch)) $this->fetch = $fetch; - return $this; - } - - /** - * Sets the iterator class, which should be used for multiple results - * Set this to array to get a simple array instead of an iterator object - * - * @param string $iterator - * @return object - */ - public function iterator($iterator) { - if(!is_null($iterator)) $this->iterator = $iterator; - return $this; - } - - /** - * Sets the name of the table, which should be queried - * - * @param string $table - * @return object - */ - public function table($table) { - if(!is_null($table) && $this->database->validateTable($table)) $this->table = $table; - return $this; - } - - /** - * Sets the name of the primary key column - * - * @param string $primaryKeyName - * @return object - */ - public function primaryKeyName($primaryKeyName) { - $this->primaryKeyName = $primaryKeyName; - return $this; - } - - /** - * Sets the columns, which should be selected from the table - * By default all columns will be selected - * - * @param mixed $select Pass either a string of columns or an array - * @return object - */ - public function select($select) { - $this->select = $select; - return $this; - } - - /** - * Adds a new join clause to the query - * - * @param string $table Name of the table, which should be joined - * @param string $on The on clause for this join - * @param string $type The join type. Uses an inner join by default - * @return object - */ - public function join($table, $on, $type = '') { - - $join = array( - 'table' => $table, - 'on' => $on, - 'type' => $type - ); - - $this->join[] = $join; - return $this; - - } - - /** - * Shortcut for creating a left join clause - * - * @param string $table Name of the table, which should be joined - * @param string $on The on clause for this join - * @return object - */ - public function leftJoin($table, $on) { - return $this->join($table, $on, 'left'); - } - - /** - * Shortcut for creating a right join clause - * - * @param string $table Name of the table, which should be joined - * @param string $on The on clause for this join - * @return object - */ - public function rightJoin($table, $on) { - return $this->join($table, $on, 'right'); - } - - /** - * Shortcut for creating an inner join clause - * - * @param string $table Name of the table, which should be joined - * @param string $on The on clause for this join - * @return object - */ - public function innerJoin($table, $on) { - return $this->join($table, $on, 'inner'); - } - - /** - * Sets the values which should be used for the update or insert clause - * - * @param mixed $values Can either be a string or an array of values - * @return object - */ - public function values($values = array()) { - if(!is_null($values)) $this->values = $values; - return $this; - } - - /** - * Attaches additional bindings to the query. - * Also can be used as getter for all attached bindings by not passing an argument. - * - * @param mixed $bindings Array of bindings or null to use this method as getter - * @return mixed - */ - public function bindings($bindings = null) { - - if(is_array($bindings)) { - $this->bindings = array_merge($this->bindings, $bindings); - return $this; - } - - return $this->bindings; - - } - - /** - * Attaches an additional where clause - * - * All available ways to add where clauses - * - * ->where('username like "myuser"'); (args: 1) - * ->where(array('username' => 'myuser')); (args: 1) - * ->where(function($where) { $where->where('id', '=', 1) }) (args: 1) - * ->where('username like ?', 'myuser') (args: 2) - * ->where('username', 'like', 'myuser'); (args: 3) - * - * @param list - * @return object - */ - public function where() { - $this->where = $this->filterQuery(func_get_args(), $this->where); - return $this; - } - - /** - * Shortcut to attach a where clause with an OR operator. - * Check out the where() method docs for additional info. - * - * @param list - * @return object - */ - public function orWhere() { - - $args = func_get_args(); - $mode = a::last($args); - - // if there's a where clause mode attribute attached… - if(in_array($mode, array('AND', 'OR'))) { - // remove that from the list of arguments - array_pop($args); - } - - // make sure to always attach the OR mode indicator - $args[] = 'OR'; - - call_user_func_array(array($this, 'where'), $args); - return $this; - } - - /** - * Shortcut to attach a where clause with an AND operator. - * Check out the where() method docs for additional info. - * - * @param list - * @return object - */ - public function andWhere() { - - $args = func_get_args(); - $mode = a::last($args); - - // if there's a where clause mode attribute attached… - if(in_array($mode, array('AND', 'OR'))) { - // remove that from the list of arguments - array_pop($args); - } - - // make sure to always attach the AND mode indicator - $args[] = 'AND'; - - call_user_func_array(array($this, 'where'), func_get_args()); - return $this; - } - - /** - * Attaches a group by clause - * - * @param string $group - * @return object - */ - public function group($group) { - $this->group = $group; - return $this; - } - - /** - * Attaches an additional having clause - * - * All available ways to add having clauses - * - * ->having('username like "myuser"'); (args: 1) - * ->having(array('username' => 'myuser')); (args: 1) - * ->having(function($having) { $having->having('id', '=', 1) }) (args: 1) - * ->having('username like ?', 'myuser') (args: 2) - * ->having('username', 'like', 'myuser'); (args: 3) - * - * @param list - * @return object - */ - public function having() { - $this->having = $this->filterQuery(func_get_args(), $this->having); - return $this; - } - - /** - * Attaches an order clause - * - * @param string $order - * @return object - */ - public function order($order) { - $this->order = $order; - return $this; - } - - /** - * Sets the offset for select clauses - * - * @param int $offset - * @return object - */ - public function offset($offset) { - $this->offset = $offset; - return $this; - } - - /** - * Sets the limit for select clauses - * - * @param int $limit - * @return object - */ - public function limit($limit) { - $this->limit = $limit; - return $this; - } - - /** - * Builds the different types of SQL queries - * This uses the SQL class to build stuff. - * - * @param string $type (select, update, insert) - * @return string The final query - */ - public function build($type) { - - $sql = new SQL($this->database, $this); - - switch($type) { - case 'select': - - return $sql->select(array( - 'table' => $this->table, - 'columns' => $this->select, - 'join' => $this->join, - 'distinct' => $this->distinct, - 'where' => $this->where, - 'group' => $this->group, - 'having' => $this->having, - 'order' => $this->order, - 'offset' => $this->offset, - 'limit' => $this->limit - )); - - case 'update': - - return $sql->update(array( - 'table' => $this->table, - 'where' => $this->where, - 'values' => $this->values, - )); - - case 'insert': - - return $sql->insert(array( - 'table' => $this->table, - 'values' => $this->values, - )); - - case 'delete': - - return $sql->delete(array( - 'table' => $this->table, - 'where' => $this->where, - )); - - } - - } - - /** - * Builds a count query - * - * @return object - */ - public function count() { - return $this->aggregate('COUNT'); - } - - /** - * Builds a max query - * - * @param string $column - * @return object - */ - public function max($column) { - return $this->aggregate('MAX', $column); - } - - /** - * Builds a min query - * - * @param string $column - * @return object - */ - public function min($column) { - return $this->aggregate('MIN', $column); - } - - /** - * Builds a sum query - * - * @param string $column - * @return object - */ - public function sum($column) { - return $this->aggregate('SUM', $column); - } - - /** - * Builds an average query - * - * @param string $column - * @return object - */ - public function avg($column) { - return $this->aggregate('AVG', $column); - } - - /** - * Builds an aggregation query. - * This is used by all the aggregation methods above - * - * @param string $method - * @param string $column - * @param string $default An optional default value, which should be returned if the query fails - * @return object - */ - public function aggregate($method, $column = '*', $default = 0) { - - // reset the sorting to avoid counting issues - $this->order = null; - - // validate column - if($column !== '*') { - $sql = new SQL($this->database, $this); - list($table, $columnPart) = $sql->splitIdentifier($this->table, $column); - if(!$this->database->validateColumn($table, $columnPart)) { - throw new Error('Invalid column ' . $column); - } - - $column = $sql->combineIdentifier($table, $columnPart); - } - - $fetch = $this->fetch; - $row = $this->select($method . '(' . $column . ') as aggregation')->fetch('Obj')->first(); - $result = $row ? $row->get('aggregation') : $default; - $this->fetch($fetch); - return $result; - } - - /** - * Used as an internal shortcut for firing a db query - * - * @param string $query - * @param array $params - * @return mixed - */ - protected function query($query, $params = array()) { - - if($this->debug) return array( - 'query' => $query, - 'bindings' => $this->bindings(), - 'options' => $params - ); - - if($this->fail) $this->database->fail(); - - $result = $this->database->query($query, $this->bindings(), $params); - $this->reset(); - return $result; - - } - - /** - * Used as an internal shortcut for executing a db query - * - * @param string $query - * @param array $params - * @return mixed - */ - protected function execute($query, $params = array()) { - - if($this->debug) return array( - 'query' => $query, - 'bindings' => $this->bindings(), - 'options' => $params - ); - - if($this->fail) $this->database->fail(); - - $result = $this->database->execute($query, $this->bindings(), $params); - $this->reset(); - return $result; - - } - - /** - * Selects only one row from a table - * - * @return object - */ - public function first() { - return $this->query($this->offset(0)->limit(1)->build('select'), array( - 'fetch' => $this->fetch, - 'iterator' => 'array', - 'method' => 'fetch', - )); - } - - /** - * Selects only one row from a table - * - * @return object - */ - public function row() { - return $this->first(); - } - - /** - * Selects only one row from a table - * - * @return object - */ - public function one() { - return $this->first(); - } - - /** - * Automatically adds pagination to a query - * - * @param int $page - * @param int $limit The number of rows, which should be returned for each page - * @param array $params Optional params for the pagination object - * @return object Collection iterator with attached pagination object - */ - public function page($page, $limit, $params = array()) { - - $defaults = array( - 'page' => $page - ); - - $options = array_merge($defaults, $params); - - // clone this to create a counter query - $counter = clone $this; - - // count the total number of rows for this query - $count = $counter->count(); - - // pagination - $pagination = new Pagination($count, $limit, $options); - - // apply it to the dataset and retrieve all rows. make sure to use Collection as the iterator to be able to attach the pagination object - $collection = $this->offset($pagination->offset())->limit($pagination->limit())->all(); - - // store all pagination vars in a separate object - if($collection) $collection->paginate($pagination); - - // return the limited collection - return $collection; - - } - - /** - * Returns all matching rows from a table - * - * @return mixed - */ - public function all() { - - return $this->query($this->build('select'), array( - 'fetch' => $this->fetch, - 'iterator' => $this->iterator, - )); - } - - /** - * Returns only values from a single column - * - * @param string $column - * @return mixed - */ - public function column($column) { - - $sql = new SQL($this->database, $this); - $primaryKey = $sql->combineIdentifier($this->table, $this->primaryKeyName); - - $results = $this->query($this->select(array($column))->order($primaryKey . ' ASC')->build('select'), array( - 'iterator' => 'array', - 'fetch' => 'array', - )); - - $results = a::extract($results, $column); - - if($this->iterator == 'array') return $results; - - $iterator = $this->iterator; - return new $iterator($results); - - } - - /** - * Find a single row by column and value - * - * @param string $column - * @param mixed $value - * @return mixed - */ - public function findBy($column, $value) { - return $this->where(array($column => $value))->first(); - } - - /** - * Find a single row by its primary key - * - * @param mixed $id - * @return mixed - */ - public function find($id) { - return $this->findBy($this->primaryKeyName, $id); - } - - /** - * Fires an insert query - * - * @param array $values You can pass values here or set them with ->values() before - * @return mixed Returns the last inserted id on success or false. - */ - public function insert($values = null) { - $query = $this->execute($this->values($values)->build('insert')); - return ($query) ? $this->database->lastId() : false; - } - - /** - * Fires an update query - * - * @param array $values You can pass values here or set them with ->values() before - * @param mixed $where You can pass a where clause here or set it with ->where() before - * @return boolean - */ - public function update($values = null, $where = null) { - return $this->execute($this->values($values)->where($where)->build('update')); - } - - /** - * Fires a delete query - * - * @param mixed $where You can pass a where clause here or set it with ->where() before - * @return boolean - */ - public function delete($where = null) { - return $this->execute($this->where($where)->build('delete')); - } - - /** - * Enables magic queries like findByUsername or findByEmail - * - * @param string $method - * @param array $arguments - * @return mixed - */ - public function __call($method, $arguments) { - - if(preg_match('!^findBy([a-z]+)!i', $method, $match)) { - $column = str::lower($match[1]); - return $this->findBy($column, $arguments[0]); - } else { - throw new Error('Invalid query method: ' . $method, static::ERROR_INVALID_QUERY_METHOD); - } - - } - - /** - * Builder for where and having clauses - * - * @param array $args Arguments, see where() description - * @param string $current Current value (like $this->where) - * @return string - */ - protected function filterQuery($args, $current) { - - $mode = a::last($args); - $result = ''; - - // if there's a where clause mode attribute attached… - if(in_array($mode, array('AND', 'OR'))) { - // remove that from the list of arguments - array_pop($args); - } else { - $mode = 'AND'; - } - - switch(count($args)) { - case 1: - - if(is_null($args[0])) { - - return $current; - - // ->where('username like "myuser"'); - } else if(is_string($args[0])) { - - // simply add the entire string to the where clause - // escaping or using bindings has to be done before calling this method - $result = $args[0]; - - // ->where(array('username' => 'myuser')); - } else if(is_array($args[0])) { - - $sql = new SQL($this->database, $this); - - // simple array mode (AND operator) - $result = $sql->values($this->table, $args[0], ' AND ', true, true); - - } else if(is_callable($args[0])) { - - $query = clone $this; - call_user_func($args[0], $query); - $result = '(' . $query->where . ')'; - - } - - break; - case 2: - - // ->where('username like :username', array('username' => 'myuser')) - if(is_string($args[0]) && is_array($args[1])) { - - // prepared where clause - $result = $args[0]; - - // store the bindings - $this->bindings($args[1]); - - // ->where('username like ?', 'myuser') - } else if(is_string($args[0]) && is_string($args[1])) { - - // prepared where clause - $result = $args[0]; - - // store the bindings - $this->bindings(array($args[1])); - - } - - break; - case 3: - - // ->where('username', 'like', 'myuser'); - if(is_string($args[0]) && is_string($args[1])) { - - // validate column - $sql = new SQL($this->database, $this); - list($table, $column) = $sql->splitIdentifier($this->table, $args[0]); - if(!$this->database->validateColumn($table, $column)) { - throw new Error('Invalid column ' . $args[0]); - } - $key = $sql->combineIdentifier($table, $column); - - // ->where('username', 'in', array('myuser', 'myotheruser')); - if(is_array($args[2])) { - - $predicate = trim(strtoupper($args[1])); - if(!in_array($predicate, array( - 'IN', 'NOT IN' - ))) throw new Error('Invalid predicate ' . $predicate); - - // build a list of bound values - $values = array(); - $bindings = array(); - foreach($args[2] as $value) { - $valueBinding = sql::generateBindingName('value'); - $bindings[$valueBinding] = $value; - $values[] = $valueBinding; - } - - // add that to the where clause in parenthesis - $result = $key . ' ' . $predicate . ' (' . implode(', ', $values) . ')'; - - $this->bindings($bindings); - - // ->where('username', 'like', 'myuser'); - } else { - - $predicate = trim(strtoupper($args[1])); - if(!in_array($predicate, array( - '=', '>=', '>', '<=', '<', '<>', '!=', '<=>', - 'IS', 'IS NOT', - 'BETWEEN', 'NOT BETWEEN', - 'LIKE', 'NOT LIKE', - 'SOUNDS LIKE', - 'REGEXP', 'NOT REGEXP' - ))) throw new Error('Invalid predicate/operator ' . $predicate); - - $valueBinding = sql::generateBindingName('value'); - $bindings[$valueBinding] = $args[2]; - - $result = $key . ' ' . $predicate . ' ' . $valueBinding; - - $this->bindings($bindings); - - } - - } - - break; - - } - - // attach the where clause - if(!empty($current)) { - return $current . ' ' . $mode . ' ' . $result; - } else { - return $result; - } - - } - -} diff --git a/kirby/toolkit/lib/db.php b/kirby/toolkit/lib/db.php deleted file mode 100644 index 32c7f22..0000000 --- a/kirby/toolkit/lib/db.php +++ /dev/null @@ -1,251 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class DB { - - const ERROR_UNKNOWN_METHOD = 0; - - // query shortcuts - public static $queries = array(); - - // The singleton Database object - public static $connection = null; - - /** - * (Re)connect the database - * - * @param mixed $params Pass array() to use the default params from the config - * @return object - */ - public static function connect($params = null) { - if(is_null($params) && !is_null(static::$connection)) return static::$connection; - if(is_null($params)) { - - // try to connect with the default connection settings - $params = array( - 'type' => c::get('db.type', 'mysql'), - 'host' => c::get('db.host', 'localhost'), - 'user' => c::get('db.user', 'root'), - 'password' => c::get('db.password', ''), - 'database' => c::get('db.name', ''), - 'prefix' => c::get('db.prefix', ''), - ); - - } - - return static::$connection = new Database($params); - } - - /** - * Returns the current database connection - * - * @return object - */ - public static function connection() { - return static::$connection; - } - - /** - * Sets the current table, which should be queried - * - * @param string $table - * @return object Returns a DBQuery object, which can be used to build a full query for that table - */ - public static function table($table) { - $connection = db::connect(); - return $connection->table($table); - } - - /** - * Executes a raw sql query which expects a set of results - * - * @param string $query - * @param array $bindings - * @param array $params - * @return mixed - */ - public static function query($query, $bindings = array(), $params = array()) { - $connection = db::connect(); - return $connection->query($query, $bindings, $params); - } - - /** - * Executes a raw sql query which expects no set of results (i.e. update, insert, delete) - * - * @param string $query - * @param array $bindings - * @return mixed - */ - public static function execute($query, $bindings = array()) { - $connection = db::connect(); - return $connection->execute($query, $bindings); - } - - /** - * Magic calls for other static db methods, - * which are redircted to the database class if available - * - * @param string $method - * @param mixed $arguments - * @return mixed - */ - public static function __callStatic($method, $arguments) { - - if(isset(static::$queries[$method])) { - return call(static::$queries[$method], $arguments); - } else if(!is_callable(array(static::$connection, $method))) { - throw new Error('invalid static db method: ' . $method, static::ERROR_UNKNOWN_METHOD); - } else { - return call(array(static::$connection, $method), $arguments); - } - } - -} - -/** - * Shortcut for select clauses - * - * @param string $table The name of the table, which should be queried - * @param mixed $columns Either a string with columns or an array of column names - * @param mixed $where The where clause. Can be a string or an array - * @param mixed $order - * @param int $offset - * @param int $limit - * @return mixed - */ -db::$queries['select'] = function($table, $columns = '*', $where = null, $order = null, $offset = 0, $limit = null) { - return db::table($table)->select($columns)->where($where)->order($order)->offset($offset)->limit($limit)->all(); -}; - -/** - * Shortcut for selecting a single row in a table - * - * @param string $table The name of the table, which should be queried - * @param mixed $columns Either a string with columns or an array of column names - * @param mixed $where The where clause. Can be a string or an array - * @param mixed $order - * @param int $offset - * @param int $limit - * @return mixed - */ -db::$queries['first'] = db::$queries['row'] = db::$queries['one'] = function($table, $columns = '*', $where = null, $order = null) { - return db::table($table)->select($columns)->where($where)->order($order)->first(); -}; - -/** - * Returns only values from a single column - * - * @param string $table The name of the table, which should be queried - * @param mixed $column The name of the column to select from - * @param mixed $where The where clause. Can be a string or an array - * @param mixed $order - * @param int $offset - * @param int $limit - * @return mixed - */ -db::$queries['column'] = function($table, $column, $where = null, $order = null, $offset = 0, $limit = null) { - return db::table($table)->where($where)->order($order)->offset($offset)->limit($limit)->column($column); -}; - -/** - * Shortcut for inserting a new row into a table - * - * @param string $table The name of the table, which should be queried - * @param string $values An array of values, which should be inserted - * @return boolean - */ -db::$queries['insert'] = function($table, $values) { - return db::table($table)->insert($values); -}; - -/** - * Shortcut for updating a row in a table - * - * @param string $table The name of the table, which should be queried - * @param string $values An array of values, which should be inserted - * @param mixed $where An optional where clause - * @return boolean - */ -db::$queries['update'] = function($table, $values, $where = null) { - return db::table($table)->where($where)->update($values); -}; - -/** - * Shortcut for deleting rows in a table - * - * @param string $table The name of the table, which should be queried - * @param mixed $where An optional where clause - * @return boolean - */ -db::$queries['delete'] = function($table, $where = null) { - return db::table($table)->where($where)->delete(); -}; - -/** - * Shortcut for counting rows in a table - * - * @param string $table The name of the table, which should be queried - * @param string $where An optional where clause - * @return int - */ -db::$queries['count'] = function($table, $where = null) { - return db::table($table)->where($where)->count(); -}; - -/** - * Shortcut for calculating the minimum value in a column - * - * @param string $table The name of the table, which should be queried - * @param string $column The name of the column of which the minimum should be calculated - * @param string $where An optional where clause - * @return mixed - */ -db::$queries['min'] = function($table, $column, $where = null) { - return db::table($table)->where($where)->min($column); -}; - -/** - * Shortcut for calculating the maximum value in a column - * - * @param string $table The name of the table, which should be queried - * @param string $column The name of the column of which the maximum should be calculated - * @param string $where An optional where clause - * @return mixed - */ -db::$queries['max'] = function($table, $column, $where = null) { - return db::table($table)->where($where)->max($column); -}; - -/** - * Shortcut for calculating the average value in a column - * - * @param string $table The name of the table, which should be queried - * @param string $column The name of the column of which the average should be calculated - * @param string $where An optional where clause - * @return mixed - */ -db::$queries['avg'] = function($table, $column, $where = null) { - return db::table($table)->where($where)->avg($column); -}; - -/** - * Shortcut for calculating the sum of all values in a column - * - * @param string $table The name of the table, which should be queried - * @param string $column The name of the column of which the sum should be calculated - * @param string $where An optional where clause - * @return mixed - */ -db::$queries['sum'] = function($table, $column, $where = null) { - return db::table($table)->where($where)->sum($column); -}; \ No newline at end of file diff --git a/kirby/toolkit/lib/detect.php b/kirby/toolkit/lib/detect.php deleted file mode 100644 index a436568..0000000 --- a/kirby/toolkit/lib/detect.php +++ /dev/null @@ -1,261 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Detect { - - /** - * Checks if the mb string extension is installed - * - * @return boolean - */ - public static function mbstring() { - return function_exists('mb_split'); - } - - /** - * Checks if the required php version is installed - * - * @param mixed $min - * @return boolean - */ - public static function php($min = '5.3') { - return version_compare(PHP_VERSION, $min, '>='); - } - - /** - * Checks if PHP is running on Apache - * - * @return boolean - */ - public static function apache() { - return apache_get_version() ? true : false; - } - - /** - * Checks if the site is running on Windows - * - * @return boolean - */ - public static function windows() { - return DS == '/' ? false : true; - } - - /** - * Checks if the site is running on IIS - * - * @return boolean - */ - public static function iis() { - return isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'],'IIS') !== false ? true : false; - } - - /** - * Checks if mysql installed with the minimum required version - * - * @param mixed $min - * @return boolean - */ - public static function mysql($min = '5') { - $extensions = get_loaded_extensions(); - if(!in_array('mysql', $extensions)) return false; - $version = preg_replace('#(^\D*)([0-9.]+).*$#', '\2', mysql_get_client_info()); - return version_compare($version, $min, '>='); - } - - /** - * Checks if SQLite 3 is installed - * - * @return boolean - */ - public static function sqlite() { - return in_array('sqlite3', get_loaded_extensions()); - } - - /** - * Checks if safe mode is enabled - * - * @return boolean - */ - public static function safemode() { - return ini_get('safe_mode'); - } - - /** - * Checks if gdlib is installed - * - * @return boolean - */ - public static function gdlib() { - return function_exists('gd_info'); - } - - /** - * Checks if imageick is installed - * - * @return boolean - */ - public static function imagick() { - return class_exists('Imagick'); - } - - /** - * Checks if CURL is installed - * - * @return boolean - */ - public static function curl() { - return in_array('curl', get_loaded_extensions()); - } - - /** - * Check if APC cache is installed - * - * @return boolean - */ - public static function apc() { - return function_exists('apc_add'); - } - - /** - * Check if the Memcache extension is installed - * - * @return boolean - */ - public static function memcache() { - return class_exists('Memcache'); - } - - /** - * Check if the Memcached extension is installed - * - * @return boolean - */ - public static function memcached() { - return class_exists('Memcached'); - } - - /** - * Check if the imap extension is installed - * - * @return boolean - */ - public static function imap() { - return function_exists('imap_body'); - } - - /** - * Check if the mcrypt extension is installed - * - * @return boolean - */ - public static function mcrypt() { - return function_exists('mcrypt_encrypt'); - } - - /** - * Check if the exif extension is installed - * - * @return boolean - */ - public static function exif() { - return function_exists('read_exif_data'); - } - - /** - * Detect if the script is installed in a subfolder - * - * @return string - */ - public static function subfolder() { - return trim(dirname($_SERVER['SCRIPT_NAME']), '/\\'); - } - - /** - * Detects the current path - * - * @return string - */ - public static function path() { - $uri = explode('/', url::path()); - $script = explode('/', trim($_SERVER['SCRIPT_NAME'], '/\\')); - $parts = array_diff_assoc($uri, $script); - if(empty($parts)) return false; - return implode('/', $parts); - } - - /** - * Detect the document root - * - * @return string - */ - public static function documentRoot() { - $local = $_SERVER['SCRIPT_NAME']; - $absolute = $_SERVER['SCRIPT_FILENAME']; - return substr($absolute, 0, strpos($absolute, $local)); - } - - /** - * Converts any ini size value to an integer - * - * @param string $key - * @return int - */ - public static function iniSize($key) { - - $size = ini_get($key); - $size = trim($size); - $last = strtolower($size[strlen($size)-1]); - switch($last) { - case 'g': - $size *= 1024; - case 'm': - $size *= 1024; - case 'k': - $size *= 1024; - } - return $size; - - } - - /** - * Returns the max accepted upload size - * defined in the php.ini - * - * @return int - */ - public static function maxUploadSize() { - return static::iniSize('upload_max_filesize'); - } - - /** - * Returns the max accepted post size - * defined in the php.ini - * - * @return int - */ - public static function maxPostSize() { - return static::iniSize('post_max_size'); - } - - /** - * Dirty browser sniffing for an ios device - * - * @return boolean - */ - public static function ios() { - $ua = visitor::ua(); - return (str::contains($ua, 'iPod') || str::contains($ua, 'iPhone') || str::contains($ua, 'iPad')); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/dimensions.php b/kirby/toolkit/lib/dimensions.php deleted file mode 100644 index 4d52ecf..0000000 --- a/kirby/toolkit/lib/dimensions.php +++ /dev/null @@ -1,316 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Dimensions { - - // the width of the parent object - public $width = 0; - - // the height of the parent object - public $height = 0; - - /** - * Constructor - * - * @param int $width - * @param int $height - */ - public function __construct($width, $height) { - $this->width = $width; - $this->height = $height; - } - - /** - * Returns the width - * - * @return int - */ - public function width() { - return $this->width; - } - - /** - * Returns the height - * - * @return int - */ - public function height() { - return $this->height; - } - - /** - * Calculates and returns the ratio - * - * - * - * $dimensions = new Dimensions(1200, 768); - * echo $dimensions->ratio(); - * // output: 1.5625 - * - * - * - * @return float - */ - public function ratio() { - if($this->width && $this->height) { - return ($this->width / $this->height); - } else { - return 0; - } - } - - /** - * Recalculates the width and height - * to fit into the given box. - * - * - * - * $dimensions = new Dimensions(1200, 768); - * $dimensions->fit(500); - * - * echo $dimensions->width(); - * // output: 500 - * - * echo $dimensions->height(); - * // output: 320 - * - * - * - * @param int $box the max width and/or height - * @param boolean $force If true, the dimensions will be upscaled to fit the box if smaller - * @return object returns this object with recalculated dimensions - */ - public function fit($box, $force = false) { - - if($this->width == 0 || $this->height == 0) { - $this->width = $box; - $this->height = $box; - return $this; - } - - $ratio = $this->ratio(); - - if($this->width > $this->height) { - if($this->width > $box || $force === true) $this->width = $box; - $this->height = round($this->width / $ratio); - } elseif($this->height > $this->width) { - if($this->height > $box || $force === true) $this->height = $box; - $this->width = round($this->height * $ratio); - } elseif($this->width > $box) { - $this->width = $box; - $this->height = $box; - } - - return $this; - - } - - /** - * Recalculates the width and height - * to fit the given width - * - * - * - * $dimensions = new Dimensions(1200, 768); - * $dimensions->fitWidth(500); - * - * echo $dimensions->width(); - * // output: 500 - * - * echo $dimensions->height(); - * // output: 320 - * - * - * - * @param int $fit the max width - * @param boolean $force If true, the dimensions will be upscaled to fit the width if smaller - * @return object returns this object with recalculated dimensions - */ - public function fitWidth($fit, $force = false) { - - if(!$fit) return $this; - - if($this->width <= $fit && !$force) return $this; - - $ratio = $this->ratio(); - - $this->width = $fit; - $this->height = round($fit / $ratio); - - return $this; - - } - - /** - * Recalculates the width and height - * to fit the given height - * - * - * - * $dimensions = new Dimensions(1200, 768); - * $dimensions->fitHeight(500); - * - * echo $dimensions->width(); - * // output: 781 - * - * echo $dimensions->height(); - * // output: 500 - * - * - * - * @param int $fit the max height - * @param boolean $force If true, the dimensions will be upscaled to fit the height if smaller - * @return object returns this object with recalculated dimensions - */ - public function fitHeight($fit, $force = false) { - - if(!$fit) return $this; - - if($this->height <= $fit && !$force) return $this; - - $ratio = $this->ratio(); - - $this->width = round($fit * $ratio); - $this->height = $fit; - - return $this; - - } - - /** - * Recalculates the dimensions by the width and height - * - * @param int $width the max height - * @param int $height the max width - * @return object - */ - public function fitWidthAndHeight($width, $height, $force = false) { - - if($this->width > $this->height) { - - $this->fitWidth($width, $force); - - // do another check for the max height - if($this->height > $height) $this->fitHeight($height); - - } else { - - $this->fitHeight($height, $force); - - // do another check for the max width - if($this->width > $width) $this->fitWidth($width); - - } - - return $this; - - } - - /** - * @param int $width - * @param int $height - * @param boolean $force - * @return Dimensions - */ - public function resize($width, $height, $force = false) { - $this->fitWidthAndHeight($width, $height, $force); - return $this; - } - - /** - * Crops the dimensions by width and height - * - * @param int $width - * @param int $height - * @return object - */ - public function crop($width, $height = null) { - - $this->width = $width; - $this->height = $width; - - if($height) { - $this->height = $height; - } - - return $this; - - } - - /** - * Returns a string representation of the orientation - * - * @return string - */ - public function orientation() { - if(!$this->ratio()) return false; - if($this->portrait()) return 'portrait'; - if($this->landscape()) return 'landscape'; - if($this->square()) return 'square'; - } - - /** - * Checks if the dimensions are portrait - * - * @return boolean - */ - public function portrait() { - return $this->height > $this->width; - } - - /** - * Checks if the dimensions are landscape - * - * @return boolean - */ - public function landscape() { - return $this->width > $this->height; - } - - /** - * Checks if the dimensions are square - * - * @return boolean - */ - public function square() { - return $this->width == $this->height; - } - - /** - * Converts the dimensions object - * to a plain PHP array - * - * @return array - */ - public function toArray() { - return array( - 'width' => $this->width(), - 'height' => $this->height(), - 'ratio' => $this->ratio(), - 'orientation' => $this->orientation(), - ); - } - - /** - * Echos the dimensions as width × height - * - * @return string - */ - public function __toString() { - return $this->width . ' × ' . $this->height; - } - -} diff --git a/kirby/toolkit/lib/dir.php b/kirby/toolkit/lib/dir.php deleted file mode 100644 index 1d97293..0000000 --- a/kirby/toolkit/lib/dir.php +++ /dev/null @@ -1,209 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Dir { - - public static $defaults = array( - 'permissions' => 0755, - 'ignore' => array('.', '..', '.DS_Store', '.gitignore', '.git', '.svn', '.htaccess', 'Thumb.db', '@eaDir') - ); - - /** - * Creates a new directory - * - * - * - * $create = dir::make('/app/test/new-directory'); - * - * if($create) echo 'the directory has been created'; - * - * - * - * @param string $dir The path for the new directory - * @return boolean True: the dir has been created, false: creating failed - */ - public static function make($dir, $recursive = true) { - return is_dir($dir) ? true : @mkdir($dir, static::$defaults['permissions'], $recursive); - } - - /** - * Reads all files from a directory and returns them as an array. - * It skips unwanted invisible stuff. - * - * - * - * $files = dir::read('mydirectory'); - * // returns array('file-1.txt', 'file-2.txt', 'file-3.txt', etc...); - * - * - * - * @param string $dir The path of directory - * @param array $ignore Optional array with filenames, which should be ignored - * @return mixed An array of filenames or false - */ - public static function read($dir, $ignore = array()) { - if(!is_dir($dir)) return array(); - $skip = array_merge(static::$defaults['ignore'], $ignore); - return (array)array_diff(scandir($dir),$skip); - } - - /** - * Moves a directory to a new location - * - * - * - * $move = dir::move('mydirectory', 'mynewdirectory'); - * - * if($move) echo 'the directory has been moved to mynewdirectory'; - * - * - * - * @param string $old The current path of the directory - * @param string $new The desired path where the dir should be moved to - * @return boolean True: the directory has been moved, false: moving failed - */ - public static function move($old, $new) { - if(!is_dir($old)) return false; - return @rename($old, $new); - } - - /** - * Deletes a directory - * - * - * - * $remove = dir::remove('mydirectory'); - * - * if($remove) echo 'the directory has been removed'; - * - * - * - * @param string $dir The path of the directory - * @param boolean $keep If set to true, the directory will flushed but not removed. - * @return boolean True: the directory has been removed, false: removing failed - */ - public static function remove($dir, $keep = false) { - if(!is_dir($dir)) return false; - - // It's easier to handle this with the Folder class - $object = new Folder($dir); - return $object->remove($keep); - } - - /** - * Flushes a directory - * - * @param string $dir The path of the directory - * @return boolean True: the directory has been flushed, false: flushing failed - */ - public static function clean($dir) { - return static::remove($dir, true); - } - - /** - * Gets the size of the directory and all subfolders and files - * - * @param string $dir The path of the directory - * @return mixed - */ - public static function size($dir) { - - if(!file_exists($dir)) return false; - - // It's easier to handle this with the Folder class - $object = new Folder($dir); - return $object->size(); - - } - - /** - * Returns a nicely formatted size of all the contents of the folder - * - * @param string $dir The path of the directory - * @return mixed - */ - public static function niceSize($dir) { - return f::niceSize(static::size($dir)); - } - - /** - * Recursively check when the dir and all - * subfolders have been modified for the last time. - * - * @param string $dir The path of the directory - * @param string $format - * @return int - */ - public static function modified($dir, $format = null, $handler = 'date') { - // It's easier to handle this with the Folder class - $object = new Folder($dir); - return $object->modified($format, $handler); - } - - /** - * Checks if the directory or any subdirectory has been - * modified after the given timestamp - * - * @param string $dir - * @param int $time - * @return boolean - */ - public static function wasModifiedAfter($dir, $time) { - - if(filemtime($dir) > $time) return true; - - $content = dir::read($dir); - - foreach($content as $item) { - $subdir = $dir . DS . $item; - if(filemtime($subdir) > $time) return true; - if(is_dir($subdir) && dir::wasModifiedAfter($subdir, $time)) return true; - } - - return false; - - } - - /** - * Checks if the dir is writable - * - * @param string $dir - * @return boolean - */ - public static function writable($dir) { - return is_writable($dir); - } - - /** - * Checks if the dir is readable - * - * @param string $dir - * @return boolean - */ - public static function readable($dir) { - return is_readable($dir); - } - - /** - * Copy a file, or recursively copy a folder and its contents - * - * @param string $dir Source path - * @param string $to Destination path - */ - public static function copy($dir, $to) { - // It's easier to handle this with the Folder class - $object = new Folder($dir); - return $object->copy($to); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/email.php b/kirby/toolkit/lib/email.php deleted file mode 100644 index b20cdc7..0000000 --- a/kirby/toolkit/lib/email.php +++ /dev/null @@ -1,291 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Email extends Obj { - - const ERROR_INVALID_RECIPIENT = 0; - const ERROR_INVALID_SENDER = 1; - const ERROR_INVALID_REPLY_TO = 2; - const ERROR_INVALID_SUBJECT = 3; - const ERROR_INVALID_BODY = 4; - const ERROR_INVALID_SERVICE = 5; - const ERROR_DISABLED = 6; - - public static $defaults = array( - 'service' => 'mail', - 'options' => array(), - 'to' => null, - 'from' => null, - 'replyTo' => null, - 'subject' => null, - 'body' => null - ); - - public static $services = array(); - public static $disabled = false; - - public $error; - public $service; - public $options; - public $to; - public $from; - public $replyTo; - public $subject; - public $body; - - public function __construct($params = array()) { - $options = a::merge(static::$defaults, $params); - parent::__construct($options); - } - - public function __set($key, $value) { - $this->$key = $value; - } - - /** - * Validates the constructed email - * to make sure it can be sent at all - */ - public function validate() { - if(!v::email($this->extractAddress($this->to))) throw new Error('Invalid recipient', static::ERROR_INVALID_RECIPIENT); - if(!v::email($this->extractAddress($this->from))) throw new Error('Invalid sender', static::ERROR_INVALID_SENDER); - if(!v::email($this->extractAddress($this->replyTo))) throw new Error('Invalid reply address', static::ERROR_INVALID_REPLY_TO); - if(empty($this->subject)) throw new Error('Missing subject', static::ERROR_INVALID_SUBJECT); - if(empty($this->body)) throw new Error('Missing body', static::ERROR_INVALID_BODY); - } - - /** - * Public getter for the error exception - * - * @return Exception - */ - public function error() { - return $this->error; - } - - /** - * Extracts the email address from an address string - * - * @return string - */ - protected function extractAddress($string) { - if(v::email($string)) return $string; - preg_match('/<(.*?)>/i', $string, $array); - return (empty($array[1])) ? $string : $array[1]; - } - - /** - * Sends the constructed email - * - * @param array $params Optional way to set values for the email - * @return boolean - */ - public function send($params = null) { - - try { - - // fail silently if sending emails is disabled - if(static::$disabled) throw new Error('Sending emails is disabled', static::ERROR_DISABLED); - - // overwrite already set values - if(is_array($params) && !empty($params)) { - foreach(a::merge($this->toArray(), $params) as $key => $val) { - $this->set($key, $val); - } - } - - // reset all errors - $this->error = null; - - // default service - if(empty($this->service)) $this->service = 'mail'; - - // if there's no dedicated reply to address, use the from address - if(empty($this->replyTo)) $this->replyTo = $this->from; - - // validate the email - $this->validate(); - - // check if the email service is available - if(!isset(static::$services[$this->service])) { - throw new Error('The email service is not available: ' . $this->service, static::ERROR_INVALID_SERVICE); - } - - // run the service - call(static::$services[$this->service], $this); - - // reset the error - $this->error = null; - return true; - - } catch(Exception $e) { - $this->error = $e; - return false; - } - - } - -} - - -/** - * Default mail driver - */ -email::$services['mail'] = function($email) { - - $headers = array( - 'From: ' . $email->from, - 'Reply-To: ' . $email->replyTo, - 'Return-Path: ' . $email->replyTo, - 'Message-ID: <' . time() . '-' . $email->from . '>', - 'X-Mailer: PHP v' . phpversion(), - 'Content-Type: text/plain; charset=utf-8', - 'Content-Transfer-Encoding: 8bit', - ); - - ini_set('sendmail_from', $email->from); - $send = mail($email->to, str::utf8($email->subject), str::utf8($email->body), implode(PHP_EOL, $headers)); - ini_restore('sendmail_from'); - - if(!$send) { - throw new Error('The email could not be sent'); - } - -}; - -/** - * Amazon mail driver - */ -email::$services['amazon'] = function($email) { - - if(empty($email->options['key'])) throw new Error('Missing Amazon API key'); - if(empty($email->options['secret'])) throw new Error('Missing Amazon API secret'); - - $setup = array( - 'Action' => 'SendEmail', - 'Destination.ToAddresses.member.1' => $email->to, - 'ReplyToAddresses.member.1' => $email->replyTo, - 'ReturnPath' => $email->replyTo, - 'Source' => $email->from, - 'Message.Subject.Data' => $email->subject, - 'Message.Body.Text.Data' => $email->body - ); - - $params = array(); - - foreach($setup as $key => $value) { - $params[] = $key . '=' . str_replace('%7E', '~', rawurlencode($value)); - } - - sort($params, SORT_STRING); - - $host = a::get($email->options, 'host', 'email.us-east-1.amazonaws.com'); - $url = 'https://' . $host . '/'; - $date = gmdate('D, d M Y H:i:s e'); - $signature = base64_encode(hash_hmac('sha256', $date, $email->options['secret'], true)); - $query = implode('&', $params); - $headers = array(); - $auth = 'AWS3-HTTPS AWSAccessKeyId=' . $email->options['key']; - $auth .= ',Algorithm=HmacSHA256,Signature=' . $signature; - - $headers[] = 'Date: ' . $date; - $headers[] = 'Host: ' . $host; - $headers[] = 'X-Amzn-Authorization: '. $auth; - $headers[] = 'Content-Type: application/x-www-form-urlencoded'; - - $email->response = remote::post($url, array( - 'data' => $query, - 'headers' => $headers - )); - - if(!in_array($email->response->code(), array(200, 201, 202, 204))) { - throw new Error('The mail could not be sent!', $email->response->code()); - } - -}; - -/** - * Mailgun mail driver - */ -email::$services['mailgun'] = function($email) { - - if(empty($email->options['key'])) throw new Error('Missing Mailgun API key'); - if(empty($email->options['domain'])) throw new Error('Missing Mailgun API domain'); - - $url = 'https://api.mailgun.net/v2/' . $email->options['domain'] . '/messages'; - $auth = base64_encode('api:' . $email->options['key']); - - $headers = array( - 'Accept: application/json', - 'Authorization: Basic ' . $auth - ); - - $data = array( - 'from' => $email->from, - 'to' => $email->to, - 'subject' => $email->subject, - 'text' => $email->body, - 'h:Reply-To' => $email->replyTo, - ); - - $email->response = remote::post($url, array( - 'data' => $data, - 'headers' => $headers - )); - - if($email->response->code() != 200) { - throw new Error('The mail could not be sent!'); - } - -}; - -/** - * Postmark mail driver - */ -email::$services['postmark'] = function($email) { - - if(empty($email->options['key'])) throw new Error('Invalid Postmark API Key'); - - // reset the api key if we are in test mode - if(a::get($email->options, 'test')) $email->options['key'] = 'POSTMARK_API_TEST'; - - // the url for postmarks api - $url = 'https://api.postmarkapp.com/email'; - - $headers = array( - 'Accept: application/json', - 'Content-Type: application/json', - 'X-Postmark-Server-Token: ' . $email->options['key'] - ); - - $data = array( - 'From' => $email->from, - 'To' => $email->to, - 'ReplyTo' => $email->replyTo, - 'Subject' => $email->subject, - 'TextBody' => $email->body - ); - - // fetch the response - $email->response = remote::post($url, array( - 'data' => json_encode($data), - 'headers' => $headers - )); - - if($email->response->code() != 200) { - throw new Error('The mail could not be sent'); - } - -}; diff --git a/kirby/toolkit/lib/embed.php b/kirby/toolkit/lib/embed.php deleted file mode 100644 index 34a9365..0000000 --- a/kirby/toolkit/lib/embed.php +++ /dev/null @@ -1,124 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Embed { - - /** - * Embeds a youtube video by passing the Youtube url - * - * @param string $url Youtube url i.e. http://www.youtube.com/watch?v=d9NF2edxy-M - * @param array $attr Additional attributes for the iframe - * @return string - */ - public static function youtube($url, $attr = array()) { - - // http://www.youtube.com/embed/d9NF2edxy-M - if(preg_match('!youtube.com\/embed\/([a-z0-9_-]+)!i', $url, $array)) { - $id = $array[1]; - // http://www.youtube.com/watch?feature=player_embedded&v=d9NF2edxy-M#! - } elseif(preg_match('!v=([a-z0-9_-]+)!i', $url, $array)) { - $id = $array[1]; - // http://youtu.be/d9NF2edxy-M - } elseif(preg_match('!youtu.be\/([a-z0-9_-]+)!i', $url, $array)) { - $id = $array[1]; - } - - // no id no result! - if(empty($id)) return false; - - // default options - if(!empty($attr['options'])) { - $options = '?' . http_build_query($attr['options']); - // options should not propagate to the attr list - unset($attr['options']); - } else { - $options = ''; - } - - // default attributes - $attr = array_merge(array( - 'src' => '//youtube.com/embed/' . $id . $options, - 'frameborder' => '0', - 'webkitAllowFullScreen' => 'true', - 'mozAllowFullScreen' => 'true', - 'allowFullScreen' => 'true', - 'width' => '100%', - 'height' => '100%', - ), $attr); - - return html::tag('iframe', '', $attr); - - } - - /** - * Embeds a vimeo video by passing the vimeo url - * - * @param string $url vimeo url i.e. http://vimeo.com/52345557 - * @param array $attr Additional attributes for the iframe - * @return string - */ - public static function vimeo($url, $attr = array()) { - - // get the uid from the url - if(preg_match('!vimeo.com\/([0-9]+)!i', $url, $array)) { - $id = $array[1]; - } else { - $id = null; - } - - // no id no result! - if(empty($id)) return false; - - // default options - if(!empty($attr['options'])) { - $options = '?' . http_build_query($attr['options']); - // options should not propagate to the attr list - unset($attr['options']); - } else { - $options = ''; - } - - // default attributes - $attr = array_merge(array( - 'src' => '//player.vimeo.com/video/' . $id . $options, - 'frameborder' => '0', - 'webkitAllowFullScreen' => 'true', - 'mozAllowFullScreen' => 'true', - 'allowFullScreen' => 'true', - 'width' => '100%', - 'height' => '100%', - ), $attr); - - return html::tag('iframe', '', $attr); - - } - - /** - * Embeds a github gist - * - * @param string $url Gist url: i.e. https://gist.github.com/2924148 - * @param string $file The name of a particular file from the gist, which should displayed only. - * @return string - */ - public static function gist($url, $file = null) { - - // url for the script file - $url = $url . '.js' . r(!is_null($file), '?file=' . $file); - - // load the gist - return html::tag('script', '', array('src' => $url)); - - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/error.php b/kirby/toolkit/lib/error.php deleted file mode 100644 index 6ded65b..0000000 --- a/kirby/toolkit/lib/error.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Error extends Exception { - - public function message() { - return $this->message; - } - - public function code() { - return $this->code; - } - - public function __toString() { - return $this->message; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/errorreporting.php b/kirby/toolkit/lib/errorreporting.php deleted file mode 100644 index 118231e..0000000 --- a/kirby/toolkit/lib/errorreporting.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @link http://getkirby.com - * @copyright Lukas Bestle - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class ErrorReporting { - - /** - * Returns the current raw value - * - * @return int The current value - */ - public static function get() { - return error_reporting(); - } - - /** - * Sets a new raw error reporting value - * - * @param int $level The new level to set - * @return int The new value - */ - public static function set($level) { - if(static::get() !== error_reporting($level)) { - throw new Exception('Internal error: error_reporting() did not return the old value.'); - } - return static::get(); - } - - /** - * Check if the current error reporting includes an error level - * - * @param mixed $level The level to check for - * @param int $current A custom current level - * @return boolean - */ - public static function includes($level, $current = null) { - // also allow strings - if(is_string($level)) { - if(defined($level)) { - $level = constant($level); - } else if(defined('E_' . strtoupper($level))) { - $level = constant('E_' . strtoupper($level)); - } else { - throw new Exception('The level "' . $level . '" does not exist.'); - } - } - - $value = ($current)? $current : static::get(); - return bitmask::includes($level, $value); - } - - /** - * Adds a level to the current error reporting - * - * @param int $level The level to add - * @return boolean - */ - public static function add($level) { - // check if it is already added - if(static::includes($level)) return false; - - $old = static::get(); - $newExpected = bitmask::add($level, $old); - $newActual = static::set($newExpected); - - return $newActual === $newExpected; - } - - /** - * Removes a level from the current error reporting - * - * @param int $level The level to remove - * @return boolean - */ - public static function remove($level) { - // check if it is already removed - if(!static::includes($level)) return false; - - $old = static::get(); - $newExpected = bitmask::remove($level, $old); - $newActual = static::set($newExpected); - - return $newActual === $newExpected; - } -} diff --git a/kirby/toolkit/lib/escape.php b/kirby/toolkit/lib/escape.php deleted file mode 100644 index db748a0..0000000 --- a/kirby/toolkit/lib/escape.php +++ /dev/null @@ -1,266 +0,0 @@ - - * @link https://github.com/ezraverheijen/escape - * @copyright Ezra Verheijen - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Escape { - - /** - * Check if a string needs to be escaped or not - * - * @param string $string - * @return boolean - */ - public static function noNeedToEscape($string) { - return $string === '' || ctype_digit($string); - } - - /** - * Convert a character from UTF-8 to UTF-16BE - * - * @param string $char - * @return string - */ - public static function convertEncoding($char) { - return str::convert($char, 'UTF-16BE', 'UTF-8'); - } - - /** - * Check if a character is undefined in HTML - * - * @param string $char - * @return boolean - */ - public static function charIsUndefined($char) { - $ascii = ord($char); - return ($ascii <= 0x1f && $char != "\t" && $char != "\n" && $char != "\r") - || ($ascii >= 0x7f && $ascii <= 0x9f); - } - - /** - * Escape HTML element content - * - * This can be used to put untrusted data directly into the HTML body somewhere. - * This includes inside normal tags like div, p, b, td, etc. - * - * Escapes &, <, >, ", and ' with HTML entity encoding to prevent switching - * into any execution context, such as script, style, or event handlers. - * - * ...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE... - *
...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...
- * - * @uses ENT_SUBSTITUE if available (PHP >= 5.4) - * - * @param string $string - * @return string - */ - public static function html($string) { - $flags = ENT_QUOTES; - if(defined('ENT_SUBSTITUTE')) { - $flags |= ENT_SUBSTITUTE; - } - return htmlspecialchars($string, $flags, 'UTF-8'); - } - - /** - * Escape XML element content - * - * Removes offending characters that could be wrongfully interpreted as XML markup. - * - * The following characters are reserved in XML and will be replaced with their - * corresponding XML entities: - * - * ' is replaced with ' - * " is replaced with " - * & is replaced with & - * < is replaced with < - * > is replaced with > - * - * @uses ENT_XML1 if available (PHP >= 5.4) - * - * @param string $string - * @return string - */ - public static function xml($string) { - if (defined('ENT_XML1')) { - return htmlspecialchars($string, ENT_QUOTES | ENT_XML1, 'UTF-8'); - } else { - return str_replace(''', ''', htmlspecialchars($string, ENT_QUOTES, 'UTF-8')); - } - } - - /** - * Escape common HTML attributes data - * - * This can be used to put untrusted data into typical attribute values - * like width, name, value, etc. - * - * This should not be used for complex attributes like href, src, style, - * or any of the event handlers like onmouseover. - * Use esc($string, 'js') for event handler attributes, esc($string, 'url') - * for src attributes and esc($string, 'css') for style attributes. - * - *
content
- *
content
- *
content
- * - * @param string $string - * @param string $strict Whether to escape characters like [space] % * + , - / ; < = > ^ and | - * which is necessary in case of unquoted HTML attributes. - * @return string - */ - public static function attr($string, $strict = false) { - if(static::noNeedToEscape($string)) return $string; - if($strict !== true) { - return preg_replace_callback('/[^a-z0-9,\.\-_]/iSu', 'static::escapeAttrChar', $string); - } - return static::html($string); - } - - /** - * Escape JavaScript data values - * - * This can be used to put dynamically generated JavaScript code - * into both script blocks and event-handler attributes. - * - * - * - *
- * - * @param string $string - * @return string - */ - public static function js($string) { - if(static::noNeedToEscape($string)) return $string; - return preg_replace_callback('/[^a-z0-9,\._]/iSu', 'static::escapeJSChar', $string); - } - - /** - * Escape HTML style property values - * - * This can be used to put untrusted data into a stylesheet or a style tag. - * - * Stay away from putting untrusted data into complex properties like url, - * behavior, and custom (-moz-binding). You should also not put untrusted data - * into IE’s expression property value which allows JavaScript. - * - * - * - * text - * - * @param string $string - * @return string - */ - public static function css($string) { - if(static::noNeedToEscape($string)) return $string; - return preg_replace_callback('/[^a-z0-9]/iSu', 'static::escapeCSSChar', $string); - } - - /** - * Escape URL parameter values - * - * This can be used to put untrusted data into HTTP GET parameter values. - * This should not be used to escape an entire URI. - * - * link - * - * @param string $string - * @return string - */ - public static function url($string) { - return rawurlencode($string); - } - - /** - * Escape character for HTML attribute - * - * Callback function for preg_replace_callback() that applies HTML attribute - * escaping to all matches. - * - * @param array $matches - * @return mixed Unicode replacement if character is undefined in HTML, - * named HTML entity if available (only those that XML supports), - * upper hex entity if a named entity does not exist or - * entity with the &#xHH; format if ASCII value is less than 256. - */ - protected static function escapeAttrChar($matches) { - $char = $matches[0]; - - if(static::charIsUndefined($char)) { - return '�'; - } - - $dec = hexdec(bin2hex($char)); - - $namedEntities = array( - 34 => '"', // " - 38 => '&', // & - 60 => '<', // < - 62 => '>' // > - ); - - if(isset($namedEntities[$dec])) { - return $namedEntities[$dec]; - } - - if($dec > 255) { - return sprintf('&#x%04X;', $dec); - } - - return sprintf('&#x%02X;', $dec); - } - - /** - * Escape character for JavaScript - * - * Callback function for preg_replace_callback() that applies Javascript - * escaping to all matches. - * - * @param array $matches - * @return string - */ - protected static function escapeJSChar($matches) { - $char = $matches[0]; - if(str::length($char) == 1) { - return sprintf('\\x%02X', ord($char)); - } - $char = static::convertEncoding($char); - return sprintf('\\u%04s', str::upper(bin2hex($char))); - } - - /** - * Escape character for CSS - * - * Callback function for preg_replace_callback() that applies CSS - * escaping to all matches. - * - * @param array $matches - * @return string - */ - protected static function escapeCSSChar($matches) { - $char = $matches[0]; - if(str::length($char) == 1) { - $ord = ord($char); - } else { - $char = static::convertEncoding($char); - $ord = hexdec(bin2hex($char)); - } - return sprintf('\\%X ', $ord); - } - -} diff --git a/kirby/toolkit/lib/exif.php b/kirby/toolkit/lib/exif.php deleted file mode 100644 index 02cd717..0000000 --- a/kirby/toolkit/lib/exif.php +++ /dev/null @@ -1,221 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Exif { - - // the parent media object - protected $media = null; - - // the raw exif array - protected $data = null; - - // the camera object with model and make - protected $camera = null; - - // the location object - protected $location = null; - - // the timestamp - protected $timestamp = null; - - // the exposure value - protected $exposure = null; - - // the aperture value - protected $aperture = null; - - // iso value - protected $iso = null; - - // focal length - protected $focalLength = null; - - // color or black/white - protected $isColor = null; - - /** - * Constructor - * - * @param Media $media - */ - public function __construct(Media $media) { - $this->media = $media; - $this->parse(); - } - - /** - * Returns the raw data array from the parser - * - * @return array - */ - public function data() { - return $this->data; - } - - /** - * Returns the Camera object - * - * @return object KirbyExifCamera - */ - public function camera() { - - if(!is_null($this->camera)) return $this->camera; - - // check for valid exif data - if(!is_array($this->data)) return null; - - // initialize and return it - return $this->camera = new Exif\Camera($this->data); - - } - - /** - * Returns the location object - * - * @return object ExifLocation - */ - public function location() { - - if(!is_null($this->location)) return $this->location; - - // check for valid exif data - if(!is_array($this->data)) return null; - - // initialize and return it - return $this->location = new Exif\Location($this->data); - - } - - /** - * Returns the timestamp - * - * @return string - */ - public function timestamp() { - return $this->timestamp; - } - - /** - * Returns the exposure - * - * @return string - */ - public function exposure() { - return $this->exposure; - } - - /** - * Returns the aperture - * - * @return string - */ - public function aperture() { - return $this->aperture; - } - - /** - * Returns the iso value - * - * @return int - */ - public function iso() { - return $this->iso; - } - - /** - * Checks if this is a color picture - * - * @return boolean - */ - public function isColor() { - return $this->isColor; - } - - /** - * Checks if this is a bw picture - * - * @return boolean - */ - public function isBW() { - return !$this->isColor; - } - - /** - * Returns the focal length - * - * @return string - */ - public function focalLength() { - return $this->focalLength; - } - - /** - * Pareses and stores all relevant exif data - */ - protected function parse() { - - // read the exif data of the media object if possible - $this->data = @read_exif_data($this->media->root()); - - // stop on invalid exif data - if(!is_array($this->data)) return false; - - // store the timestamp when the picture has been taken - if(isset($this->data['DateTimeOriginal'])) { - $this->timestamp = strtotime($this->data['DateTimeOriginal']); - } else { - $this->timestamp = a::get($this->data, 'FileDateTime', $this->media->modified()); - } - - // exposure - $this->exposure = a::get($this->data, 'ExposureTime'); - - // iso - $this->iso = a::get($this->data, 'ISOSpeedRatings'); - - // focal length - if(isset($this->data['FocalLength'])) { - $this->focalLength = $this->data['FocalLength']; - } else if(isset($this->data['FocalLengthIn35mmFilm'])) { - $this->focalLength = $this->data['FocalLengthIn35mmFilm']; - } - - // aperture - $this->aperture = @$this->data['COMPUTED']['ApertureFNumber']; - - // color or bw - $this->isColor = @$this->data['COMPUTED']['IsColor'] == true; - - } - - /** - * Converts the object into a nicely readable array - * - * @return array - */ - public function toArray() { - - return array( - 'camera' => $this->camera()->toArray(), - 'location' => $this->location()->toArray(), - 'timestamp' => $this->timestamp(), - 'exposure' => $this->exposure(), - 'aperture' => $this->aperture(), - 'iso' => $this->iso(), - 'focalLength' => $this->focalLength(), - 'isColor' => $this->isColor() - ); - - } - -} diff --git a/kirby/toolkit/lib/exif/camera.php b/kirby/toolkit/lib/exif/camera.php deleted file mode 100644 index 7bfeff0..0000000 --- a/kirby/toolkit/lib/exif/camera.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Camera { - - protected $make; - protected $model; - - /** - * Constructor - * - * @param array $exif - */ - public function __construct($exif) { - $this->make = @$exif['Make']; - $this->model = @$exif['Model']; - } - - /** - * Returns the make of the camera - * - * @return string - */ - public function make() { - return $this->make; - } - - /** - * Returns the camera model - * - * @return string - */ - public function model() { - return $this->model; - } - - /** - * Converts the object into a nicely readable array - * - * @return array - */ - public function toArray() { - return array( - 'make' => $this->make, - 'model' => $this->model - ); - } - - /** - * Returns the full make + model name - * - * @return string - */ - public function __toString() { - return trim($this->make . ' ' . $this->model); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/exif/location.php b/kirby/toolkit/lib/exif/location.php deleted file mode 100644 index a62ab66..0000000 --- a/kirby/toolkit/lib/exif/location.php +++ /dev/null @@ -1,118 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Location { - - // latitude - protected $lat; - - // longitude - protected $lng; - - /** - * Constructor - * - * @param array $exif The entire exif array - */ - public function __construct($exif) { - - if( - isset($exif['GPSLatitude']) && - isset($exif['GPSLatitudeRef']) && - isset($exif['GPSLongitude']) && - isset($exif['GPSLongitudeRef']) - ) { - $this->lat = $this->gps($exif['GPSLatitude'], $exif['GPSLatitudeRef']); - $this->lng = $this->gps($exif['GPSLongitude'], $exif['GPSLongitudeRef']); - } - - } - - /** - * Returns the latitude - * - * @return float - */ - public function lat() { - return $this->lat; - } - - /** - * Returns the longitude - * - * @return float - */ - public function lng() { - return $this->lng; - } - - /** - * Converts the gps coordinates - * - * @param string $coord - * @param string $hemi - * @return float - */ - protected function gps($coord, $hemi) { - - $degrees = count($coord) > 0 ? $this->num($coord[0]) : 0; - $minutes = count($coord) > 1 ? $this->num($coord[1]) : 0; - $seconds = count($coord) > 2 ? $this->num($coord[2]) : 0; - - $hemi = strtoupper($hemi); - $flip = ($hemi == 'W' || $hemi == 'S') ? -1 : 1; - - return $flip * ($degrees + $minutes / 60 + $seconds / 3600); - - } - - /** - * Converts coordinates to floats - * - * @param string $part - * @return float - */ - protected function num($part) { - - $parts = explode('/', $part); - - if(count($parts) <= 0) return 0; - if(count($parts) == 1) return $parts[0]; - - return floatval($parts[0]) / floatval($parts[1]); - - } - - /** - * Converts the object into a nicely readable array - * - * @return array - */ - public function toArray() { - return array( - 'lat' => $this->lat(), - 'lng' => $this->lng() - ); - } - - /** - * Echos the entire location as lat, lng - * - * @return string - */ - public function __toString() { - return trim(trim($this->lat() . ', ' . $this->lng(), ',')); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/f.php b/kirby/toolkit/lib/f.php deleted file mode 100644 index dd27d6c..0000000 --- a/kirby/toolkit/lib/f.php +++ /dev/null @@ -1,794 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class F { - - public static $mimes = array( - 'hqx' => 'application/mac-binhex40', - 'cpt' => 'application/mac-compactpro', - 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream'), - 'bin' => 'application/macbinary', - 'dms' => 'application/octet-stream', - 'lha' => 'application/octet-stream', - 'lzh' => 'application/octet-stream', - 'exe' => array('application/octet-stream', 'application/x-msdownload'), - 'class' => 'application/octet-stream', - 'psd' => 'application/x-photoshop', - 'so' => 'application/octet-stream', - 'sea' => 'application/octet-stream', - 'dll' => 'application/octet-stream', - 'oda' => 'application/oda', - 'pdf' => array('application/pdf', 'application/x-download'), - 'ai' => 'application/postscript', - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'mif' => 'application/vnd.mif', - 'wbxml' => 'application/wbxml', - 'wmlc' => 'application/wmlc', - 'dcr' => 'application/x-director', - 'dir' => 'application/x-director', - 'dxr' => 'application/x-director', - 'dvi' => 'application/x-dvi', - 'gtar' => 'application/x-gtar', - 'gz' => 'application/x-gzip', - 'php' => array('text/php', 'text/x-php', 'application/x-httpd-php', 'application/php', 'application/x-php', 'application/x-httpd-php-source'), - 'php3' => array('text/php', 'text/x-php', 'application/x-httpd-php', 'application/php', 'application/x-php', 'application/x-httpd-php-source'), - 'phtml' => array('text/php', 'text/x-php', 'application/x-httpd-php', 'application/php', 'application/x-php', 'application/x-httpd-php-source'), - 'phps' => array('text/php', 'text/x-php', 'application/x-httpd-php', 'application/php', 'application/x-php', 'application/x-httpd-php-source'), - 'js' => 'application/x-javascript', - 'swf' => 'application/x-shockwave-flash', - 'sit' => 'application/x-stuffit', - 'tar' => 'application/x-tar', - 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'), - 'xhtml' => 'application/xhtml+xml', - 'xht' => 'application/xhtml+xml', - 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'), - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mpga' => 'audio/mpeg', - 'mp2' => 'audio/mpeg', - 'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'), - 'aif' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'aifc' => 'audio/x-aiff', - 'ram' => 'audio/x-pn-realaudio', - 'rm' => 'audio/x-pn-realaudio', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'ra' => 'audio/x-realaudio', - 'rv' => 'video/vnd.rn-realvideo', - 'wav' => 'audio/x-wav', - 'bmp' => 'image/bmp', - 'gif' => 'image/gif', - 'ico' => 'image/x-icon', - 'jpg' => array('image/jpeg', 'image/pjpeg'), - 'jpeg' => array('image/jpeg', 'image/pjpeg'), - 'jpe' => array('image/jpeg', 'image/pjpeg'), - 'png' => 'image/png', - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'svg' => 'image/svg+xml', - 'css' => 'text/css', - 'html' => 'text/html', - 'htm' => 'text/html', - 'shtml' => 'text/html', - 'txt' => 'text/plain', - 'text' => 'text/plain', - 'log' => array('text/plain', 'text/x-log'), - 'rtx' => 'text/richtext', - 'rtf' => 'text/rtf', - 'xml' => 'text/xml', - 'xsl' => 'text/xml', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpe' => 'video/mpeg', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - 'avi' => 'video/x-msvideo', - 'movie' => 'video/x-sgi-movie', - 'doc' => 'application/msword', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', - 'xls' => array('application/excel', 'application/vnd.ms-excel', 'application/msexcel'), - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', - 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint'), - 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', - 'word' => array('application/msword', 'application/octet-stream'), - 'xl' => 'application/excel', - 'eml' => 'message/rfc822', - 'json' => array('application/json', 'text/json'), - 'odt' => 'application/vnd.oasis.opendocument.text', - 'odc' => 'application/vnd.oasis.opendocument.chart', - 'odp' => 'application/vnd.oasis.opendocument.presentation', - ); - - public static $types = array( - - 'image' => array( - 'jpeg', - 'jpg', - 'jpe', - 'gif', - 'png', - 'svg', - 'ico', - 'tif', - 'tiff', - 'bmp', - 'psd', - 'ai', - 'eps', - 'ps' - ), - - 'document' => array( - 'txt', - 'text', - 'mdown', - 'md', - 'markdown', - 'pdf', - 'doc', - 'docx', - 'dotx', - 'word', - 'xl', - 'xls', - 'xlsx', - 'xltx', - 'ppt', - 'pptx', - 'potx', - 'csv', - 'rtf', - 'rtx', - 'log', - 'odt', - 'odp', - 'odc', - ), - - 'archive' => array( - 'zip', - 'tar', - 'gz', - 'gzip', - 'tgz', - ), - - 'code' => array( - 'js', - 'css', - 'scss', - 'htm', - 'html', - 'shtml', - 'xhtml', - 'php', - 'php3', - 'php4', - 'rb', - 'xml', - 'json', - 'java', - 'py' - ), - - 'video' => array( - 'mov', - 'movie', - 'avi', - 'ogg', - 'ogv', - 'webm', - 'flv', - 'swf', - 'mp4', - 'm4v', - 'mpg', - 'mpe' - ), - - 'audio' => array( - 'mp3', - 'm4a', - 'wav', - 'aif', - 'aiff', - 'midi', - ), - - ); - - public static $units = array('B','kB','MB','GB','TB','PB', 'EB', 'ZB', 'YB'); - - /** - * Checks if a file exists - * - * @param string $file - * @return boolean - */ - public static function exists($file) { - return file_exists($file); - } - - /** - * Safely requires a file if it exists - */ - public static function load($file, $data = array()) { - if(file_exists($file)) { - extract($data); - require($file); - } - } - - /** - * Creates a new file - * - * - * - * f::write('test.txt', 'hello'); - * // creates a new text file with hello as content - * - * // create a new file - * f::write('text.txt', array('test' => 'hello')); - * // creates a new file and encodes the array as json - * - * - * - * @param string $file The path for the new file - * @param mixed $content Either a string, an object or an array. Arrays and objects will be serialized. - * @param boolean $append true: append the content to an exisiting file if available. false: overwrite. - * @return boolean - */ - public static function write($file, $content, $append = false) { - if(is_array($content) || is_object($content)) $content = serialize($content); - $mode = ($append) ? FILE_APPEND | LOCK_EX : LOCK_EX; - // if the parent directory does not exist, create it - if(!is_dir(dirname($file))) { - if(!dir::make(dirname($file))) return false; - } - return (@file_put_contents($file, $content, $mode) !== false) ? true : false; - } - - /** - * Appends new content to an existing file - * - * @param string $file The path for the file - * @param mixed $content Either a string or an array. Arrays will be converted to JSON. - * @return boolean - */ - public static function append($file, $content) { - return static::write($file,$content,true); - } - - /** - * Reads the content of a file - * - * - * - * $content = f::read('test.txt'); - * // i.e. content is hello - * - * $content = f::read('text.txt', 'json'); - * // returns an array with the parsed content - * - * - * - * @param string $file The path for the file - * @return mixed - */ - public static function read($file) { - return @file_get_contents($file); - } - - /** - * Returns the file content as base64 encoded string - * - * @param string $file The path for the file - * @return string - */ - public static function base64($file) { - return base64_encode(f::read($file)); - } - - /** - * Returns the file as data uri - * - * @param string $file The path for the file - * @return string - */ - public static function uri($file) { - $mime = static::mime($file); - return ($mime) ? 'data:' . $mime . ';base64,' . static::base64($file) : false; - } - - /** - * Moves a file to a new location - * - * - * - * $move = f::move('test.txt', 'super.txt'); - * - * if($move) echo 'The file has been moved'; - * - * - * - * @param string $old The current path for the file - * @param string $new The path to the new location - * @return boolean - */ - public static function move($old, $new) { - if(!file_exists($old) || file_exists($new)) return false; - return @rename($old, $new); - } - - /** - * Copy a file to a new location. - * - * @param string $file - * @param string $target - * @return boolean - */ - public static function copy($file, $target) { - if(!file_exists($file) || file_exists($target)) return false; - return @copy($file, $target); - } - - /** - * Deletes a file - * - * - * - * $remove = f::remove('test.txt'); - * if($remove) echo 'The file has been removed'; - * - * - * - * @param string $file The path for the file - * @return boolean - */ - public static function remove($file) { - return file_exists($file) && is_file($file) && !empty($file) ? @unlink($file) : false; - } - - /** - * Gets the extension of a file - * - * - * - * $extension = f::extension('test.txt'); - * // extension is txt - * - * - * - * @param string $file The filename or path - * @param string $extension Set an optional extension to overwrite the current one - * @return string - */ - public static function extension($file, $extension = false) { - - // overwrite the current extension - if($extension !== false) { - return static::name($file) . '.' . $extension; - } - - // return the current extension - return strtolower(pathinfo($file, PATHINFO_EXTENSION)); - - } - - /** - * Returns all extensions for a certain file type - * - * @param string $type - * @return array - */ - public static function extensions($type = null) { - if(is_null($type)) return array_keys(static::$mimes); - return isset(static::$types[$type]) ? static::$types[$type] : array(); - } - - /** - * Extracts the filename from a file path - * - * - * - * $filename = f::filename('/var/www/test.txt'); - * // filename is test.txt - * - * - * - * @param string $name The path - * @return string - */ - public static function filename($name) { - return pathinfo($name, PATHINFO_BASENAME); - } - - /** - * Extracts the name from a file path or filename without extension - * - * - * - * $name = f::name('/var/www/test.txt'); - * - * // name is test - * - * - * - * @param string $name The path or filename - * @return string - */ - public static function name($name) { - return pathinfo($name, PATHINFO_FILENAME); - } - - /** - * Just an alternative for dirname() to stay consistent - * - * - * - * $dirname = f::dirname('/var/www/test.txt'); - * // dirname is /var/www - * - * - * - * @param string $file The path - * @return string - */ - public static function dirname($file) { - return dirname($file); - } - - /** - * Returns the size of a file. - * - * - * - * $size = f::size('/var/www/test.txt'); - * // size is ie: 1231939 - * - * - * - * @param mixed $file The path - * @return mixed - */ - public static function size($file) { - return filesize($file); - } - - /** - * Converts an integer size into a human readable format - * - * - * - * $niceSize = f::niceSize('/path/to/a/file.txt'); - * // nice size is i.e: 212 kb - * - * $niceSize = f::niceSize(1231939); - * // nice size is: 1,2 mb - * - * - * - * @param mixed $size The file size or a file path - * @return string - */ - public static function niceSize($size) { - - // file mode - if(is_string($size) && file_exists($size)) { - $size = static::size($size); - } - - // make sure it's an int - $size = (int)$size; - - // avoid errors for invalid sizes - if($size <= 0) return '0 kB'; - - // the math magic - return round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . static::$units[$i]; - - } - - /** - * Get the file's last modification time. - * - * @param string $file - * @param string $format - * @param string $handler date or strftime - * @return int - */ - public static function modified($file, $format = null, $handler = 'date') { - if(file_exists($file)) { - return !is_null($format) ? $handler($format, filemtime($file)) : filemtime($file); - } else { - return false; - } - } - - /** - * Returns the mime type of a file - * - * @param string $file - * @return mixed - */ - public static function mime($file) { - - // stop for invalid files - if(!file_exists($file)) return null; - - // Fileinfo is prefered if available - if(function_exists('finfo_file')) { - $finfo = finfo_open(FILEINFO_MIME_TYPE); - $mime = finfo_file($finfo, $file); - finfo_close($finfo); - return $mime; - } - - // for older versions with mime_content_type go for that. - if(function_exists('mime_content_type') && $mime = @mime_content_type($file) !== false) { - return $mime; - } - - // shell check - try { - $mime = system::execute('file', [$file, '-z', '-b', '--mime'], 'output'); - $mime = trim(str::split($mime, ';')[0]); - if(f::mimeToExtension($mime)) return $mime; - } catch(Exception $e) { - // no mime type detectable with shell - $mime = null; - } - - // Mime Sniffing - $reader = new MimeReader($file); - $mime = $reader->get_type(); - - if(!empty($mime) && f::mimeToExtension($mime)) { - return $mime; - } - - // guess the matching mime type by extension - return f::extensionToMime(f::extension($file)); - - } - - /** - * Returns all detectable mime types - * - * @return array - */ - public static function mimes() { - return static::$mimes; - } - - /** - * Categorize the file - * - * @param string $file Either the file path or extension - * @return string - */ - public static function type($file) { - - $length = strlen($file); - - if($length >= 2 && $length <= 4) { - // use the file name as extension - $extension = $file; - } else { - // get the extension from the filename - $extension = pathinfo($file, PATHINFO_EXTENSION); - } - - if(empty($extension)) { - // detect the mime type first to get the most reliable extension - $mime = static::mime($file); - $extension = static::mimeToExtension($mime); - } - - // sanitize extension - $extension = strtolower($extension); - - foreach(static::$types as $type => $extensions) { - if(in_array($extension, $extensions)) return $type; - } - - return null; - - } - - /** - * Returns an array of all available file types - * - * @return array - */ - public static function types() { - return static::$types; - } - - /** - * Checks if a file is of a certain type - * - * @param string $file Full path to the file - * @param string $value An extension or mime type - * @return boolean - */ - public static function is($file, $value) { - - if(in_array($value, static::extensions())) { - // check for the extension - return static::extension($file) == $value; - } else if(strpos($value, '/') !== false) { - // check for the mime type - return static::mime($file) == $value; - } - - return false; - - } - - /** - * Converts a mime type to a file extension - * - * @param string $mime - * @return string - */ - public static function mimeToExtension($mime) { - foreach(static::$mimes as $key => $value) { - if(is_array($value) && in_array($mime, $value)) return $key; - if($value == $mime) return $key; - } - return null; - } - - /** - * Returns the type for a given mime - * - * @param string $mime - * @return string - */ - public static function mimeToType($mime) { - return static::extensionToType(static::mimeToExtension($mime)); - } - - /** - * Converts a file extension to a mime type - * - * @param string $extension - * @return string - */ - public static function extensionToMime($extension) { - $mime = isset(static::$mimes[$extension]) ? static::$mimes[$extension] : null; - return is_array($mime) ? array_shift($mime) : $mime; - } - - /** - * Returns the file type for a passed extension - * - * @param string $extension - * @return string - */ - public static function extensionToType($extension) { - - // get all categorized types - foreach(static::$types as $type => $extensions) { - if(in_array($extension, $extensions)) return $type; - } - - return null; - - } - - /** - * Sanitize a filename to strip unwanted special characters - * - * - * - * $safe = f::safeName('über genious.txt'); - * // safe will be ueber-genious.txt - * - * - * - * @param string $string The file name - * @return string - */ - public static function safeName($string) { - $name = static::name($string); - $extension = static::extension($string); - $end = !empty($extension) ? '.' . str::slug($extension) : ''; - return str::slug($name, '-', 'a-z0-9@._-') . $end; - } - - /** - * Checks if the file is writable - * - * @param string $file - * @return boolean - */ - public static function isWritable($file) { - return is_writable($file); - } - - /** - * Checks if the file is readable - * - * @param string $file - * @return boolean - */ - public static function isReadable($file) { - return is_readable($file); - } - - /** - * Read and send the file with the correct headers - * - * @param string $file - */ - public static function show($file) { - - // stop the download if the file does not exist or is not readable - if(!is_file($file) || !is_readable($file)) return false; - - // send the browser headers - header::type(f::mime($file)); - - // send the file - die(f::read($file)); - - } - - /* - * Automatically sends all needed headers for the file to be downloaded - * and echos the file's content - * - * @param string $file The root to the file - * @param string $name Optional filename for the download - */ - public static function download($file, $name = null) { - - // stop the download if the file does not exist or is not readable - if(!is_file($file) || !is_readable($file)) return false; - - header::download(array( - 'name' => $name ? $name : f::filename($file), - 'size' => f::size($file), - 'mime' => f::mime($file), - 'modified' => f::modified($file) - )); - - die(f::read($file)); - - } - - /** - * Tries to find a file by various extensions - * - * @param string $base - * @param array $extensions - * @return string|false - */ - public static function resolve($base, $extensions) { - foreach($extensions as $ext) { - $file = $base . '.' . $ext; - if(file_exists($file)) return $file; - } - return false; - } - -} diff --git a/kirby/toolkit/lib/folder.php b/kirby/toolkit/lib/folder.php deleted file mode 100644 index 39e9d76..0000000 --- a/kirby/toolkit/lib/folder.php +++ /dev/null @@ -1,406 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Folder { - - // the root for the directory - protected $root = null; - - // a cache for the scanned inventory - protected $inventory = null; - - /** - * Constructor - */ - public function __construct($root) { - if(file_exists($root) && is_file($root)) throw new Exception('Invalid folder: ' . $root); - $this->root = $root; - } - - /** - * Returns the root of the directory - */ - public function root() { - return $this->root; - } - - /** - * Returns a md5 hash of the root - */ - public function hash() { - return md5($this->root); - } - - /** - * Returns the name of the directory without the full path - * - * @return string - */ - public function name() { - return basename($this->root); - } - - /** - * Returns the parent directory object - * - * @return Directory - */ - public function parent() { - return new static(dirname($this->root)); - } - - /** - * Checks if the dir exists - * - * @return boolean - */ - public function exists() { - return is_dir($this->root); - } - - /** - * Creates the directory if it does not exist yet - * - * @param boolean $recursive - * @return boolean - */ - public function make($recursive = true) { - return dir::make($this->root, $recursive); - } - - /** - * Alternative for make - * - * @param boolean $recursive - * @return boolean - */ - public function create($recursive = true) { - return $this->make($recursive); - } - - /** - * Returns the entire content of the directory - * - * @return array - */ - public function inventory() { - if(!is_dir($this->root)) return array(); - return $this->inventory = is_null($this->inventory) ? scandir($this->root) : $this->inventory; - } - - /** - * Reads the directory content and returns an array with file objects - * - * @param array $ignore - * @return array - */ - public function scan($ignore = null) { - $skip = is_array($ignore) ? $ignore : a::get(dir::$defaults, 'ignore', array()); - return empty($skip) ? $this->inventory() : (array)array_diff($this->inventory(), $skip); - } - - /** - * Alternative for scan - * - * @param array $ignore - * @return array - */ - public function read($ignore = null) { - return $this->scan($ignore); - } - - /** - * Returns a collection with full File and Directory objects - * for each item in the directory - * - * @param array $ignore - * @return Collection - */ - public function content($ignore = null) { - $raw = $this->scan($ignore); - $root = $this->root; - $content = new Collection(); - - foreach($raw as $file) { - - if(is_dir($root . DS . $file)) { - $content->append($file, new static($root . DS . $file)); - } else { - $content->append($file, new Media($root . DS . $file)); - } - - } - - return $content; - - } - - /** - * Return a collection of all files within the directory - * - * @param array $ignore - * @param boolean $plain - * @return mixed When $plain is true an array will be returned. Otherwise a Collection - */ - public function files($ignore = null, $plain = false) { - - $raw = $this->scan($ignore); - - if($plain) { - - $content = array(); - - foreach($raw as $file) { - if(is_file($this->root . DS . $file)) $content[] = $file; - } - - } else { - - $content = new Collection(); - - foreach($raw as $file) { - if(is_file($this->root . DS . $file)) { - $content->append($file, new Media($this->root . DS . $file)); - } - } - - } - - return $content; - - } - - /** - * Return a collection of subfolders - * - * @param array $ignore - * @param boolean $plain - * @return mixed If $plain is true an array will be returned. Otherwise a Collection - */ - public function children($ignore = null, $plain = false) { - - $raw = $this->scan($ignore); - - if($plain) { - - $content = array(); - - foreach($raw as $file) { - if(is_dir($this->root . DS . $file)) $content[] = $file; - } - - } else { - - $content = new Collection(); - - foreach($raw as $file) { - if(is_dir($this->root . DS . $file)) { - $content->append($file, new static($this->root . DS . $file)); - } - } - - } - - return $content; - - } - - /** - * Returns a subfolder object by path - * - * @return mixed Directory - */ - public function child($path) { - $root = $this->root . DS . str_replace('/', DS, $path); - if(!is_dir($root)) return false; - return new static($root); - } - - /** - * Corresponding method to File::type() - * which makes it possible to filter a collection - * of files and directories by type. - * - * @return string - */ - public function type() { - return 'directory'; - } - - /** - * Moves the directory to a new location - * - * @param string $to - * @return boolean - */ - public function move($to) { - if(!dir::move($this->root, $to)) { - return false; - } else { - $this->root = true; - return true; - } - } - - /** - * Copies the directory to a new location - * - * @param string $to - * @return boolean - */ - public function copy($to) { - - // Make destination directory - $copy = new static($to); - if(!$copy->make()) return false; - - // Loop through all subfiles and folders - foreach($this->content() as $item) { - if(is_a($item, 'Folder')) { - $dest = $to . DS . $item->name(); - } else { - $dest = $to . DS . $item->filename(); - } - if(!$item->copy($dest)) return false; - } - - return $copy; - - } - - /** - * Deletes the directory - * - * @param boolean $keep Set this to true to keep the directory but delete all its content - * @return boolean - */ - public function delete($keep = false) { - $items = $this->content(array('.', '..')); - foreach($items as $item) $item->delete(); - return $keep ? true : @rmdir($this->root); - } - - /** - * Alternative for delete - * - * @param boolean $keep Set this to true to keep the directory but delete all its content - * @return boolean - */ - public function remove($keep = false) { - return $this->delete($keep); - } - - /** - * Deletes all contents of the directory - * - * @return boolean - */ - public function flush() { - return $this->delete(true); - } - - /** - * Alternative for flush - * - * @return boolean - */ - public function clean() { - return $this->delete(true); - } - - /** - * Returns the entire size of the directory and all its contents - * - * @return int - */ - public function size() { - - $size = 0; - $items = $this->content(array('.', '..')); - - foreach($items AS $item) $size += $item->size(); - return $size; - - } - - /** - * Returns the size as a human-readable string - * - * @return string - */ - public function niceSize() { - return f::niceSize($this->size()); - } - - /** - * Recursively check when the dir and all - * subfolders have been modified for the last time. - * - * @return int - */ - public function modified($format = null, $handler = 'date') { - - $modified = filemtime($this->root); - $items = $this->scan(array('.', '..')); - - foreach($items AS $item) { - - if(is_file($this->root . DS . $item)) { - $newModified = filemtime($this->root . DS . $item); - } else { - $object = new static($this->root . DS . $item); - $newModified = $object->modified(); - } - - $modified = ($newModified > $modified) ? $newModified : $modified; - - } - - return !is_null($format) ? $handler($format, $modified) : $modified; - - } - - /** - * Checks if the directory is writable - * - * @param boolean $recursive - * @return boolean - */ - public function isWritable($recursive = false) { - if($recursive) { - if(!$this->isWritable()) return false; - foreach($this->content() as $f) { - if(!$f->isWritable(true)) return false; - } - return true; - } - return is_writable($this->root); - } - - /** - * Checks if the directory is readable - * - * @return boolean - */ - public function isReadable() { - return is_readable($this->root); - } - - /** - * Makes it possible to echo the entire object - * - * @return string - */ - public function __toString() { - return $this->root; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/header.php b/kirby/toolkit/lib/header.php deleted file mode 100644 index 7c87220..0000000 --- a/kirby/toolkit/lib/header.php +++ /dev/null @@ -1,236 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Header { - - // configuration - public static $codes = array( - - // successful - '_200' => 'OK', - '_201' => 'Created', - '_202' => 'Accepted', - - // redirection - '_301' => 'Moved Permanently', - '_302' => 'Found', - '_303' => 'See Other', - '_304' => 'Not Modified', - '_307' => 'Temporary Redirect', - - // client error - '_400' => 'Bad Request', - '_401' => 'Unauthorized', - '_402' => 'Payment Required', - '_403' => 'Forbidden', - '_404' => 'Not Found', - '_405' => 'Method Not Allowed', - - // server error - '_500' => 'Internal Server Error', - '_501' => 'Not Implemented', - '_502' => 'Bad Gateway', - '_503' => 'Service Unavailable' - ); - - /** - * Sends a content type header - * - * @param string $mime - * @param string $charset - * @param boolean $send - * @return mixed - */ - public static function contentType($mime, $charset = 'UTF-8', $send = true) { - if(f::extensionToMime($mime)) $mime = f::extensionToMime($mime); - $header = 'Content-type: ' . $mime; - if($charset) $header .= '; charset=' . $charset; - if(!$send) return $header; - header($header); - } - - /** - * Shortcut for static::contentType() - * - * @param string $mime - * @param string $charset - * @param boolean $send - * @return mixed - */ - public static function type($mime, $charset = 'UTF-8', $send = true) { - return static::contentType($mime, $charset, $send); - } - - /** - * Sends a status header - * - * @param int $code The HTTP status code - * @param boolean $send If set to false the header will be returned instead - * @return mixed - */ - public static function status($code, $send = true) { - - $codes = static::$codes; - $code = !array_key_exists('_' . $code, $codes) ? 400 : $code; - $message = isset($codes['_' . $code]) ? $codes['_' . $code] : 'Something went wrong'; - $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0'; - $header = $protocol . ' ' . $code . ' ' . $message; - - if(!$send) return $header; - - // try to send the header - header($header); - - } - - /** - * Sends a 200 header - * - * @param boolean $send - * @return mixed - */ - public static function success($send = true) { - return static::status(200, $send); - } - - /** - * Sends a 201 header - * - * @param boolean $send - * @return mixed - */ - public static function created($send = true) { - return static::status(201, $send); - } - - /** - * Sends a 202 header - * - * @param boolean $send - * @return mixed - */ - public static function accepted($send = true) { - return static::status(202, $send); - } - - /** - * Sends a 400 header - * - * @param boolean $send - * @return mixed - */ - public static function error($send = true) { - return static::status(400, $send); - } - - /** - * Sends a 403 header - * - * @param boolean $send - * @return mixed - */ - public static function forbidden($send = true) { - return static::status(403, $send); - } - - /** - * Sends a 404 header - * - * @param boolean $send - * @return mixed - */ - public static function notfound($send = true) { - return static::status(404, $send); - } - - /** - * Sends a 404 header - * - * @param boolean $send - * @return mixed - */ - public static function missing($send = true) { - return static::status(404, $send); - } - - /** - * Sends a 500 header - * - * @param boolean $send - * @return mixed - */ - public static function panic($send = true) { - return static::status(500, $send); - } - - /** - * Sends a 503 header - * - * @param boolean $send - * @return mixed - */ - public static function unavailable($send = true) { - return static::status(503, $send); - } - - /** - * Sends a redirect header - * - * @param boolean $send - * @return mixed - */ - public static function redirect($url, $code = 301, $send = true) { - - $status = static::status($code, false); - $location = 'Location:' . $url; - - if(!$send) { - return $status . PHP_EOL . $location; - } - - header($status); - header($location); - exit(); - - } - - /** - * Sends download headers for anything that is downloadable - * - * @param array $params Check out the defaults array for available parameters - */ - public static function download($params = array()) { - - $defaults = array( - 'name' => 'download', - 'size' => false, - 'mime' => 'application/force-download', - 'modified' => time() - ); - - $options = array_merge($defaults, $params); - - header('Pragma: public'); - header('Expires: 0'); - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - header('Last-Modified: '. gmdate('D, d M Y H:i:s', $options['modified']) . ' GMT'); - header('Cache-Control: private', false); - static::contentType($options['mime']); - header('Content-Disposition: attachment; filename="' . $options['name'] . '"'); - header('Content-Transfer-Encoding: binary'); - if($options['size']) header('Content-Length: ' . $options['size']); - header('Connection: close'); - - } - -} diff --git a/kirby/toolkit/lib/html.php b/kirby/toolkit/lib/html.php deleted file mode 100644 index 9db770e..0000000 --- a/kirby/toolkit/lib/html.php +++ /dev/null @@ -1,255 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Html { - - /** - * An internal store for a html entities translation table - * - * @return array - */ - public static $entities = array( - ' ' => ' ', '¡' => '¡', '¢' => '¢', '£' => '£', '¤' => '¤', '¥' => '¥', '¦' => '¦', '§' => '§', - '¨' => '¨', '©' => '©', 'ª' => 'ª', '«' => '«', '¬' => '¬', '­' => '­', '®' => '®', '¯' => '¯', - '°' => '°', '±' => '±', '²' => '²', '³' => '³', '´' => '´', 'µ' => 'µ', '¶' => '¶', '·' => '·', - '¸' => '¸', '¹' => '¹', 'º' => 'º', '»' => '»', '¼' => '¼', '½' => '½', '¾' => '¾', '¿' => '¿', - 'À' => 'À', 'Á' => 'Á', 'Â' => 'Â', 'Ã' => 'Ã', 'Ä' => 'Ä', 'Å' => 'Å', 'Æ' => 'Æ', 'Ç' => 'Ç', - 'È' => 'È', 'É' => 'É', 'Ê' => 'Ê', 'Ë' => 'Ë', 'Ì' => 'Ì', 'Í' => 'Í', 'Î' => 'Î', 'Ï' => 'Ï', - 'Ð' => 'Ð', 'Ñ' => 'Ñ', 'Ò' => 'Ò', 'Ó' => 'Ó', 'Ô' => 'Ô', 'Õ' => 'Õ', 'Ö' => 'Ö', '×' => '×', - 'Ø' => 'Ø', 'Ù' => 'Ù', 'Ú' => 'Ú', 'Û' => 'Û', 'Ü' => 'Ü', 'Ý' => 'Ý', 'Þ' => 'Þ', 'ß' => 'ß', - 'à' => 'à', 'á' => 'á', 'â' => 'â', 'ã' => 'ã', 'ä' => 'ä', 'å' => 'å', 'æ' => 'æ', 'ç' => 'ç', - 'è' => 'è', 'é' => 'é', 'ê' => 'ê', 'ë' => 'ë', 'ì' => 'ì', 'í' => 'í', 'î' => 'î', 'ï' => 'ï', - 'ð' => 'ð', 'ñ' => 'ñ', 'ò' => 'ò', 'ó' => 'ó', 'ô' => 'ô', 'õ' => 'õ', 'ö' => 'ö', '÷' => '÷', - 'ø' => 'ø', 'ù' => 'ù', 'ú' => 'ú', 'û' => 'û', 'ü' => 'ü', 'ý' => 'ý', 'þ' => 'þ', 'ÿ' => 'ÿ', - 'ƒ' => 'ƒ', 'Α' => 'Α', 'Β' => 'Β', 'Γ' => 'Γ', 'Δ' => 'Δ', 'Ε' => 'Ε', 'Ζ' => 'Ζ', 'Η' => 'Η', - 'Θ' => 'Θ', 'Ι' => 'Ι', 'Κ' => 'Κ', 'Λ' => 'Λ', 'Μ' => 'Μ', 'Ν' => 'Ν', 'Ξ' => 'Ξ', 'Ο' => 'Ο', - 'Π' => 'Π', 'Ρ' => 'Ρ', 'Σ' => 'Σ', 'Τ' => 'Τ', 'Υ' => 'Υ', 'Φ' => 'Φ', 'Χ' => 'Χ', 'Ψ' => 'Ψ', - 'Ω' => 'Ω', 'α' => 'α', 'β' => 'β', 'γ' => 'γ', 'δ' => 'δ', 'ε' => 'ε', 'ζ' => 'ζ', 'η' => 'η', - 'θ' => 'θ', 'ι' => 'ι', 'κ' => 'κ', 'λ' => 'λ', 'μ' => 'μ', 'ν' => 'ν', 'ξ' => 'ξ', 'ο' => 'ο', - 'π' => 'π', 'ρ' => 'ρ', 'ς' => 'ς', 'σ' => 'σ', 'τ' => 'τ', 'υ' => 'υ', 'φ' => 'φ', 'χ' => 'χ', - 'ψ' => 'ψ', 'ω' => 'ω', 'ϑ' => 'ϑ', 'ϒ' => 'ϒ', 'ϖ' => 'ϖ', '•' => '•', '…' => '…', '′' => '′', - '″' => '″', '‾' => '‾', '⁄' => '⁄', '℘' => '℘', 'ℑ' => 'ℑ', 'ℜ' => 'ℜ', '™' => '™', 'ℵ' => 'ℵ', - '←' => '←', '↑' => '↑', '→' => '→', '↓' => '↓', '↔' => '↔', '↵' => '↵', '⇐' => '⇐', '⇑' => '⇑', - '⇒' => '⇒', '⇓' => '⇓', '⇔' => '⇔', '∀' => '∀', '∂' => '∂', '∃' => '∃', '∅' => '∅', '∇' => '∇', - '∈' => '∈', '∉' => '∉', '∋' => '∋', '∏' => '∏', '∑' => '∑', '−' => '−', '∗' => '∗', '√' => '√', - '∝' => '∝', '∞' => '∞', '∠' => '∠', '∧' => '∧', '∨' => '∨', '∩' => '∩', '∪' => '∪', '∫' => '∫', - '∴' => '∴', '∼' => '∼', '≅' => '≅', '≈' => '≈', '≠' => '≠', '≡' => '≡', '≤' => '≤', '≥' => '≥', - '⊂' => '⊂', '⊃' => '⊃', '⊄' => '⊄', '⊆' => '⊆', '⊇' => '⊇', '⊕' => '⊕', '⊗' => '⊗', '⊥' => '⊥', - '⋅' => '⋅', '⌈' => '⌈', '⌉' => '⌉', '⌊' => '⌊', '⌋' => '⌋', '⟨' => '〈', '⟩' => '〉', '◊' => '◊', - '♠' => '♠', '♣' => '♣', '♥' => '♥', '♦' => '♦', '"' => '"', '&' => '&', '<' => '<', '>' => '>', 'Œ' => 'Œ', - 'œ' => 'œ', 'Š' => 'Š', 'š' => 'š', 'Ÿ' => 'Ÿ', 'ˆ' => 'ˆ', '˜' => '˜', ' ' => ' ', ' ' => ' ', - ' ' => ' ', '‌' => '‌', '‍' => '‍', '‎' => '‎', '‏' => '‏', '–' => '–', '—' => '—', '‘' => '‘', - '’' => '’', '‚' => '‚', '“' => '“', '”' => '”', '„' => '„', '†' => '†', '‡' => '‡', '‰' => '‰', - '‹' => '‹', '›' => '›', '€' => '€' - ); - - /** - * Checks if a tag is self-closing - * - * @param string $tag - * @return param - */ - public static function isVoid($tag) { - - $void = array( - 'area', - 'base', - 'br', - 'col', - 'command', - 'embed', - 'hr', - 'img', - 'input', - 'keygen', - 'link', - 'meta', - 'param', - 'source', - 'track', - 'wbr', - ); - - return in_array(strtolower($tag), $void); - - } - - /** - * Returns the full array with all HTML entities - * - * @return array - */ - public static function entities() { - return static::$entities; - } - - /** - * Converts a string to a html-safe string - * - * @param string $string - * @param boolean $keepTags True: lets stuff inside html tags untouched. - * @return string The html string - */ - public static function encode($string, $keepTags = true) { - if($keepTags) { - return stripslashes(implode('', preg_replace_callback('/^([^<].+[^>])$/', function($match) { - return htmlentities($match[1], ENT_COMPAT, 'utf-8'); - }, preg_split('/(<.+?>)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE)))); - } else { - return htmlentities($string, ENT_COMPAT, 'utf-8'); - } - } - - /** - * Removes all html tags and encoded chars from a string - * - * - * - * echo html::decode('some crazy stuff'); - * // output: some uber crazy stuff - * - * - * - * @param string $string - * @return string The html string - */ - public static function decode($string) { - $string = strip_tags($string); - return html_entity_decode($string, ENT_COMPAT, 'utf-8'); - } - - /** - * Converts lines in a string into html breaks - * - * @param string $string - * @return string - */ - public static function breaks($string) { - return nl2br($string); - } - - /** - * Generates an Html tag with optional content and attributes - * - * @param string $name The name of the tag, i.e. "a" - * @param mixed $content The content if availble. Pass null to generate a self-closing tag, Pass an empty string to generate empty content - * @param array $attr An associative array with additional attributes for the tag - * @return string The generated Html - */ - public static function tag($name, $content = null, $attr = array()) { - - if(is_array($content)) { - $attr = $content; - $content = null; - } - - $html = '<' . $name; - $attr = static::attr($attr); - - if(!empty($attr)) $html .= ' ' . $attr; - - if(static::isVoid($name)) { - $html .= '>'; - } else { - $html .= '>' . $content . ''; - } - - return $html; - - } - - /** - * Generates a single attribute or a list of attributes - * - * @param string $name mixed string: a single attribute with that name will be generated. array: a list of attributes will be generated. Don't pass a second argument in that case. - * @param string $value if used for a single attribute, pass the content for the attribute here - * @return string the generated html - */ - public static function attr($name, $value = null) { - if(is_array($name)) { - $attributes = array(); - foreach($name as $key => $val) { - $a = static::attr($key, $val); - if($a) $attributes[] = $a; - } - return implode(' ', $attributes); - } - - if(empty($value) && $value !== '0' && $value !== 0) { - return false; - } else if($value === ' ') { - return strtolower($name) . '=""'; - } else if(is_bool($value)) { - return $value === true ? strtolower($name) : ''; - } else { - return strtolower($name) . '="' . ( is_array($value) ? implode(' ', $value) : $value ) . '"'; - } - - } - - /** - * Generates an a tag - * - * @param string $href The url for the a tag - * @param mixed $text The optional text. If null, the url will be used as text - * @param array $attr Additional attributes for the tag - * @return string the generated html - */ - public static function a($href, $text = null, $attr = array()) { - $attr = array_merge(array('href' => $href), $attr); - if(empty($text)) $text = $href; - return static::tag('a', $text, $attr); - } - - /** - * Generates an "a mailto" tag - * - * @param string $email The url for the a tag - * @param mixed $text The optional text. If null, the url will be used as text - * @param array $attr Additional attributes for the tag - * @return string the generated html - */ - public static function email($email, $text = null, $attr = array()) { - if(empty($text)) { - // show only the eMail address without additional parameters (if the 'text' argument is empty) - $text = str::encode(a::first(str::split($email, '?'))); - } - $email = str::encode($email); - $attr = array_merge(array('href' => 'mailto:' . $email), $attr); - return static::tag('a', $text, $attr); - } - - /** - * Generates an img tag - * - * @param string $src The url of the image - * @param array $attr Additional attributes for the image tag - * @return string the generated html - */ - public static function img($src, $attr = array()) { - $attr = array_merge(array('src' => $src, 'alt' => pathinfo($src, PATHINFO_FILENAME)), $attr); - return static::tag('img', null, $attr); - } - - /** - * Generates a HTML5 shiv script tag with additional comments for older IEs - * - * @return string the generated html - */ - public static function shiv() { - return '' . PHP_EOL; - } - -} diff --git a/kirby/toolkit/lib/i.php b/kirby/toolkit/lib/i.php deleted file mode 100644 index 59de3fe..0000000 --- a/kirby/toolkit/lib/i.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class I implements Iterator { - - public $data = array(); - - /** - * Constructor - * - * @param array $data - */ - public function __construct($data = array()) { - if(is_array($data)) $this->data = $data; - } - - /** - * Checks if the current key is set - * - * `isset($mycollection->mykey)` - * - * @param string $key the key to check - * @return boolean - */ - public function __isset($key) { - return isset($this->data[$key]); - } - - /** - * Removes an element from the array by key - * - * `unset($mycollection->mykey)` - * - * @param string $key the name of the key - */ - public function __unset($key) { - unset($this->data[$key]); - } - - /** - * Moves the cusor to the first element of the array - */ - public function rewind() { - reset($this->data); - } - - /** - * Returns the current element of the array - * - * @return mixed - */ - public function current() { - return current($this->data); - } - - /** - * Returns the current key from the array - * - * @return string - */ - public function key() { - return key($this->data); - } - - /** - * Moves the cursor to the previous element in the array - * and returns it - * - * @return mixed - */ - public function prev() { - return prev($this->data); - } - - /** - * Moves the cursor to the next element in the array - * and returns it - * - * @return mixed - */ - public function next() { - return next($this->data); - } - - /** - * Checks if an element is valid - * This is needed for the Iterator implementation - * - * @return boolean - */ - public function valid() { - return $this->current() !== false; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/l.php b/kirby/toolkit/lib/l.php deleted file mode 100644 index 7c607eb..0000000 --- a/kirby/toolkit/lib/l.php +++ /dev/null @@ -1,17 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class L extends Silo { - public static $data = array(); -} \ No newline at end of file diff --git a/kirby/toolkit/lib/media.php b/kirby/toolkit/lib/media.php deleted file mode 100644 index b5c4e9c..0000000 --- a/kirby/toolkit/lib/media.php +++ /dev/null @@ -1,639 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Media { - - // optional url where the file is reachable - public $url = null; - - // the full path for the file - protected $root = null; - - // the filename including the extension - protected $filename = null; - - // the name excluding the extension - protected $name = null; - - // the extension of the file - protected $extension = null; - - // the content of the file - protected $content = null; - - // cache for various data - protected $cache = array(); - - /** - * Constructor - * - * @param string $root - */ - public function __construct($root, $url = null) { - $this->url = $url; - $this->root = $root === null ? $root : realpath($root); - $this->filename = basename($root); - $this->name = pathinfo($root, PATHINFO_FILENAME); - $this->extension = strtolower(pathinfo($root, PATHINFO_EXTENSION)); - } - - /** - * Resets the internal cache - */ - public function reset() { - $this->cache = array(); - } - - /** - * Returns the full root of the asset - * - * @return string - */ - public function root() { - return $this->root; - } - - /** - * Returns the url - * - * @return string - */ - public function url() { - return $this->url; - } - - /** - * Returns a md5 hash of the root - */ - public function hash() { - return md5($this->root); - } - - /** - * Returns the parent directory path - * - * @return string - */ - public function dir() { - return dirname($this->root); - } - - /** - * Returns the filename of the file - * i.e. somefile.jpg - * - * @return string - */ - public function filename() { - return $this->filename; - } - - /** - * Returns the name of the file without extension - * - * @return string - */ - public function name() { - return $this->name; - } - - /** - * Returns the filename as safe name - * - * @return string - */ - public function safeName() { - return f::safeName($this->filename()); - } - - /** - * Returns the extension of the file - * i.e. jpg - * - * @return string - */ - public function extension() { - // return the current extension - return $this->extension; - } - - /** - * Reads the file content and parses it - * - * @param string $format - * @return mixed - */ - public function read($format = null) { - return str::parse($this->content(), $format); - } - - /** - * Setter and getter for the file content - * - * @param string $content - * @return string - */ - public function content($content = null, $format = null) { - - if(!is_null($content)) { - if(is_array($content)) { - switch($format) { - case 'json': - $content = json_encode($content); - break; - case 'yaml': - $content = yaml::encode($content); - break; - default: - $content = serialize($content); - break; - } - } else if(is_object($content)) { - $content = serialize($content); - } - return $this->content = $content; - } - - if(is_null($this->content)) { - $this->content = file_get_contents($this->root); - } - - return $this->content; - - } - - /** - * Saves the file - * - * @param string $content - * @return boolean - */ - public function save($content = null, $format = null) { - $content = $this->content($content, $format); - return f::write($this->root, $content); - } - - /** - * Alternative for save - * - * @param string $content - * @return boolean - */ - public function write($content = null, $format = null) { - return $this->save($content, $format); - } - - /** - * Change the file's modification date to now - * and create it with an empty content if it is not there yet - * - * @return boolean - */ - public function touch() { - return touch($this->root); - } - - /** - * Appends the content and saves the file - * - * @param string $content - * @return boolean - */ - public function append($content) { - $this->content = $this->content() . $content; - return $this->save(); - } - - /** - * Deletes the file - * - * @return boolean - */ - public function delete() { - return f::remove($this->root); - } - - /** - * Alternative for delete - * - * @return boolean - */ - public function remove() { - return f::remove($this->root); - } - - /** - * Moves the file to a new location - * - * @param string $to - * @return boolean - */ - public function move($to) { - if(!f::move($this->root, $to)) { - return false; - } else { - $this->root = $to; - return true; - } - } - - /** - * Copies the file to a new location - * - * @param string $to - * @return boolean - */ - public function copy($to) { - return f::copy($this->root, $to); - } - - /** - * Returns the file size as integer - * - * @return int - */ - public function size() { - return f::size($this->root); - } - - /** - * Returns the human readable version of the file size - * - * @return string - */ - public function niceSize() { - return f::niceSize($this->size()); - } - - /** - * Get the file's last modification time. - * - * @return int - */ - public function modified($format = null, $handler = 'date') { - return f::modified($this->root, $format, $handler); - } - - /** - * Returns the mime type of a file - * - * @return string - */ - public function mime() { - return f::mime($this->root); - } - - /** - * Categorize the file - * - * @return string - */ - public function type() { - return f::type($this->root); - } - - /** - * Checks if a file is of a certain type - * - * @param string $value An extension or mime type - * @return boolean - */ - public function is($value) { - return f::is($this->root, $value); - } - - /** - * Returns the file content as base64 encoded string - * - * @return string - */ - public function base64() { - return base64_encode($this->content()); - } - - /** - * Returns the file as data uri - * - * @return string - */ - public function dataUri() { - return 'data:' . $this->mime() . ';base64,' . $this->base64(); - } - - /** - * Checks if the file exists - * - * @return boolean - */ - public function exists() { - return file_exists($this->root); - } - - /** - * Checks if the file is writable - * - * @return boolean - */ - public function isWritable() { - return is_writable($this->root); - } - - /** - * Checks if the file is readable - * - * @return boolean - */ - public function isReadable() { - return is_readable($this->root); - } - - /** - * Checks if the file is executable - * - * @return boolean - */ - public function isExecutable() { - return is_executable($this->root); - } - - /** - * Sends an appropriate header for the asset - * - * @param boolean $send - * @return mixed - */ - public function header($send = true) { - return header::type($this->mime(), false, $send); - } - - /** - * Safely requires a file if it exists - * - * @param array $data Optional variables, which will be made available to the file - */ - public function load($data = array()) { - return f::load($this->root, $data); - } - - /** - * Read and send the file with the correct headers - */ - public function show() { - f::show($this->root); - } - - /* - * Automatically sends all needed headers for the file to be downloaded - * and echos the file's content - * - * @param string $filename Optional filename for the download - */ - public function download($filename = null) { - f::download($this->root, $filename); - } - - /** - * Returns the exif object for this file (if image) - * - * @return Exif - */ - public function exif() { - if(isset($this->cache['exif'])) return $this->cache['exif']; - return $this->cache['exif'] = new Exif($this); - } - - /** - * Returns the PHP imagesize array - * - * @return array - */ - public function imagesize() { - return (array)getimagesize($this->root); - } - - /** - * Returns the dimensions of the file if possible - * - * @return Dimensions - */ - public function dimensions() { - - if(isset($this->cache['dimensions'])) return $this->cache['dimensions']; - - if(in_array($this->mime(), array('image/jpeg', 'image/png', 'image/gif'))) { - $size = (array)getimagesize($this->root); - $width = a::get($size, 0, 0); - $height = a::get($size, 1, 0); - } else if($this->extension() == 'svg') { - $content = $this->read(); - $xml = simplexml_load_string($content); - $attr = $xml->attributes(); - $width = floatval($attr->width); - $height = floatval($attr->height); - if($width == 0 or $height == 0 and !empty($attr->viewBox)) { - $box = str::split($attr->viewBox, ' '); - $width = floatval(a::get($box, 2, 0)); - $height = floatval(a::get($box, 3, 0)); - } - } else { - $width = 0; - $height = 0; - } - - return $this->cache['dimensions'] = new Dimensions($width, $height); - - } - - /** - * Returns the width of the asset - * - * @return int - */ - public function width() { - return $this->dimensions()->width(); - } - - /** - * Returns the height of the asset - * - * @return int - */ - public function height() { - return $this->dimensions()->height(); - } - - /** - * Returns the ratio of the asset - * - * @return int - */ - public function ratio() { - return $this->dimensions()->ratio(); - } - - /** - * Checks if the dimensions of the asset are portrait - * - * @return boolean - */ - public function isPortrait() { - return $this->dimensions()->portrait(); - } - - /** - * Checks if the dimensions of the asset are landscape - * - * @return boolean - */ - public function isLandscape() { - return $this->dimensions()->landscape(); - } - - /** - * Checks if the dimensions of the asset are square - * - * @return boolean - */ - public function isSquare() { - return $this->dimensions()->square(); - } - - /** - * Returns the orientation as string - * landscape | portrait | square - * - * @return string - */ - public function orientation() { - return $this->dimensions()->orientation(); - } - - /** - * @param array $attr - * @return string - */ - public function html($attr = array()) { - - if($this->type() != 'image') return false; - - $img = new Brick('img'); - $img->attr('src', $this->url()); - $img->attr('alt', ' '); - - if(is_string($attr) || (is_object($attr) && method_exists($attr, '__toString'))) { - $img->attr('alt', (string)$attr); - } else if(is_array($attr)) { - $img->attr($attr); - } - - return $img; - - } - - /** - * Scales the image if possible - * - * @param int $width - * @param mixed $height - * @param mixed $quality - * @return Media - */ - public function resize($width, $height = null, $quality = null) { - - if($this->type() != 'image') return $this; - - $params = array('width' => $width); - - if($height) $params['height'] = $height; - if($quality) $params['quality'] = $quality; - - return new Thumb($this, $params); - - } - - /** - * Scales and crops the image if possible - * - * @param int $width - * @param mixed $height - * @param mixed $quality - * @return Media - */ - public function crop($width, $height = null, $quality = null) { - - if($this->type() != 'image') return $this; - - $params = array('width' => $width, 'crop' => true); - - if($height) $params['height'] = $height; - if($quality) $params['quality'] = $quality; - - return new Thumb($this, $params); - - } - - /** - * Converts the media object to a - * plain PHP array - * - * @param closure $callback - * @return array - */ - public function toArray($callback = null) { - - $data = array( - 'root' => $this->root(), - 'url' => $this->url(), - 'hash' => $this->hash(), - 'dir' => $this->dir(), - 'filename' => $this->filename(), - 'name' => $this->name(), - 'safeName' => $this->safeName(), - 'extension' => $this->extension(), - 'size' => $this->size(), - 'niceSize' => $this->niceSize(), - 'modified' => $this->modified(), - 'mime' => $this->mime(), - 'type' => $this->type(), - 'dimensions' => $this->dimensions()->toArray() - ); - - - if(is_null($callback)) { - return $data; - } else { - return array_map($callback, $data); - } - - } - - /** - * Converts the entire file array into - * a json string - * - * @param closure $callback Filter callback - * @return string - */ - public function toJson($callback = null) { - return json_encode($this->toArray($callback)); - } - - /** - * Returns a full link to this file - * Perfect for debugging in connection with echo - * - * @return string - */ - public function __toString() { - return $this->root; - } - -} diff --git a/kirby/toolkit/lib/obj.php b/kirby/toolkit/lib/obj.php deleted file mode 100644 index 2ed253c..0000000 --- a/kirby/toolkit/lib/obj.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Obj extends stdClass { - - public function __construct($data = array()) { - foreach($data as $key => $val) { - $this->{$key} = $val; - } - } - - public function __call($method, $arguments) { - return isset($this->$method) ? $this->$method : null; - } - - public function set($key, $value) { - $this->$key = $value; - } - - public function get($key, $default = null) { - return isset($this->$key) ? $this->$key : $default; - } - - public function toArray() { - return (array)$this; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/pagination.php b/kirby/toolkit/lib/pagination.php deleted file mode 100644 index be94b2f..0000000 --- a/kirby/toolkit/lib/pagination.php +++ /dev/null @@ -1,417 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Pagination { - - // configuration - public static $defaults = array( - 'variable' => 'page', - 'method' => 'param', - 'omitFirstPage' => true, - 'page' => false, - 'url' => null, - 'redirect' => false, - ); - - // options - protected $options = array(); - - // the current page - protected $page = null; - - // total count of items - protected $count = 0; - - // the number of displayed rows - protected $limit = 0; - - // the total number of pages - protected $pages = 0; - - // the offset for the slice function - protected $offset = 0; - - // the range start for ranged pagination - protected $rangeStart = 0; - - // the range end for ranged pagination - protected $rangeEnd = 0; - - /** - * Constructor - * - * @param mixed $count Either an integer or a Collection - * @param int $limit The number of items per page - * @param array $params Additional parameters to control the pagination object - */ - public function __construct($count, $limit, $params = array()) { - - // You can still pass an entire collection - if($count instanceof Collection) { - $count = $count->count(); - } - - $this->options = array_merge(static::$defaults, $params); - $this->count = (int)$count; - $this->limit = (int)$limit; - $this->pages = (int)ceil($this->count / $this->limit); - $this->offset = (int)(($this->page()-1) * $this->limit); - - } - - /** - * Returns the current page number - * - * @return int - */ - public function page() { - - if(!is_null($this->page)) return $this->page; - - if($this->options['page']) { - $this->page = $this->options['page']; - } else { - $this->page = ($this->options['method'] == 'query') ? get($this->options['variable']) : param($this->options['variable']); - } - - // make sure the page is an int - $this->page = intval($this->page); - - // set the first page correctly - if($this->page == 0) { - $this->page = 1; - } - - // sanitize the page if too low - if($this->page < 1) { - $this->redirect(); - $this->page = 1; - } - - // sanitize the page if too high - if($this->page > $this->pages && $this->count > 0) { - $this->redirect(); - $this->page = $this->lastPage(); - } - - // return the sanitized page number - return $this->page; - - } - - /** - * Redirects to an error page if the redirect option is set - * and the pagination is beyond the allowed boundaries - */ - public function redirect() { - if($redirect = $this->options['redirect']) { - go($redirect); - } - } - - /** - * Returns the total number of pages - * - * @return int - */ - public function countPages() { - return $this->pages; - } - - /** - * Alternative for countPages() - * - * @return int - */ - public function pages() { - return $this->pages; - } - - /** - * Returns the current offset - * This is used for the slice() method together with - * the limit to get the correct items from collections - * - * @return int - */ - public function offset() { - return $this->offset; - } - - /** - * Returns the chosen limit - * This is used for the slice() method together with - * the offset to get the correct items from collections - * - * @return int - */ - public function limit() { - return $this->limit; - } - - /** - * Checks if multiple pages are needed - * or if the collection can be displayed on a single page - * - * @return boolean - */ - public function hasPages() { - return $this->countPages() > 1; - } - - /** - * Returns the total number of items in the collection - * - * @return int - */ - public function countItems() { - return $this->count; - } - - /** - * Alternative for countItems() - * - * @return int - */ - public function items() { - return $this->count; - } - - /** - * Returns a page url for any given page number - * - * @param int $page The page number - * @return string The url - */ - public function pageURL($page) { - - if($this->options['method'] == 'query') { - - $query = url::query($this->options['url']); - - if($page == 1 && $this->options['omitFirstPage']) { - unset($query[$this->options['variable']]); - } else { - $query[$this->options['variable']] = $page; - } - - return url::build(array('query' => $query), $this->options['url']); - - } else { - - $params = url::params($this->options['url']); - - if($page == 1 && $this->options['omitFirstPage']) { - unset($params[$this->options['variable']]); - } else { - $params[$this->options['variable']] = $page; - } - - return url::build(array('params' => $params), $this->options['url']); - - } - - } - - /** - * Returns the number of the first page - * - * @return int - */ - public function firstPage() { - return 1; - } - - /** - * Checks if the current page is the first page - * - * @return boolean - */ - public function isFirstPage() { - return ($this->page == $this->firstPage()) ? true : false; - } - - /** - * Returns the url for the first page - * - * @return string - */ - public function firstPageURL() { - return $this->pageURL(1); - } - - /** - * Returns the number of the last page - * - * @return int - */ - public function lastPage() { - return $this->pages; - } - - /** - * Checks if the current page is the last page - * - * @return boolean - */ - public function isLastPage() { - return $this->page == $this->lastPage(); - } - - /** - * Returns the url for the last page - * - * @return string - */ - public function lastPageURL() { - return $this->pageURL($this->lastPage()); - } - - /** - * Returns the number of the previous page - * - * @return int - */ - public function prevPage() { - return $this->hasPrevPage() ? $this->page-1 : $this->page; - } - - /** - * Returns the url for the previous page - * - * @return string - */ - public function prevPageURL() { - return $this->pageURL($this->prevPage()); - } - - /** - * Checks if there's a previous page - * - * @return boolean - */ - public function hasPrevPage() { - return $this->page > 1; - } - - /** - * Returns the number of the next page - * - * @return int - */ - public function nextPage() { - return $this->hasNextPage() ? $this->page+1 : $this->page; - } - - /** - * Returns the url for the next page - * - * @return string - */ - public function nextPageURL() { - return $this->pageURL($this->nextPage()); - } - - /** - * Checks if there's a next page - * - * @return boolean - */ - public function hasNextPage() { - return $this->page < $this->pages; - } - - /** - * Returns the index number of the first item on the current page - * Can be used to display something like - * "Currently showing 1 - 10 of 123 items" - * - * @return int - */ - public function numStart() { - return $this->offset+1; - } - - /** - * Returns the index number of the last item on the current page - * Can be used to display something like - * "Currently showing 1 - 10 of 123 items" - * - * @return int - */ - public function numEnd() { - $end = $this->offset+$this->limit; - if($end > $this->items()) $end = $this->items(); - return $end; - } - - /** - * Creates a range of page numbers for Google-like pagination - * - * @return array - */ - public function range($range=5) { - - if($this->countPages() <= $range) { - $this->rangeStart = 1; - $this->rangeEnd = $this->countPages(); - return range($this->rangeStart, $this->rangeEnd); - } - - $this->rangeStart = $this->page - (int)floor($range/2); - $this->rangeEnd = $this->page + (int)floor($range/2); - - if($this->rangeStart <= 0) { - $this->rangeEnd += abs($this->rangeStart)+1; - $this->rangeStart = 1; - } - - if($this->rangeEnd > $this->countPages()) { - $this->rangeStart -= $this->rangeEnd-$this->countPages(); - $this->rangeEnd = $this->countPages(); - } - - return range($this->rangeStart,$this->rangeEnd); - - } - - /** - * Returns the first page of the created range - * - * @return int - */ - public function rangeStart() { - return $this->rangeStart; - } - - /** - * Returns the last page of the created range - * - * @return int - */ - public function rangeEnd() { - return $this->rangeEnd; - } - - /** - * Returns the most important pagination data into a readable array - * - * @return array - */ - public function toArray() { - return array( - 'page' => $this->page(), - 'pages' => $this->pages(), - 'items' => $this->countItems(), - ); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/password.php b/kirby/toolkit/lib/password.php deleted file mode 100644 index 2fd1bb0..0000000 --- a/kirby/toolkit/lib/password.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Password { - - /** - * Generates a salted hash for a plaintext password - * - * @param string $plaintext - * @return string - */ - public static function hash($plaintext) { - $salt = substr(str_replace('+', '.', base64_encode(sha1(str::random(), true))), 0, 22); - return crypt($plaintext, '$2a$10$' . $salt); - } - - /** - * Checks if a given string is already a hash - * - * @param string - * @return boolean - */ - public static function isHash($hash) { - return preg_match('!^\$2a\$10\$!', $hash); - } - - /** - * Checks if a password matches the encrypted hash - * - * @param string $plaintext - * @param string $hash - * @return boolean - */ - public static function match($plaintext, $hash) { - return crypt($plaintext, $hash) === $hash; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/r.php b/kirby/toolkit/lib/r.php deleted file mode 100644 index f5e4c9b..0000000 --- a/kirby/toolkit/lib/r.php +++ /dev/null @@ -1,346 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class R { - - // Stores the raw request data - protected static $raw = null; - - // Stores all sanitized request data - protected static $data = null; - - // the request body - protected static $body = null; - - /** - * Returns the raw request data - * - * @return array - */ - public static function raw() { - if(!is_null(static::$raw)) return static::$raw; - return static::$raw = array_merge($_GET, $_POST); - } - - /** - * Returns either the entire data array or parts of it - * - * - * - * echo r::data('username'); - * // sample output 'bastian' - * - * echo r::data('username', 'peter'); - * // if no username is found in the request peter will be echoed - * - * - * - * @param string $key An optional key to receive only parts of the data array - * @param mixed $default A default value, which will be returned if nothing can be found for a given key - * @param mixed - */ - public static function data($key = null, $default = null) { - - if(is_null(static::$data)) { - static::$data = static::sanitize(static::raw()); - - if(!static::is('GET')) { - $body = static::body(); - parse_str($body, $parsed); - - if(!is_array($parsed)) { - $parsed = json_decode($body, false); - if(!is_array($parsed)) $parsed = array(); - } - - static::$data = array_merge($parsed, static::$data); - - } - - } - - if(is_null($key)) { - return static::$data; - } else if(isset(static::$data[$key])) { - return static::$data[$key]; - } else { - return $default; - } - - } - - /** - * Only returns get data - * - * @return array - */ - public static function getData($key = null, $default = null) { - return a::get((array)static::sanitize($_GET), $key, $default); - } - - /** - * Only returns post data - * - * @return array - */ - public static function postData($key = null, $default = null) { - return a::get((array)static::sanitize($_POST), $key, $default); - } - - /** - * Private method to sanitize incoming request data - * - * @param array $data - * @return array - */ - protected static function sanitize($data) { - - if(!is_array($data)) { - return trim(str::stripslashes($data)); - } - - foreach($data as $key => $value) { - $data[$key] = static::sanitize($value); - } - - return $data; - - } - - /** - * Sets or overwrites a variable in the data array - * - * - * - * r::set('username', 'bastian'); - * - * dump($request); - * - * // sample output: array( - * // 'username' => 'bastian' - * // ... other stuff from the request - * // ); - * - * - * - * @param mixed $key The key to set/replace. Use an array to set multiple values at once - * @param mixed $value The value - * @return array - */ - public static function set($key, $value = null) { - - // set multiple values at once - if(is_array($key)) { - foreach($key as $k => $v) static::set($k, $v); - // return this for chaining - return; - } - - // make sure the data array is actually an array - if(is_null(static::$data)) static::$data = array(); - - // sanitize the - static::$data[$key] = static::sanitize($value); - - // return the new data array - return static::$data; - - } - - /** - * Alternative for r::data($key, $default) - * - * - * - * echo r::get('username'); - * // sample output 'bastian' - * - * echo r::get('username', 'peter'); - * // if no username is found in the request peter will be echoed - * - * - * - * @param string $key An optional key to receive only parts of the data array - * @param mixed $default A default value, which will be returned if nothing can be found for a given key - * @param mixed - */ - public static function get($key = null, $default = null) { - return static::data($key, $default); - } - - /** - * Removes a variable from the request array - * - * @param string $key - */ - public static function remove($key) { - unset(static::$data[$key]); - } - - /** - * Returns the current request method - * - * @return string POST, GET, DELETE, PUT, HEAD, PATCH, etc. - */ - public static function method() { - return isset($_SERVER['REQUEST_METHOD']) ? strtoupper($_SERVER['REQUEST_METHOD']) : 'GET'; - } - - /** - * Returns the request body from POST requests for example - * - * @return mixed - */ - public static function body() { - if(!is_null(static::$body)) return static::$body; - return static::$body = file_get_contents('php://input'); - } - - /** - * Returns the files array - * - * @param string $key An optional key to receive only parts of the files array - * @param mixed $default A default value, which will be returned if nothing can be found for a given key - * @return array - */ - public static function files($key = null, $default = null) { - return a::get($_FILES, $key, $default); - } - - /** - * Checks if the request is of a specific type: - * - * - GET - * - POST - * - PUT - * - PATCH - * - DELETE - * - AJAX - * - * @return boolean - */ - public static function is($method) { - if($method == 'ajax') { - return static::ajax(); - } else { - return strtoupper($method) == static::method() ? true : false; - } - } - - /** - * Checks for a specific key in the data array - * - * @return boolean - */ - public static function has($key) { - $data = static::data(); - return isset($data[$key]); - } - - /** - * Returns the referer if available - * - * - * - * echo r::referer(); - * // sample result: http://someurl.com - * - * - * - * @param string $default Pass an optional URL to use as default referer if no referer is being found - * @return string - */ - public static function referer($default = null) { - return a::get($_SERVER, 'HTTP_REFERER', $default); - } - - /** - * Nobody remembers how to spell it - * so this is a shortcut - * - * - * - * echo $request->referrer(); - * // sample result: http://someurl.com - * - * - * - * @param string $default Pass an optional URL to use as default referer if no referer is being found - * @return string - */ - public static function referrer($default = null) { - return static::referer($default); - } - - /** - * Returns the IP address from the - * request user if available - * - * @param mixed - */ - public static function ip() { - return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : false; - } - - /** - * Checks if the request has been made from the command line - * - * @return boolean - */ - public static function cli() { - return defined('STDIN') || (substr(PHP_SAPI, 0, 3) == 'cgi' && $term = getenv('TERM') && $term !== 'unknown'); - } - - /** - * Checks if the request is an AJAX request - * - * - * - * if($request->ajax()) echo 'ajax rulez'; - * - * - * - * @return boolean - */ - public static function ajax() { - return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'); - } - - /** - * Returns the request scheme - * - * @return string - */ - public static function scheme() { - return url::scheme(); - } - - /** - * Checks if the request is encrypted - * - * @return boolean - */ - public static function ssl() { - return static::scheme() == 'https'; - } - - /** - * Alternative for r::ssl() - * - * @return boolean - */ - public static function secure() { - return static::ssl(); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/redirect.php b/kirby/toolkit/lib/redirect.php deleted file mode 100644 index 6a43ebd..0000000 --- a/kirby/toolkit/lib/redirect.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Redirect { - - /** - * Redirects the user to a new URL - * - * @param string $url The URL to redirect to - * @param boolean $code The HTTP status code, which should be sent (301, 302 or 303) - * @param boolean $send If true, headers will be sent and redirection will take effect - */ - public static function send($url = false, $code = false, $send = true) { - return header::redirect($url, $code, $send); - } - - /** - * Redirects to a specific URL. You can pass either a normal URI - * a controller path or simply nothing (which redirects home) - */ - public static function to() { - static::send(call_user_func_array(array('url', 'to'), func_get_args())); - } - - /** - * Redirects to the home page of the app - */ - public static function home() { - static::send(url::home()); - } - - /** - * Redirects to the last location of the user - * - * @param string $fallback - */ - public static function back($fallback = null) { - // get the last url - $last = url::last(); - // make sure there's a proper fallback - if(empty($last)) $last = $fallback ? $fallback : url::home(); - static::send($last); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/remote.php b/kirby/toolkit/lib/remote.php deleted file mode 100644 index aeae2cd..0000000 --- a/kirby/toolkit/lib/remote.php +++ /dev/null @@ -1,327 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Remote { - - // configuration - public static $defaults = array( - 'method' => 'GET', - 'data' => array(), - 'file' => null, - 'timeout' => 10, - 'headers' => array(), - 'encoding' => 'utf-8', - 'agent' => null, - 'body' => true, - ); - - // store for the response object - protected $response = null; - - // all options for the request - protected $options = array(); - - // all received headers - protected $headers = array(); - - /** - * Constructor - * - * @param string $url - * @param array $options - */ - public function __construct($url, $options = array()) { - - // set all options - $this->options = array_merge(static::$defaults, $options); - - // add the url - $this->options['url'] = $url; - - // send the request - $this->send(); - - } - - /** - * Sets up all curl options and sends the request - * - * @return object Response - */ - protected function send() { - - // start a curl request - $curl = curl_init(); - - // curl options - $params = array( - CURLOPT_URL => $this->options['url'], - CURLOPT_ENCODING => $this->options['encoding'], - CURLOPT_CONNECTTIMEOUT => $this->options['timeout'], - CURLOPT_TIMEOUT => $this->options['timeout'], - CURLOPT_AUTOREFERER => true, - CURLOPT_RETURNTRANSFER => $this->options['body'], - CURLOPT_FOLLOWLOCATION => true, - CURLOPT_MAXREDIRS => 10, - CURLOPT_SSL_VERIFYPEER => false, - CURLOPT_HEADER => false, - CURLOPT_HEADERFUNCTION => array($this, 'header'), - ); - - // add all headers - if(!empty($this->options['headers'])) $params[CURLOPT_HTTPHEADER] = $this->options['headers']; - - // add the user agent - if(!empty($this->options['agent'])) $params[CURLOPT_USERAGENT] = $this->options['agent']; - - // do some request specific stuff - switch(strtolower($this->options['method'])) { - case 'post': - $params[CURLOPT_POST] = true; - $params[CURLOPT_POSTFIELDS] = $this->postfields($this->options['data']); - break; - case 'put': - - $params[CURLOPT_CUSTOMREQUEST] = 'PUT'; - $params[CURLOPT_POSTFIELDS] = $this->postfields($this->options['data']); - - // put a file - if($this->options['file']) { - $params[CURLOPT_INFILE] = fopen($this->options['file'], 'r'); - $params[CURLOPT_INFILESIZE] = f::size($this->options['file']); - } - - break; - case 'delete': - $params[CURLOPT_CUSTOMREQUEST] = 'DELETE'; - $params[CURLOPT_POSTFIELDS] = $this->postfields($this->options['data']); - break; - case 'head': - $params[CURLOPT_CUSTOMREQUEST] = 'HEAD'; - $params[CURLOPT_POSTFIELDS] = $this->postfields($this->options['data']); - $params[CURLOPT_NOBODY] = true; - break; - } - - curl_setopt_array($curl, $params); - - $content = curl_exec($curl); - $error = curl_errno($curl); - $message = curl_error($curl); - $info = curl_getinfo($curl); - - curl_close($curl); - - $this->response = new RemoteResponse(); - $this->response->headers = $this->headers; - $this->response->error = $error; - $this->response->message = $message; - $this->response->content = $content; - $this->response->code = $info['http_code']; - $this->response->info = $info; - - return $this->response; - - } - - /** - * Used by curl to parse incoming headers - * - * @param object $curl the curl connection - * @param string $header the header line - * @return int the length of the heade - */ - protected function header($curl, $header) { - - $parts = str::split($header, ':'); - - if(!empty($parts[0]) && !empty($parts[1])) { - $this->headers[$parts[0]] = $parts[1]; - } - - return strlen($header); - - } - - /** - * Returns all options which have been - * set for the current request - * - * @return array - */ - public function options() { - return $this->options; - } - - /** - * Returns the response object for - * the current request - * - * @return object Response - */ - public function response() { - return $this->response; - } - - /** - * Static method to init this class and send a request - * - * @param string $url - * @param array $params - * @return object Response - */ - public static function request($url, $params = array()) { - $request = new self($url, $params); - return $request->response(); - } - - /** - * Static method to send a GET request - * - * @param string $url - * @param array $params - * @return object Response - */ - public static function get($url, $params = array()) { - - $defaults = array( - 'method' => 'GET', - 'data' => array(), - ); - - $options = array_merge($defaults, $params); - $query = http_build_query($options['data']); - - if(!empty($query)) { - $url = (url::hasQuery($url)) ? $url . '&' . $query : $url . '?' . $query; - } - - // remove the data array from the options - unset($options['data']); - - $request = new self($url, $options); - return $request->response(); - - } - - /** - * Static method to send a POST request - * - * @param string $url - * @param array $params - * @return object Response - */ - public static function post($url, $params = array()) { - - $defaults = array( - 'method' => 'POST' - ); - - $request = new self($url, array_merge($defaults, $params)); - return $request->response(); - - } - - /** - * Static method to send a PUT request - * - * @param string $url - * @param array $params - * @return object Response - */ - public static function put($url, $params = array()) { - - $defaults = array( - 'method' => 'PUT' - ); - - $request = new self($url, array_merge($defaults, $params)); - return $request->response(); - - } - - /** - * Static method to send a DELETE request - * - * @param string $url - * @param array $params - * @return object Response - */ - public static function delete($url, $params = array()) { - - $defaults = array( - 'method' => 'DELETE' - ); - - $request = new self($url, array_merge($defaults, $params)); - return $request->response(); - - } - - /** - * Static method to send a HEAD request - * - * @param string $url - * @param array $params - * @return object Response - */ - public static function head($url, $params = array()) { - - $defaults = array( - 'method' => 'HEAD' - ); - - $request = new self($url, array_merge($defaults, $params)); - return $request->response(); - - } - - /** - * Static method to send a HEAD request - * which only returns an array of headers - * - * @param string $url - * @param array $params - * @return array - */ - public static function headers($url, $params = array()) { - $request = static::head($url, $params); - return array_merge($request->headers(), $request->info()); - } - - /** - * Internal method to handle post field data - * - * @param mixed $data - * @return mixed - */ - protected function postfields($data) { - - if(is_object($data) || is_array($data)) { - return http_build_query($data); - } else { - return $data; - } - - } - -} - -class RemoteResponse extends Obj { - - public function __toString() { - return (string)$this->content; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/response.php b/kirby/toolkit/lib/response.php deleted file mode 100644 index 8ffca3d..0000000 --- a/kirby/toolkit/lib/response.php +++ /dev/null @@ -1,142 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Response { - - // the response content - protected $content; - - // the format type - protected $format; - - // the HTTP code - protected $code; - - /** - * Constructor - * - * @param string $content - * @param string $format - * @param int $code Optional HTTP code - */ - public function __construct($content, $format = 'html', $code = 200) { - - $this->content = $content; - $this->format = strtolower($format); - $this->code = $code; - - // convert arrays to json - if(is_array($this->content) && $this->format == 'json') { - - if(defined('JSON_PRETTY_PRINT') && get('pretty')) { - $this->content = json_encode($this->content, JSON_PRETTY_PRINT); - } else { - $this->content = json_encode($this->content); - } - - } - - } - - /** - * Sends the correct header for the response - * - * @param boolean $send If set to false, the header will be returned - * @return mixed - */ - public function header($send = true) { - - $status = header::status($this->code, false); - $type = header::type($this->format, 'utf-8', false); - - if(!$send) return $status . PHP_EOL . $type; - - header($status); - header($type); - - } - - /** - * Returns the content of this response - * - * @return string - */ - public function content() { - return $this->content; - } - - /** - * Returns the content format - * - * @return string - */ - public function format() { - return $this->format; - } - - /** - * Returns a success response - * - * @param string $message - * @param mixed $data - * @param mixed $code - * @return object - */ - static public function success($message = 'Everything went fine', $data = array(), $code = 200) { - return new static(array( - 'status' => 'success', - 'code' => $code, - 'message' => $message, - 'data' => $data - ), 'json', $code); - } - - /** - * Returns an error response - * - * @param mixed $message Either a message string or an error or errors object - * @param mixed $code - * @param mixed $data - * @return object - */ - static public function error($message = 'Something went wrong', $code = 400, $data = array()) { - return new static(array( - 'status' => 'error', - 'code' => $code, - 'message' => $message, - 'data' => $data - ), 'json', $code); - } - - /** - * Converts an array to json and returns it properly - * - * @param array $data - * @return object - */ - static public function json($data, $code = 200) { - return new static($data, 'json', $code); - } - - /** - * Echos the content - * and sends the appropriate header - * - * @return string - */ - public function __toString() { - $this->header(); - return (string)$this->content; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/router.php b/kirby/toolkit/lib/router.php deleted file mode 100644 index a286a2e..0000000 --- a/kirby/toolkit/lib/router.php +++ /dev/null @@ -1,284 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Router { - - // request instance - protected $request = null; - - // the matched route if found - protected $route = null; - - // all registered routes - protected $routes = array( - 'GET' => array(), - 'POST' => array(), - 'HEAD' => array(), - 'PUT' => array(), - 'PATCH' => array(), - 'DELETE' => array() - ); - - // The wildcard patterns supported by the router. - protected $patterns = array( - '(:num)' => '([0-9]+)', - '(:alpha)' => '([a-zA-Z]+)', - '(:any)' => '([a-zA-Z0-9\.\-_%=]+)', - '(:all)' => '(.*)', - ); - - // The optional wildcard patterns supported by the router. - protected $optional = array( - '/(:num?)' => '(?:/([0-9]+)', - '/(:alpha?)' => '(?:/([a-zA-Z]+)', - '/(:any?)' => '(?:/([a-zA-Z0-9\.\-_%=]+)', - '/(:all?)' => '(?:/(.*)', - ); - - // additional events, which can be triggered by routes - protected $filters = array(); - - /** - * Constructor - * - * @param array $routes - */ - public function __construct($routes = array()) { - $this->register($routes); - } - - /** - * Returns the found route - * - * @return mixed - */ - public function route() { - return $this->route; - } - - /** - * Returns the arguments array from the current route - * - * @return array - */ - public function arguments() { - if($route = $this->route()) return $route->arguments(); - } - - /** - * Adds a new route - * - * @param mixed $pattern - * @param mixed $params - * @param mixed $optional - * @return Obj - */ - public function register($pattern, $params = array(), $optional = array()) { - - if($pattern === false) { - return false; - } else if(is_array($pattern)) { - foreach($pattern as $v) { - if($v === false || empty($v['pattern'])) { - continue; - } else if(is_array($v['pattern'])) { - foreach($v['pattern'] as $p) { - $v['pattern'] = $p; - $this->register($p, $v); - } - } else { - $this->register($v['pattern'], $v); - } - } - return $this; - } - - $defaults = array( - 'pattern' => $pattern, - 'https' => false, - 'ajax' => false, - 'filter' => null, - 'method' => 'GET', - 'arguments' => array(), - ); - - $route = new Obj(array_merge($defaults, $params, $optional)); - - // convert single methods or methods separated by | to arrays - if(is_string($route->method)) { - - if(strpos($route->method, '|') !== false) { - $route->method = str::split($route->method, '|'); - } else if($route->method == 'ALL') { - $route->method = array_keys($this->routes); - } else { - $route->method = array($route->method); - } - - } - - if(is_string($route->filter)) { - if(strpos($route->filter, '|') !== false) { - $route->filter = str::split($route->filter, '|'); - } else { - $route->filter = array($route->filter); - } - } - - foreach($route->method as $method) { - $this->routes[strtoupper($method)][$route->pattern] = $route; - } - - return $route; - - } - - /** - * Add a new router filter - * - * @param string $name A simple name for the filter, which can be used by routes later - * @param closure $function A filter function, which should be called before routes - */ - public function filter($name, $function) { - $this->filters[$name] = $function; - } - - /** - * Return all registered filters - * - * @return array - */ - public function filters() { - return $this->filters; - } - - /** - * Call all matching filters - * - * @param mixed $filters - */ - protected function filterer($filters) { - foreach((array)$filters as $filter) { - if(array_key_exists($filter, $this->filters) && is_callable($this->filters[$filter])) { - call_user_func($this->filters[$filter]); - } - } - } - - /** - * Returns all added routes - * - * @param string $method - * @return array - */ - public function routes($method = null) { - return is_null($method) ? $this->routes : $this->routes[strtoupper($method)]; - } - - /** - * Iterate through every route to find a matching route. - * - * @param string $path Optional path to match against - * @return Route - */ - public function run($path = null) { - - $method = r::method(); - $ajax = r::ajax(); - $https = r::ssl(); - $routes = a::get($this->routes, $method, array()); - - // detect path if not set manually - if($path === null) $path = implode('/', (array)url::fragments(detect::path())); - - // empty urls should never happen - if(empty($path)) $path = '/'; - - foreach($routes as $route) { - - if($route->https && !$https) continue; - if($route->ajax && !$ajax) continue; - - // handle exact matches - if($route->pattern == $path) { - $this->route = $route; - break; - } - - // We only need to check routes with regular expression since all others - // would have been able to be matched by the search for literal matches - // we just did before we started searching. - if(strpos($route->pattern, '(') === false) continue; - - $preg = '#^'. $this->wildcards($route->pattern) . '$#u'; - - // If we get a match we'll return the route and slice off the first - // parameter match, as preg_match sets the first array item to the - // full-text match of the pattern. - if(preg_match($preg, $path, $parameters)) { - $this->route = $route; - $this->route->arguments = array_slice($parameters, 1); - break; - } - - } - - if($this->route && $this->filterer($this->route->filter) !== false) { - return $this->route; - } else { - return null; - } - - } - - /** - * Translate route URI wildcards into regular expressions. - * - * @param string $pattern - * @return string - */ - protected function wildcards($pattern) { - - $search = array_keys($this->optional); - $replace = array_values($this->optional); - - // For optional parameters, first translate the wildcards to their - // regex equivalent, sans the ")?" ending. We'll add the endings - // back on when we know the replacement count. - $pattern = str_replace($search, $replace, $pattern, $count); - - if($count > 0) $pattern .= str_repeat(')?', $count); - - return strtr($pattern, $this->patterns); - - } - - /** - * Find a registered route by a field and value - * - * @param string $field - * @param string $value - * @return object - */ - public function findRouteBy($field, $value) { - foreach($this->routes as $method => $routes) { - foreach($routes as $route) { - if($route->$field() == $value) return $route; - } - } - } - -} diff --git a/kirby/toolkit/lib/s.php b/kirby/toolkit/lib/s.php deleted file mode 100644 index cac1749..0000000 --- a/kirby/toolkit/lib/s.php +++ /dev/null @@ -1,291 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class S { - - public static $started = false; - public static $name = 'kirby_session'; - public static $timeout = 30; - public static $cookie = array(); - - /** - * Starts a new session - * - * - * - * s::start(); - * // do whatever you want with the session now - * - * - * - */ - public static function start() { - - if(session_status() === PHP_SESSION_ACTIVE) return true; - - // store the session name - static::$cookie += array( - 'lifetime' => 0, - 'path' => ini_get('session.cookie_path'), - 'domain' => ini_get('session.cookie_domain'), - 'secure' => r::secure(), - 'httponly' => true - ); - - // set the custom session name - session_name(static::$name); - - // make sure to use cookies only - ini_set('session.use_cookies', 1); - ini_set('session.use_only_cookies', 1); - - // try to start the session - if(!session_start()) return false; - - if(!setcookie( - static::$name, - session_id(), - cookie::lifetime(static::$cookie['lifetime']), - static::$cookie['path'], - static::$cookie['domain'], - static::$cookie['secure'], - static::$cookie['httponly'] - )) { - return false; - } - - // mark it as started - static::$started = true; - - // check if the session is still valid - if(!static::check()) { - return static::destroy(); - } - - return true; - - } - - /** - * Checks if the session is still valid - * and not expired - * - * @return boolean - */ - public static function check() { - - // check for the last activity and compare it with the session timeout - if(isset($_SESSION['kirby_session_activity']) && time() - $_SESSION['kirby_session_activity'] > static::$timeout * 60) { - return false; - } - - // check for an existing fingerprint and compare it - if(isset($_SESSION['kirby_session_fingerprint']) and $_SESSION['kirby_session_fingerprint'] !== static::fingerprint()) { - return false; - } - - // store a new fingerprint and the last activity - $_SESSION['kirby_session_fingerprint'] = static::fingerprint(); - $_SESSION['kirby_session_activity'] = time(); - - return true; - - } - - /** - * Generates a fingerprint from the user agent string - * - * @return string - */ - public static function fingerprint() { - if(!r::cli()) { - return sha1(Visitor::ua() . (ip2long($_SERVER['REMOTE_ADDR']) & ip2long('255.255.0.0'))); - } else { - return ''; - } - } - - /** - * Returns the current session id - * - * @return string - */ - public static function id() { - static::start(); - return session_id(); - } - - /** - * Sets a session value by key - * - * - * - * s::set('username', 'bastian'); - * // saves the username in the session - * - * s::set(array( - * 'key1' => 'val1', - * 'key2' => 'val2', - * 'key3' => 'val3' - * )); - * // setting multiple variables at once - * - * - * - * @param mixed $key The key to define - * @param mixed $value The value for the passed key - */ - public static function set($key, $value = false) { - - static::start(); - - if(!isset($_SESSION)) return false; - if(is_array($key)) { - $_SESSION = array_merge($_SESSION, $key); - } else { - $_SESSION[$key] = $value; - } - - } - - /** - * Gets a session value by key - * - * - * - * s::get('username', 'bastian'); - * // saves the username in the session - * - * echo s::get('username'); - * // output: 'bastian' - * - * - * - * @param mixed $key The key to look for. Pass false or null to return the entire session array. - * @param mixed $default Optional default value, which should be returned if no element has been found - * @return mixed - */ - public static function get($key = false, $default = null) { - - static::start(static::$name, static::$timeout, static::$cookie); - - if(!isset($_SESSION)) return false; - if(empty($key)) return $_SESSION; - return isset($_SESSION[$key]) ? $_SESSION[$key] : $default; - - } - - /** - * Retrieves an item and removes it afterwards - * - * @param string $key - * @param mixed $default - * @return mixed - */ - public static function pull($key, $default = null) { - $value = s::get($key, $default); - s::remove($key); - return $value; - } - - /** - * Removes a value from the session by key - * - * - * - * $_SESSION = array( - * 'username' => 'bastian', - * 'id' => 1, - * ); - * - * s::remove('username'); - * // $_SESSION = array( - * // 'id' => 1 - * // ) - * - * - * - * @param mixed $key The key to remove by - * @return array The session array without the value - */ - public static function remove($key) { - - static::start(); - - unset($_SESSION[$key]); - return $_SESSION; - - } - - /** - * Checks if the session has already been started - * - * @return boolean - */ - public static function started() { - return static::$started; - } - - /** - * Destroys a session - * - * - * - * s::start(); - * // do whatever you want with the session now - * - * s::destroy(); - * // everything stored in the session will be deleted - * - * - * - */ - public static function destroy() { - - if(!static::$started) return false; - - $_SESSION = array(); - - cookie::remove(static::$name); - - static::$started = false; - - return session_destroy(); - - } - - /** - * Alternative for s::destroy() - */ - public static function stop() { - s::destroy(); - } - - /** - * Destroys a session first and then starts it again - */ - public static function restart() { - static::destroy(); - static::start(); - } - - /** - * Create a new session Id - */ - public static function regenerateId() { - static::start(static::$name, static::$timeout, static::$cookie); - session_regenerate_id(true); - } - -} diff --git a/kirby/toolkit/lib/server.php b/kirby/toolkit/lib/server.php deleted file mode 100644 index dca04fe..0000000 --- a/kirby/toolkit/lib/server.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Server { - - /** - * Gets a value from the _SERVER array - * - * - * - * server::get('document_root'); - * // sample output: /var/www/kirby - * - * server::get(); - * // returns the whole server array - * - * - * - * @param mixed $key The key to look for. Pass false or null to return the entire server array. - * @param mixed $default Optional default value, which should be returned if no element has been found - * @return mixed - */ - public static function get($key = false, $default = null) { - if(empty($key)) return $_SERVER; - $key = str::upper($key); - $value = a::get($_SERVER, $key, $default); - return static::sanitize($key, $value); - } - - public static function sanitize($key, $value) { - - switch($key) { - case 'SERVER_ADDR': - case 'SERVER_NAME': - case 'HTTP_HOST': - $value = strip_tags($value); - $value = preg_replace('![^\w.:-]+!iu', '', $value); - $value = trim($value, '-'); - $value = htmlspecialchars($value); - break; - case 'SERVER_PORT': - $value = preg_replace('![^0-9]+!', '', $value); - break; - } - - return $value; - - } - -} diff --git a/kirby/toolkit/lib/silo.php b/kirby/toolkit/lib/silo.php deleted file mode 100644 index ec8da16..0000000 --- a/kirby/toolkit/lib/silo.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Silo { - - public static $data = array(); - - public static function set($key, $value = null) { - if(is_array($key)) { - return static::$data = array_merge(static::$data, $key); - } else { - return static::$data[$key] = $value; - } - } - - public static function get($key = null, $default = null) { - if(empty($key)) return static::$data; - return isset(static::$data[$key]) ? static::$data[$key] : $default; - } - - public static function remove($key = null) { - // reset the entire array - if(is_null($key)) return static::$data = array(); - // unset a single key - unset(static::$data[$key]); - // return the array without the removed key - return static::$data; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/sql.php b/kirby/toolkit/lib/sql.php deleted file mode 100644 index 4c1af07..0000000 --- a/kirby/toolkit/lib/sql.php +++ /dev/null @@ -1,806 +0,0 @@ -, Lukas Bestle - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Sql { - - // list of literals which should not be escaped in queries - public static $literals = array('NOW()', null); - - // sql formatting methods, defined below - public static $methods = array(); - - // the parent database connection and database query - public $database; - public $dbquery; - - // list of bindings by sql query string that defines them - protected $bindings = array(); - - /** - * Constructor - * - * @param Database $database - * @param Database\Query $dbquery Database query that is used to set the bindings directly - */ - public function __construct($database, $dbquery = null) { - $this->database = $database; - $this->dbquery = $dbquery; - } - - /** - * Sets and returns query-specific bindings - * - * @param string $query SQL query string that contains the bindings - * @param array $values Array of bindings to set (null to get the bindings) - * @return array - */ - public function bindings($query, $values = null) { - if(is_null($values)) { - return a::get($this->bindings, $query, array()); - } else { - if(!is_null($query)) $this->bindings[$query] = $values; - - // directly register bindings if possible - if($this->dbquery) $this->dbquery->bindings($values); - } - } - - /** - * Calls an SQL method using the correct database type - * - * @param string $method - * @param array $arguments - * @return mixed - */ - public function __call($method, $arguments) { - $type = $this->database->type(); - - if(isset(static::$methods[$type][$method])) { - $method = static::$methods[$type][$method]; - } else { - // fallback to shared method - if(!isset(static::$methods['_shared'][$method])) { - throw new Error('SQL method ' . $method . ' is not defined for database type ' . $type); - } - - $method = static::$methods['_shared'][$method]; - } - - // pass the sql object as first argument - array_unshift($arguments, $this); - return call($method, $arguments); - } - - /** - * Registers a method for a specified database type - * The function must take this SQL object as first parameter and set bindings on it - * - * @param string $name - * @param callable $function - * @param string $type 'mysql', 'sqlite' or '_shared' - */ - public static function registerMethod($name, $function, $type = '_shared') { - if(!isset(static::$methods[$type])) static::$methods[$type] = array(); - static::$methods[$type][$name] = $function; - } - - /** - * Returns a randomly generated binding name - * - * @param string $label String that contains lowercase letters and numbers to use as a readable identifier - * @return string - */ - public static function generateBindingName($label) { - // make sure that the binding name is valid to prevent injections - if(!preg_match('/^[a-z0-9]+$/', $label)) $label = 'invalid'; - - return ':' . $label . '_' . uniqid(); - } - -} - -/** - * Builds a select clause - * - * @param array $params List of parameters for the select clause. Check out the defaults for more info. - * @return string - */ -sql::registerMethod('select', function($sql, $params = array()) { - - $defaults = array( - 'table' => '', - 'columns' => '*', - 'join' => false, - 'distinct' => false, - 'where' => false, - 'group' => false, - 'having' => false, - 'order' => false, - 'offset' => 0, - 'limit' => false, - ); - - $options = array_merge($defaults, $params); - $query = array(); - $bindings = array(); - - $query[] = 'SELECT'; - - // select distinct values - if($options['distinct']) $query[] = 'DISTINCT'; - - // validate table - if(!$sql->database->validateTable($options['table'])) throw new Error('Invalid table ' . $options['table']); - - // columns - if(empty($options['columns'])) { - $query[] = '*'; - } else if(is_array($options['columns'])) { - // validate columns - $columns = array(); - foreach($options['columns'] as $column) { - list($table, $columnPart) = $sql->splitIdentifier($options['table'], $column); - if(!$sql->database->validateColumn($table, $columnPart)) { - throw new Error('Invalid column ' . $column); - } - - $columns[] = $sql->combineIdentifier($table, $columnPart); - } - - $query[] = implode(', ', $columns); - } else { - $query[] = $options['columns']; - } - - // table - $query[] = 'FROM ' . $sql->quoteIdentifier($options['table']); - - // join - if(!empty($options['join'])) { - foreach($options['join'] as $join) { - $joinType = ltrim(strtoupper(a::get($join, 'type', '')) . ' JOIN'); - if(!in_array($joinType, array( - 'JOIN', 'INNER JOIN', - 'OUTER JOIN', - 'LEFT OUTER JOIN', 'LEFT JOIN', - 'RIGHT OUTER JOIN', 'RIGHT JOIN', - 'FULL OUTER JOIN', 'FULL JOIN', - 'NATURAL JOIN', - 'CROSS JOIN', - 'SELF JOIN' - ))) throw new Error('Invalid join type ' . $joinType); - - // validate table - if(!$sql->database->validateTable($join['table'])) throw new Error('Invalid table ' . $join['table']); - - // ON can't be escaped here - $query[] = $joinType . ' ' . $sql->quoteIdentifier($join['table']) . ' ON ' . $join['on']; - } - } - - // where - if(!empty($options['where'])) { - // WHERE can't be escaped here - $query[] = 'WHERE ' . $options['where']; - } - - // group - if(!empty($options['group'])) { - // GROUP BY can't be escaped here - $query[] = 'GROUP BY ' . $options['group']; - } - - // having - if(!empty($options['having'])) { - // HAVING can't be escaped here - $query[] = 'HAVING ' . $options['having']; - } - - // order - if(!empty($options['order'])) { - // ORDER BY can't be escaped here - $query[] = 'ORDER BY ' . $options['order']; - } - - // offset and limit - if($options['offset'] > 0 || $options['limit']) { - if(!$options['limit']) $options['limit'] = '18446744073709551615'; - - $offsetBinding = sql::generateBindingName('offset'); - $bindings[$offsetBinding] = $options['offset']; - $limitBinding = sql::generateBindingName('limit'); - $bindings[$limitBinding] = $options['limit']; - - $query[] = 'LIMIT ' . $offsetBinding . ', ' . $limitBinding; - } - - $query = implode(' ', $query); - - $sql->bindings($query, $bindings); - return $query; - -}); - -/** - * Builds an insert clause - * - * @param array $params List of parameters for the insert clause. See defaults for more info. - * @return string - */ -sql::registerMethod('insert', function($sql, $params = array()) { - - $defaults = array( - 'table' => '', - 'values' => false, - ); - - $options = array_merge($defaults, $params); - $query = array(); - $bindings = array(); - - // validate table - if(!$sql->database->validateTable($options['table'])) throw new Error('Invalid table ' . $options['table']); - - $query[] = 'INSERT INTO ' . $sql->quoteIdentifier($options['table']); - $query[] = $sql->values($options['table'], $options['values'], ', ', false); - - $query = implode(' ', $query); - - $sql->bindings($query, $bindings); - return $query; - -}); - -/** - * Builds an update clause - * - * @param array $params List of parameters for the update clause. See defaults for more info. - * @return string - */ -sql::registerMethod('update', function($sql, $params = array()) { - - $defaults = array( - 'table' => '', - 'values' => false, - 'where' => false, - ); - - $options = array_merge($defaults, $params); - $query = array(); - $bindings = array(); - - // validate table - if(!$sql->database->validateTable($options['table'])) throw new Error('Invalid table ' . $options['table']); - - $query[] = 'UPDATE ' . $sql->quoteIdentifier($options['table']) . ' SET'; - $query[] = $sql->values($options['table'], $options['values']); - - if(!empty($options['where'])) { - // WHERE can't be escaped here - $query[] = 'WHERE ' . $options['where']; - } - - $query = implode(' ', $query); - - $sql->bindings($query, $bindings); - return $query; - -}); - -/** - * Builds a delete clause - * - * @param array $params List of parameters for the delete clause. See defaults for more info. - * @return string - */ -sql::registerMethod('delete', function($sql, $params = array()) { - - $defaults = array( - 'table' => '', - 'where' => false, - ); - - $options = array_merge($defaults, $params); - $query = array(); - $bindings = array(); - - // validate table - if(!$sql->database->validateTable($options['table'])) throw new Error('Invalid table ' . $options['table']); - - $query[] = 'DELETE FROM ' . $sql->quoteIdentifier($options['table']); - - if(!empty($options['where'])) { - // WHERE can't be escaped here - $query[] = 'WHERE ' . $options['where']; - } - - $query = implode(' ', $query); - - $sql->bindings($query, $bindings); - return $query; - -}); - -/** - * Builds a safe list of values for insert, select or update queries - * - * @param string $table Table name - * @param mixed $values A value string or array of values - * @param string $separator A separator which should be used to join values - * @param boolean $set If true builds a set list of values for update clauses - * @param boolean $enforceQualified Always use fully qualified column names - * @return string - */ -sql::registerMethod('values', function($sql, $table, $values, $separator = ', ', $set = true, $enforceQualified = false) { - - if(!is_array($values)) return $values; - - if($set) { - - $output = array(); - $bindings = array(); - - foreach($values as $key => $value) { - // validate column - list($table, $column) = $sql->splitIdentifier($table, $key); - if(!$sql->database->validateColumn($table, $column)) { - throw new Error('Invalid column ' . $key); - } - $key = $sql->combineIdentifier($table, $column, $enforceQualified !== true); - - if(in_array($value, sql::$literals, true)) { - $output[] = $key . ' = ' . (($value === null)? 'null' : $value); - continue; - } elseif(is_array($value)) { - $value = json_encode($value); - } - - $valueBinding = sql::generateBindingName('value'); - $bindings[$valueBinding] = $value; - - $output[] = $key . ' = ' . $valueBinding; - } - - $sql->bindings(null, $bindings); - return implode($separator, $output); - - } else { - - $fields = array(); - $output = array(); - $bindings = array(); - - foreach($values as $key => $value) { - // validate column - list($table, $column) = $sql->splitIdentifier($table, $key); - if(!$sql->database->validateColumn($table, $column)) { - throw new Error('Invalid column ' . $key); - } - $key = $sql->combineIdentifier($table, $column, $enforceQualified !== true); - - $fields[] = $key; - - if(in_array($value, sql::$literals, true)) { - $output[] = ($value === null)? 'null' : $value; - continue; - } elseif(is_array($value)) { - $value = json_encode($value); - } - - $valueBinding = sql::generateBindingName('value'); - $bindings[$valueBinding] = $value; - - $output[] = $valueBinding; - } - - $sql->bindings(null, $bindings); - return '(' . implode($separator, $fields) . ') VALUES (' . implode($separator, $output) . ')'; - - } - -}); - -/** - * Creates the sql for dropping a single table - * - * @param string $table - * @return string - */ -sql::registerMethod('dropTable', function($sql, $table) { - - // validate table - if(!$sql->database->validateTable($table)) throw new Error('Invalid table ' . $table); - - return 'DROP TABLE ' . $sql->quoteIdentifier($table); - -}); - -/** - * Creates a table with a simple scheme array for columns - * MySQL version - * - * @todo add more options per column - * @param string $table The table name - * @param array $columns - * @return string - */ -sql::registerMethod('createTable', function($sql, $table, $columns = array()) { - - $output = array(); - $keys = array(); - $bindings = array(); - - foreach($columns as $name => $column) { - // column type - if(!isset($column['type'])) throw new Error('No column type given for column ' . $name); - switch($column['type']) { - case 'id': - $template = '{column.name} INT(11) UNSIGNED NOT NULL AUTO_INCREMENT'; - $column['key'] = 'PRIMARY'; - break; - case 'varchar': - $template = '{column.name} varchar(255) {column.null} {column.default}'; - break; - case 'text': - $template = '{column.name} TEXT'; - break; - case 'int': - $template = '{column.name} INT(11) UNSIGNED {column.null} {column.default}'; - break; - case 'timestamp': - $template = '{column.name} TIMESTAMP {column.null} {column.default}'; - break; - default: - throw new Error('Unsupported column type: ' . $column['type']); - } - - // null - if(a::get($column, 'null') === false) { - $null = 'NOT NULL'; - } else { - $null = 'NULL'; - } - - // indexes/keys - $key = false; - if(isset($column['key'])) { - $column['key'] = strtoupper($column['key']); - - // backwards compatibility - if($column['key'] === 'PRIMARY') $column['key'] = 'PRIMARY KEY'; - - if(in_array($column['key'], array('PRIMARY KEY', 'INDEX'))) { - $key = $column['key']; - $keys[$name] = $key; - } - } - - // default value - $defaultBinding = null; - if(isset($column['default'])) { - $defaultBinding = sql::generateBindingName('default'); - $bindings[$defaultBinding] = $column['default']; - } - - $output[] = trim(str::template($template, array( - 'column.name' => $sql->quoteIdentifier($name), - 'column.null' => $null, - 'column.default' => r(!is_null($defaultBinding), 'DEFAULT ' . $defaultBinding), - ))); - - } - - // combine columns - $inner = implode(',' . PHP_EOL, $output); - - // add keys - foreach($keys as $name => $key) { - $inner .= ',' . PHP_EOL . $key . ' (' . $sql->quoteIdentifier($name) . ')'; - } - - // make it a string - $query = 'CREATE TABLE ' . $sql->quoteIdentifier($table) . ' (' . PHP_EOL . $inner . PHP_EOL . ')'; - - $sql->bindings($query, $bindings); - return $query; - -}, 'mysql'); - -/** - * Creates a table with a simple scheme array for columns - * SQLite version - * - * @todo add more options per column - * @param string $table The table name - * @param array $columns - * @return string - */ -sql::registerMethod('createTable', function($sql, $table, $columns = array()) { - - $output = array(); - $keys = array(); - $bindings = array(); - - foreach($columns as $name => $column) { - // column type - if(!isset($column['type'])) throw new Error('No column type given for column ' . $name); - switch($column['type']) { - case 'id': - $template = '{column.name} INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE'; - break; - case 'varchar': - $template = '{column.name} TEXT {column.null} {column.key} {column.default}'; - break; - case 'text': - $template = '{column.name} TEXT {column.null} {column.key} {column.default}'; - break; - case 'int': - $template = '{column.name} INTEGER {column.null} {column.key} {column.default}'; - break; - case 'timestamp': - $template = '{column.name} INTEGER {column.null} {column.key} {column.default}'; - break; - default: - throw new Error('Unsupported column type: ' . $column['type']); - } - - // null - if(a::get($column, 'null') === false) { - $null = 'NOT NULL'; - } else { - $null = 'NULL'; - } - - // indexes/keys - $key = false; - if(isset($column['key'])) { - $column['key'] = strtoupper($column['key']); - - // backwards compatibility - if($column['key'] === 'PRIMARY') $column['key'] = 'PRIMARY KEY'; - - if(in_array($column['key'], array('PRIMARY KEY', 'INDEX'))) { - $key = $column['key']; - $keys[$name] = $key; - } - } - - // default value - $default = null; - if(isset($column['default'])) { - // Apparently SQLite doesn't support bindings for default values - $default = "'" . $sql->database->escape($column['default']) . "'"; - } - - $output[] = trim(str::template($template, array( - 'column.name' => $sql->quoteIdentifier($name), - 'column.null' => $null, - 'column.key' => r($key && $key != 'INDEX', $key), - 'column.default' => r(!is_null($default), 'DEFAULT ' . $default), - ))); - - } - - // combine columns - $inner = implode(',' . PHP_EOL, $output); - - // make it a string - $query = 'CREATE TABLE ' . $sql->quoteIdentifier($table) . ' (' . PHP_EOL . $inner . PHP_EOL . ')'; - - // set bindings for our first query - $sql->bindings($query, $bindings); - - // add index keys - foreach($keys as $name => $key) { - if($key != 'INDEX') continue; - - $indexQuery = 'CREATE INDEX ' . $sql->quoteIdentifier($table . '_' . $name) . ' ON ' . $sql->quoteIdentifier($table) . ' (' . $sql->quoteIdentifier($name) . ')'; - $query .= ';' . PHP_EOL . $indexQuery; - } - - return $query; - -}, 'sqlite'); - -/** - * Splits a (qualified) identifier into table and column - * - * @param $table string Default table if the identifier is not qualified - * @param $identifier string - * @return array - */ -sql::registerMethod('splitIdentifier', function($sql, $table, $identifier) { - - // split by dot, but only outside of quotes - $parts = preg_split('/(?:`[^`]*`|"[^"]*")(*SKIP)(*F)|\./', $identifier); - - switch(count($parts)) { - // non-qualified identifier - case 1: - return array($table, $sql->unquoteIdentifier($parts[0])); - - // qualified identifier - case 2: - return array($sql->unquoteIdentifier($parts[0]), $sql->unquoteIdentifier($parts[1])); - - // every other number is an error - default: - throw new Error('Invalid identifier ' . $identifier); - } - -}); - -/** - * Unquotes an identifier (table *or* column) - * - * @param $identifier string - * @return string - */ -sql::registerMethod('unquoteIdentifier', function($sql, $identifier) { - - // remove quotes around the identifier - if(in_array(str::substr($identifier, 0, 1), array('"', '`'))) $identifier = str::substr($identifier, 1); - if(in_array(str::substr($identifier, -1), array('"', '`'))) $identifier = str::substr($identifier, 0, -1); - - // unescape duplicated quotes - return str_replace(array('""', '``'), array('"', '`'), $identifier); - -}); - -/** - * Combines an identifier (table and column) - * MySQL version - * - * @param $table string - * @param $column string - * @param $values boolean Whether the identifier is going to be used for a values clause - * Only relevant for SQLite - * @return string - */ -sql::registerMethod('combineIdentifier', function($sql, $table, $column, $values = false) { - - return $sql->quoteIdentifier($table) . '.' . $sql->quoteIdentifier($column); - -}, 'mysql'); - -/** - * Combines an identifier (table and column) - * SQLite version - * - * @param $table string - * @param $column string - * @param $values boolean Whether the identifier is going to be used for a values clause - * Only relevant for SQLite - * @return string - */ -sql::registerMethod('combineIdentifier', function($sql, $table, $column, $values = false) { - - // SQLite doesn't support qualified column names for VALUES clauses - if($values) return $sql->quoteIdentifier($column); - return $sql->quoteIdentifier($table) . '.' . $sql->quoteIdentifier($column); - -}, 'sqlite'); - -/** - * Quotes an identifier (table *or* column) - * MySQL version - * - * @param $identifier string - * @return string - */ -sql::registerMethod('quoteIdentifier', function($sql, $identifier) { - - // * is special - if($identifier === '*') return $identifier; - - // replace every backtick with two backticks - $identifier = str_replace('`', '``', $identifier); - - // wrap in backticks - return '`' . $identifier . '`'; - -}, 'mysql'); - -/** - * Quotes an identifier (table *or* column) - * SQLite version - * - * @param $identifier string - * @return string - */ -sql::registerMethod('quoteIdentifier', function($sql, $identifier) { - - // * is special - if($identifier === '*') return $identifier; - - // replace every quote with two quotes - $identifier = str_replace('"', '""', $identifier); - - // wrap in quotes - return '"' . $identifier . '"'; - -}, 'sqlite'); - -/** - * Returns a list of tables for a specified database - * MySQL version - * - * @param string $database The database name - * @return string - */ -sql::registerMethod('tableList', function($sql, $database) { - - $bindings = array(); - $databaseBinding = sql::generateBindingName('database'); - $bindings[$databaseBinding] = $database; - - $query = 'SELECT TABLE_NAME AS name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ' . $databaseBinding; - - $sql->bindings($query, $bindings); - return $query; - -}, 'mysql'); - -/** - * Returns a list of tables of the database - * SQLite version - * - * @param string $database The database name - * @return string - */ -sql::registerMethod('tableList', function($sql, $database) { - - return 'SELECT name FROM sqlite_master WHERE type = "table"'; - -}, 'sqlite'); - -/** - * Returns a list of columns for a specified table - * MySQL version - * - * @param string $database The database name - * @param string $table The table name - * @return string - */ -sql::registerMethod('columnList', function($sql, $database, $table) { - - $bindings = array(); - $databaseBinding = sql::generateBindingName('database'); - $bindings[$databaseBinding] = $database; - $tableBinding = sql::generateBindingName('table'); - $bindings[$tableBinding] = $table; - - $query = 'SELECT COLUMN_NAME AS name FROM INFORMATION_SCHEMA.COLUMNS '; - $query .= 'WHERE TABLE_SCHEMA = ' . $databaseBinding . ' AND TABLE_NAME = ' . $tableBinding; - - $sql->bindings($query, $bindings); - return $query; - -}, 'mysql'); - -/** - * Returns a list of columns for a specified table - * SQLite version - * - * @param string $database The database name - * @param string $table The table name - * @return string - */ -sql::registerMethod('columnList', function($sql, $database, $table) { - - // validate table - if(!$sql->database->validateTable($table)) throw new Error('Invalid table ' . $table); - - return 'PRAGMA table_info(' . $sql->quoteIdentifier($table) . ')'; - -}, 'sqlite'); diff --git a/kirby/toolkit/lib/str.php b/kirby/toolkit/lib/str.php deleted file mode 100644 index 540c59e..0000000 --- a/kirby/toolkit/lib/str.php +++ /dev/null @@ -1,701 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Str { - - public static $ascii = array( - '/Ä/' => 'Ae', - '/æ|ǽ|ä/' => 'ae', - '/œ|ö/' => 'oe', - '/À|Á|Â|Ã|Å|Ǻ|Ā|Ă|Ą|Ǎ|А/' => 'A', - '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª|а/' => 'a', - '/Б/' => 'B', - '/б/' => 'b', - '/Ç|Ć|Ĉ|Ċ|Č|Ц/' => 'C', - '/ç|ć|ĉ|ċ|č|ц/' => 'c', - '/Ð|Ď|Đ/' => 'Dj', - '/ð|ď|đ/' => 'dj', - '/Д/' => 'D', - '/д/' => 'd', - '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Е|Ё|Э/' => 'E', - '/è|é|ê|ë|ē|ĕ|ė|ę|ě|е|ё|э/' => 'e', - '/Ф/' => 'F', - '/ƒ|ф/' => 'f', - '/Ĝ|Ğ|Ġ|Ģ|Г/' => 'G', - '/ĝ|ğ|ġ|ģ|г/' => 'g', - '/Ĥ|Ħ|Х/' => 'H', - '/ĥ|ħ|х/' => 'h', - '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|И/' => 'I', - '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|и/' => 'i', - '/Ĵ|Й/' => 'J', - '/ĵ|й/' => 'j', - '/Ķ|К/' => 'K', - '/ķ|к/' => 'k', - '/Ĺ|Ļ|Ľ|Ŀ|Ł|Л/' => 'L', - '/ĺ|ļ|ľ|ŀ|ł|л/' => 'l', - '/М/' => 'M', - '/м/' => 'm', - '/Ñ|Ń|Ņ|Ň|Н/' => 'N', - '/ñ|ń|ņ|ň|ʼn|н/' => 'n', - '/Ö/' => 'Oe', - '/ö/' => 'oe', - '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|О/' => 'O', - '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|о/' => 'o', - '/П/' => 'P', - '/п/' => 'p', - '/Ŕ|Ŗ|Ř|Р/' => 'R', - '/ŕ|ŗ|ř|р/' => 'r', - '/Ś|Ŝ|Ş|Ș|Š|С/' => 'S', - '/ś|ŝ|ş|ș|š|ſ|с/' => 's', - '/Ţ|Ț|Ť|Ŧ|Т/' => 'T', - '/ţ|ț|ť|ŧ|т/' => 't', - '/Ü/' => 'Ue', - '/ü/' => 'ue', - '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|У/' => 'U', - '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|у/' => 'u', - '/В/' => 'V', - '/в/' => 'v', - '/Ý|Ÿ|Ŷ|Ы/' => 'Y', - '/ý|ÿ|ŷ|ы/' => 'y', - '/Ŵ/' => 'W', - '/ŵ/' => 'w', - '/Ź|Ż|Ž|З/' => 'Z', - '/ź|ż|ž|з/' => 'z', - '/Æ|Ǽ/' => 'AE', - '/ß/'=> 'ss', - '/IJ/' => 'IJ', - '/ij/' => 'ij', - '/Œ/' => 'OE', - '/Ч/' => 'Ch', - '/ч/' => 'ch', - '/Ю/' => 'Ju', - '/ю/' => 'ju', - '/Я/' => 'Ja', - '/я/' => 'ja', - '/Ш/' => 'Sh', - '/ш/' => 'sh', - '/Щ/' => 'Shch', - '/щ/' => 'shch', - '/Ж/' => 'Zh', - '/ж/' => 'zh', - ); - - /** - * Default options for string methods - * - * @var array - */ - public static $defaults = array( - 'slug' => array( - 'separator' => '-', - 'allowed' => 'a-z0-9' - ) - ); - - /** - * Converts a string to a html-safe string - * - * - * - * echo str::html('some über crazy stuff'); - * // output: some über crazy stuff - * - * echo str::html('some über crazy stuff', false); - * // output: some <em>über crazy</em> stuff - * - * - * - * @param string $string - * @param boolean $keepTags True: lets stuff inside html tags untouched. - * @return string The html string - */ - public static function html($string, $keepTags = true) { - return html::encode($string, $keepTags); - } - - /** - * Removes all html tags and encoded chars from a string - * - * - * - * echo str::unhtml('some crazy stuff'); - * // output: some uber crazy stuff - * - * - * - * @param string $string - * @return string The html string - */ - public static function unhtml($string) { - return html::decode($string); - } - - /** - * Converts a string to a xml-safe string - * Converts it to html-safe first and then it - * will replace html entities to xml entities - * - * - * - * echo str::xml('some über crazy stuff'); - * // output: some über crazy stuff - * - * - * - * @param string $text - * @param boolean $html True: convert to html first - * @return string - */ - public static function xml($text, $html = true) { - return xml::encode($text, $html); - } - - /** - * Removes all xml entities from a string - * and convert them to html entities first - * and remove all html entities afterwards. - * - * - * - * echo str::unxml('some über crazy stuff'); - * // output: some über crazy stuff - * - * - * - * @param string $string - * @return string - */ - public static function unxml($string) { - return xml::decode($string); - } - - /** - * Parses a string by a set of available methods - * - * Available methods: - * - json - * - xml - * - url - * - query - * - php - * - * - * - * str::parse('{"test":"cool","super":"genious"}'); - * // output: array( - * // 'test' => 'cool', - * // 'super' => 'genious' - * // ); - * - * str::parse('nice', 'xml'); - * // output: array( - * // 'entries' => array( - * // 'cool' => 'nice' - * // ) - * // ); - * - * - * - * @param string $string - * @param string $mode - * @return mixed - */ - public static function parse($string, $mode = 'json') { - - if(is_array($string) || is_object($string)) return $string; - - switch($mode) { - case 'json': - return (array)@json_decode($string, true); - case 'xml': - return xml::parse($string); - case 'url': - return (array)@parse_url($string); - case 'php': - return @unserialize($string); - default: - return $string; - } - - } - - /** - * Encode a string (used for email addresses) - * - * @param string $string - * @return string - */ - public static function encode($string) { - $string = (string)$string; - $encoded = ''; - for($i = 0; $i < static::length($string); $i++) { - $char = static::substr($string, $i, 1); - if(MB) { - list(, $code) = unpack('N', mb_convert_encoding($char, 'UCS-4BE', 'UTF-8')); - } else { - $code = ord($char); - } - - $encoded .= rand(1, 2) == 1 ? '&#' . $code . ';' : '&#x' . dechex($code) . ';'; - } - return $encoded; - } - - /** - * Generates an "a mailto" tag - * - * - * - * echo str::email('bastian@getkirby.com'); - * echo str::email('bastian@getkirby.com', 'mail me'); - * - * - * - * @param string $email The url for the a tag - * @param mixed $text The optional text. If null, the url will be used as text - * @param array $attr Additional attributes for the tag - * @return string the generated html - */ - public static function email($email, $text = false, $attr = array()) { - return html::email($email, $text, $attr); - } - - /** - * Generates an a tag - * - * @param string $href The url for the a tag - * @param mixed $text The optional text. If null, the url will be used as text - * @param array $attr Additional attributes for the tag - * @return string the generated html - */ - public static function link($href, $text = null, $attr = array()) { - return html::a($href, $text, $attr); - } - - /** - * Returns an array with all words in a string - * - * @param string $string - */ - public static function words($string) { - preg_match_all('/(\pL{4,})/iu', $string, $m); - return array_shift($m); - } - - /** - * Returns an array with all sentences in a string - * - * @param string $string - * @return string - */ - public static function sentences($string) { - return preg_split('/(?<=[.?!])\s+/', $string, -1, PREG_SPLIT_NO_EMPTY); - } - - /** - * Returns an array with all lines in a string - * - * @param string $string - * @return array - */ - public static function lines($string) { - return str::split($string, PHP_EOL); - } - - /** - * Checks if the given string is a URL - * - * @param string $string - * @return boolean - */ - public static function isURL($string) { - return filter_var($string, FILTER_VALIDATE_URL); - } - - /** - * Shortens a string and adds an ellipsis if the string is too long - * - * - * - * echo str::short('This is a very, very, very long string', 10); - * // output: This is a… - * - * echo str::short('This is a very, very, very long string', 10, '####'); - * // output: This i#### - * - * - * - * @param string $string The string to be shortened - * @param int $length The final number of characters the string should have - * @param string $rep The element, which should be added if the string is too long. Ellipsis is the default. - * @return string The shortened string - */ - public static function short($string, $length, $rep = '…') { - if(!$length) return $string; - if(static::length($string) <= $length) return $string; - $string = static::substr($string, 0, $length); - return $string . $rep; - } - - /** - * Creates an excerpt of a string - * It removes all html tags first and then uses str::short - * - * @param string $string The string to be shortened - * @param int $chars The final number of characters the string should have - * @param boolean $removehtml True: remove the HTML tags from the string first - * @param string $rep The element, which should be added if the string is too long. Ellipsis is the default. - * @return string The shortened string - */ - public static function excerpt($string, $chars = 140, $removehtml = true, $rep='…') { - if($removehtml) $string = strip_tags($string); - $string = str_replace(PHP_EOL, ' ', trim($string)); - if(static::length($string) <= $chars) return $string; - return $chars == 0 ? $string : static::substr($string, 0, strrpos(static::substr($string, 0, $chars), ' ')) . $rep; - } - - /** - * The widont function makes sure that there are no - * typographical widows at the end of a paragraph – - * that's a single word in the last line - * - * @param string $string - * @return string - */ - public static function widont($string = '') { - return preg_replace_callback('|([^\s])\s+([^\s]+)\s*$|', function($matches) { - if(str::contains($matches[2], '-')) { - return $matches[1] . ' ' . str_replace('-', '‑', $matches[2]); - } else { - return $matches[1] . ' ' . $matches[2]; - } - }, $string); - } - - /** - * An UTF-8 safe version of substr() - * - * @param string $str - * @param int $start - * @param int $length - * @return string - */ - public static function substr($str, $start, $length = null) { - $length = $length === null ? static::length($str) : $length; - return MB ? mb_substr($str, $start, $length, 'UTF-8') : substr($str, $start, $length); - } - - /** - * An UTF-8 safe version of strtolower() - * - * @param string $str - * @return string - */ - public static function lower($str) { - return MB ? mb_strtolower($str, 'UTF-8') : strtolower($str); - } - - /** - * An UTF-8 safe version of strotoupper() - * - * @param string $str - * @return string - */ - public static function upper($str) { - return MB ? mb_strtoupper($str, 'UTF-8') : strtoupper($str); - } - - /** - * An UTF-8 safe version of strlen() - * - * @param string $str - * @return string - */ - public static function length($str) { - return MB ? mb_strlen($str, 'UTF-8') : strlen($str); - } - - /** - * Checks if a str contains another string - * - * @param string $str - * @param string $needle - * @param boolean $i ignore upper/lowercase - * @return string - */ - public static function contains($str, $needle, $i = true) { - if($i) { - $str = static::lower($str); - $needle = static::lower($needle); - } - return strstr($str, $needle) ? true : false; - } - - /** - * Generates a random string - * - * @param int $length The length of the random string - * @return string - */ - public static function random($length = false, $type = 'alphaNum') { - $length = $length ? $length : rand(5,10); - $pool = static::pool($type); - shuffle($pool); - $size = count($pool) - 1; - $hash = ''; - for($x = 0; $x < $length; $x++) { - $hash .= $pool[rand(0, $size)]; - } - return $hash; - } - - /** - * Convert a string to a safe version to be used in a URL - * - * @param string $string The unsafe string - * @param string $separator To be used instead of space and other non-word characters. - * @return string The safe string - */ - public static function slug($string, $separator = null, $allowed = null) { - - $separator = $separator ?: static::$defaults['slug']['separator']; - $allowed = $allowed ?: static::$defaults['slug']['allowed']; - - $string = trim($string); - $string = static::lower($string); - $string = static::ascii($string); - - // replace spaces with simple dashes - $string = preg_replace('![^' . $allowed . ']!i', $separator, $string); - // remove double dashes - $string = preg_replace('![' . preg_quote($separator) . ']{2,}!', $separator, $string); - // trim trailing and leading dashes - $string = trim($string, $separator); - // replace slashes with dashes - $string = str_replace('/', $separator, $string); - - return $string; - - } - - /** - * Better alternative for explode() - * It takes care of removing empty values - * and it has a built-in way to skip values - * which are too short. - * - * @param string $string The string to split - * @param string $separator The string to split by - * @param int $length The min length of values. - * @return array An array of found values - */ - public static function split($string, $separator = ',', $length = 1) { - - if(is_array($string)) return $string; - - $string = trim($string, $separator); - $parts = explode($separator, $string); - $out = array(); - - foreach($parts AS $p) { - $p = trim($p); - if(static::length($p) > 0 && static::length($p) >= $length) $out[] = $p; - } - - return $out; - - } - - /** - * An UTF-8 safe version of ucwords() - * - * @param string $string - * @return string - */ - public static function ucwords($string) { - return MB ? mb_convert_case($string, MB_CASE_TITLE, 'UTF-8') : ucwords(strtolower($string)); - } - - /** - * An UTF-8 safe version of ucfirst() - * - * @param string $string - * @return string - */ - public static function ucfirst($string) { - return static::upper(static::substr($string, 0, 1)) . static::lower(static::substr($string, 1)); - } - - /** - * Tries to detect the string encoding - * - * @param string $string - * @return string - */ - public static function encoding($string) { - - if(MB) { - return mb_detect_encoding($string, 'UTF-8, ISO-8859-1, windows-1251'); - } else { - foreach(array('utf-8', 'iso-8859-1', 'windows-1251') as $item) { - if(md5(iconv($item, $item, $string)) == md5($string)) return $item; - } - return false; - } - - } - - /** - * Converts a string to a different encoding - * - * @param string $string - * @param string $targetEncoding - * @param string $sourceEncoding (optional) - * @return string - */ - public static function convert($string, $targetEncoding, $sourceEncoding = null) { - // detect the source encoding if not passed as third argument - if(is_null($sourceEncoding)) $sourceEncoding = static::encoding($string); - return iconv($sourceEncoding, $targetEncoding, $string); - } - - /** - * Converts a string to UTF-8 - * - * @param string $string - * @return string - */ - public static function utf8($string) { - return static::convert($string, 'utf-8'); - } - - /** - * A better way to strip slashes - * - * @param string $string - * @return string - */ - public static function stripslashes($string) { - if(is_array($string)) return $string; - return get_magic_quotes_gpc() ? stripslashes($string) : $string; - } - - /** - * A super simple string template engine, - * which replaces tags like {mytag} with any other string - * - * @param string $string - * @param array $data An associative array with keys, which should be replaced and values. - * @return string - */ - public static function template($string, $data = array()) { - $replace = array(); - foreach($data as $key => $value) $replace['{' . $key . '}'] = $value; - return str_replace(array_keys($replace), array_values($replace), $string); - } - - /** - * Convert a string to 7-bit ASCII. - * - * @param string $string - * @return string - */ - public static function ascii($string) { - $foreign = static::$ascii; - $string = preg_replace(array_keys($foreign), array_values($foreign), $string); - return preg_replace('/[^\x09\x0A\x0D\x20-\x7E]/', '', $string); - } - - /** - * Forces a download of the string as text file - * - * @param string $string - * @param string $name Optional name for the downloaded file - */ - public static function download($string, $name = null) { - - header::download(array( - 'name' => $name ? $name : 'text.txt', - 'size' => static::length($string), - 'mime' => 'text/plain', - )); - - die($string); - - } - - /** - * Checks if a string starts with the passed needle - * - * @param string $string - * @param string $needle - * @return boolean - */ - public static function startsWith($string, $needle) { - return $needle === '' || strpos($string, $needle) === 0; - } - - /** - * Checks if a string ends with the passed needle - * - * @param string $string - * @param string $needle - * @return boolean - */ - public static function endsWith($string, $needle) { - return $needle === '' || static::substr($string, -static::length($needle)) === $needle; - } - - /** - * Get a character pool with various possible combinations - * - * @param string $type - * @param boolean $array - * @return string - */ - public static function pool($type, $array = true) { - - $pool = array(); - - if(is_array($type)) { - foreach($type as $t) { - $pool = array_merge($pool, static::pool($t)); - } - } else { - - switch($type) { - case 'alphaLower': - $pool = range('a','z'); - break; - case 'alphaUpper': - $pool = range('A', 'Z'); - break; - case 'alpha': - $pool = static::pool(array('alphaLower', 'alphaUpper')); - break; - case 'num': - $pool = range(0, 9); - break; - case 'alphaNum': - $pool = static::pool(array('alpha', 'num')); - break; - } - - } - - return $array ? $pool : implode('', $pool); - - } - -} diff --git a/kirby/toolkit/lib/system.php b/kirby/toolkit/lib/system.php deleted file mode 100644 index 929d27d..0000000 --- a/kirby/toolkit/lib/system.php +++ /dev/null @@ -1,150 +0,0 @@ - - * @link http://getkirby.com - * @copyright Lukas Bestle - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class System { - - /** - * Checks if the system() function is available - * - * @return boolean - */ - public static function available() { - return (!ini_get('safe_mode') && function_exists('exec')); - } - - /** - * Checks if a command is executable - * - * @param string $command Name or path of the command to check - * @return boolean - */ - public static function isExecutable($command) { - // check if everything we need is available - if(!static::available()) { - throw new Exception('The exec() function is not available on this system. Probably, safe_mode is on (shame!).'); - } - - // only use the actual command - list($command) = explode(' ', $command); - - // get the path to the executable and check if it exists - $path = static::realpath($command); - return $path !== false; - } - - /** - * Returns the path to a specific executable - * - * @param string $command Name or path of the command - * @return mixed - */ - public static function realpath($command) { - // check if everything we need is available - if(!static::available()) { - throw new Exception('The exec() function is not available on this system. Probably, safe_mode is on (shame!).'); - } - - // if this is actually a file, we don't need to search for it any longer - if(file_exists($command)) { - return is_executable($command) ? realpath($command) : false; - } - - // let the shell search for it - // depends on the operating system - if(strtolower(substr(PHP_OS, 0, 3)) === 'win') { - // Windows - // run the "where" command - $result = `where $command`; - // everything besides "Could not find files" would be OK - $exists = !preg_match('/Could not find files/', $result); - } else { - // Unix - // run the "which" command - $result = `which $command`; - // an empty output means there is no path - $exists = !empty($result); - } - - return $exists ? trim($result) : false; - - } - - /** - * Execute a given shell command - * - * @param string $command Name or path of the command - * @param string $arguments Additional arguments - * @param string $what What to return ('status', 'success', 'output' or 'all') - * @return mixed - */ - public static function execute($command, $arguments = array(), $what = 'all') { - // check if everything we need is available - if(!static::available()) { - throw new Exception('The exec() function is not available on this system. Probably, safe_mode is on (shame!).'); - } - - // other ways of calling this method - if(is_array($command)) { - // everything is given as one array - $what = (is_array($arguments))? 'all' : $arguments; - $arguments = array_slice($command, 1); - $command = $command[0]; - } else if(!is_array($arguments)) { - // each additional argument is given as a new method argument - $arguments = array_slice(func_get_args(), 1); - $what = 'all'; - } - - // check if the command exists - if(!static::isExecutable($command)) { - throw new Exception('The command "' . $command . '" is not executable.'); - } - - // escape command - $command = escapeshellcmd($command); - - // escape arguments - array_walk($arguments, function(&$argument) { - $argument = escapeshellarg($argument); - }); - - // execute the command - exec($command . ' ' . implode(' ', $arguments) . ' 2>&1', $output, $status); - - $result = array( - 'output' => implode("\n", $output), - 'status' => $status, - 'success' => $status === 0 - ); - - // return an appropriate result - if($what === 'all' || !array_key_exists($what, $result)) { - return $result; - } else { - return $result[$what]; - } - } - - /** - * Execute a given shell command - * Alias for System::execute() - * - * @param string $command Name or path of the command - * @param string $arguments Additional arguments - * @return array - */ - public static function __callStatic($command, $arguments) { - return static::execute($command, $arguments, 'all'); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/thumb.php b/kirby/toolkit/lib/thumb.php deleted file mode 100644 index bc8b534..0000000 --- a/kirby/toolkit/lib/thumb.php +++ /dev/null @@ -1,358 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Thumb extends Obj { - - const ERROR_INVALID_IMAGE = 0; - const ERROR_INVALID_DRIVER = 1; - - public static $drivers = array(); - - public static $defaults = array( - 'destination' => false, - 'filename' => '{safeName}-{hash}.{extension}', - 'url' => '/thumbs', - 'root' => '/thumbs', - 'driver' => 'im', - 'memory' => '128M', - 'quality' => 90, - 'blur' => false, - 'blurpx' => 10, - 'width' => null, - 'height' => null, - 'upscale' => false, - 'crop' => false, - 'grayscale' => false, - 'overwrite' => false, - 'autoOrient' => false, - 'interlace' => false - ); - - public $source = null; - public $result = null; - public $destination = null; - public $options = array(); - public $error = null; - - /** - * Constructor - * - * @param mixed $source - * @param array $params - */ - public function __construct($source, $params = array()) { - - $this->source = $this->result = is_a($source, 'Media') ? $source : new Media($source); - $this->options = array_merge(static::$defaults, $this->params($params)); - $this->destination = $this->destination(); - - // don't create the thumbnail if it's not necessary - if($this->isObsolete()) return; - - // don't create the thumbnail if it exists - if(!$this->isThere()) { - - // try to create the thumb folder if it is not there yet - dir::make(dirname($this->destination->root)); - - // check for a valid image - if(!$this->source->exists() || $this->source->type() != 'image') { - throw new Error('The given image is invalid', static::ERROR_INVALID_IMAGE); - } - - // check for a valid driver - if(!array_key_exists($this->options['driver'], static::$drivers)) { - throw new Error('Invalid thumbnail driver', static::ERROR_INVALID_DRIVER); - } - - // create the thumbnail - $this->create(); - - // check if creating the thumbnail failed - if(!file_exists($this->destination->root)) return; - - } - - // create the result object - $this->result = new Media($this->destination->root, $this->destination->url); - - } - - /** - * Build the destination object - * - * @return Obj - */ - public function destination() { - - if(is_callable($this->options['destination'])) { - return call($this->options['destination'], $this); - } else { - - $destination = new Obj(); - $safeName = f::safeName($this->source->name()); - - $destination->filename = str::template($this->options['filename'], array( - 'extension' => $this->source->extension(), - 'name' => $this->source->name(), - 'filename' => $this->source->filename(), - 'safeName' => $safeName, - 'safeFilename' => $safeName . '.' . $this->extension(), - 'width' => $this->options['width'], - 'height' => $this->options['height'], - 'hash' => md5($this->source->root() . $this->settingsIdentifier()), - )); - - $destination->url = $this->options['url'] . '/' . $destination->filename; - $destination->root = $this->options['root'] . DS . $destination->filename; - - return $destination; - - } - - } - - /** - * Returns the source media object - * - * @return Media - */ - public function source() { - return $this->source; - } - - /** - * Returns the exception if available - * - * @return Exception - */ - public function error() { - return $this->error; - } - - /** - * Makes it possible to pass a string of params - * which is shorter and more convenient than - * passing a full array of keys and values: - * width:300|height:200|crop:true - * - * @param array $params - * @return array - */ - public function params($params) { - if(is_array($params)) return $params; - $result = array(); - foreach(explode('|', $params) as $param) { - $pos = strpos($param, ':'); - $result[trim(substr($param, 0, $pos))] = trim(substr($param, $pos+1)); - } - return $result; - } - - /** - * Builds a hash for all relevant settings - * - * @return string - */ - public function settingsIdentifier() { - - // build the settings string - return implode('-', array( - ($this->options['width']) ? $this->options['width'] : 0, - ($this->options['height']) ? $this->options['height'] : 0, - ($this->options['upscale']) ? $this->options['upscale'] : 0, - ($this->options['crop']) ? $this->options['crop'] : 0, - $this->options['blur'], - $this->options['grayscale'], - $this->options['quality'] - )); - - } - - /** - * Checks if the thumbnail already exists - * and is newer than the original file - * - * @return boolean - */ - public function isThere() { - - if($this->options['overwrite'] === true) return false; - - // if the thumb already exists and the source hasn't been updated - // we don't need to generate a new thumbnail - if(file_exists($this->destination->root) && f::modified($this->destination->root) >= $this->source->modified()) return true; - - return false; - - } - - /** - * Checks if the thumbnail is not needed - * because the original image is small enough - * - * @return boolean - */ - public function isObsolete() { - - if($this->options['overwrite'] === true) return false; - - // try to use the original if resizing is not necessary - if($this->options['width'] >= $this->source->width() && - $this->options['height'] >= $this->source->height() && - $this->options['crop'] == false && - $this->options['blur'] == false && - $this->options['upscale'] == false) return true; - - return false; - - } - - /** - * Calls the driver function and - * creates the thumbnail - */ - protected function create() { - return call_user_func_array(static::$drivers[$this->options['driver']], array($this)); - } - - /** - * Makes all public methods of the result object - * available to the thumb class - * - * @param string $method - * @param mixed $arguments - * @return mixed - */ - public function __call($method, $arguments) { - - if(method_exists($this->result, $method)) { - return call_user_func_array(array($this->result, $method), $arguments); - } - - } - - /** - * Generates and returns the full html tag for the thumbnail - * - * @param array $attr An optional array of attributes, which should be added to the image tag - * @return string - */ - public function tag($attr = array()) { - - // don't return the tag if the url is not available - if(!$this->result->url()) return false; - - return html::img($this->result->url(), array_merge(array( - 'alt' => isset($this->options['alt']) ? $this->options['alt'] : ' ', - 'class' => isset($this->options['class']) ? $this->options['class'] : null, - ), $attr)); - - } - - /** - * Makes it possible to echo the entire object - */ - public function __toString() { - return $this->tag(); - } - -} - - - -/** - * ImageMagick Driver - */ -thumb::$drivers['im'] = function($thumb) { - - $command = array(); - - $command[] = isset($thumb->options['bin']) ? $thumb->options['bin'] : 'convert'; - $command[] = '"' . $thumb->source->root() . '"'; - $command[] = '-strip'; - - if($thumb->options['interlace']) { - $command[] = '-interlace line'; - } - - if($thumb->source->extension() === 'gif') { - $command[] = '-coalesce'; - } - - if($thumb->options['grayscale']) { - $command[] = '-colorspace gray'; - } - - if($thumb->options['autoOrient']) { - $command[] = '-auto-orient'; - } - - $command[] = '-resize'; - - if($thumb->options['crop']) { - $command[] = $thumb->options['width'] . 'x' . $thumb->options['height'] . '^'; - $command[] = '-gravity Center -crop ' . $thumb->options['width'] . 'x' . $thumb->options['height'] . '+0+0'; - } else { - $dimensions = clone $thumb->source->dimensions(); - $dimensions->fitWidthAndHeight($thumb->options['width'], $thumb->options['height'], $thumb->options['upscale']); - $command[] = $dimensions->width() . 'x' . $dimensions->height() . '!'; - } - - $command[] = '-quality ' . $thumb->options['quality']; - - if($thumb->options['blur']) { - $command[] = '-blur 0x' . $thumb->options['blurpx']; - } - - $command[] = '-limit thread 1'; - $command[] = '"' . $thumb->destination->root . '"'; - - exec(implode(' ', $command)); - -}; - - -/** - * GDLib Driver - */ -thumb::$drivers['gd'] = function($thumb) { - - try { - $img = new abeautifulsite\SimpleImage($thumb->root()); - $img->quality = $thumb->options['quality']; - - if($thumb->options['crop']) { - @$img->thumbnail($thumb->options['width'], $thumb->options['height']); - } else { - $dimensions = clone $thumb->source->dimensions(); - $dimensions->fitWidthAndHeight($thumb->options['width'], $thumb->options['height'], $thumb->options['upscale']); - @$img->resize($dimensions->width(), $dimensions->height()); - } - - if($thumb->options['grayscale']) { - $img->desaturate(); - } - - if($thumb->options['blur']) { - $img->blur('gaussian', $thumb->options['blurpx']); - } - - if($thumb->options['autoOrient']) { - $img->auto_orient(); - } - - @$img->save($thumb->destination->root); - } catch(Exception $e) { - $thumb->error = $e; - } - -}; diff --git a/kirby/toolkit/lib/timer.php b/kirby/toolkit/lib/timer.php deleted file mode 100644 index 0325205..0000000 --- a/kirby/toolkit/lib/timer.php +++ /dev/null @@ -1,28 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Timer { - - public static $time = null; - - public static function start() { - $time = explode(' ', microtime()); - static::$time = (double)$time[1] + (double)$time[0]; - } - - public static function stop() { - $time = explode(' ', microtime()); - $time = (double)$time[1] + (double)$time[0]; - $timer = static::$time; - return round(($time-$timer), 5); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/toolkit.php b/kirby/toolkit/lib/toolkit.php deleted file mode 100644 index 2f2a77e..0000000 --- a/kirby/toolkit/lib/toolkit.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Toolkit { - - public static $version = '2.3.0'; - - public static function version() { - return static::$version; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/tpl.php b/kirby/toolkit/lib/tpl.php deleted file mode 100644 index cc06212..0000000 --- a/kirby/toolkit/lib/tpl.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Tpl extends Silo { - - public static $data = array(); - - public static function load($_file, $_data = array(), $_return = true) { - if(!file_exists($_file)) return false; - ob_start(); - extract(array_merge(static::$data, (array)$_data)); - require($_file); - $_content = ob_get_contents(); - ob_end_clean(); - if($_return) return $_content; - echo $_content; - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/upload.php b/kirby/toolkit/lib/upload.php deleted file mode 100644 index 6a306e0..0000000 --- a/kirby/toolkit/lib/upload.php +++ /dev/null @@ -1,202 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Upload { - - const ERROR_FAILED_UPLOAD = 0; - const ERROR_MISSING_TMP_DIR = 1; - const ERROR_MISSING_FILE = 2; - const ERROR_UNALLOWED_OVERWRITE = 3; - const ERROR_PARTIAL_UPLOAD = 4; - const ERROR_MAX_SIZE = 5; - const ERROR_MOVE_FAILED = 6; - const ERROR_UNACCEPTED = 7; - - public $options = array(); - public $error = null; - public $file = null; - public $to = null; - - public function __construct($to, $params = array()) { - - $defaults = array( - 'input' => 'file', - 'index' => 0, - 'to' => $to, - 'overwrite' => true, - 'maxSize' => false, - 'accept' => null, - ); - - $this->options = array_merge($defaults, $params); - - try { - $this->move(); - $this->file = new Media($this->to()); - } catch(Exception $e) { - $this->error = $e; - } - - } - - public function error() { - return $this->error; - } - - public function source() { - - $source = isset($_FILES[$this->options['input']]) ? $_FILES[$this->options['input']] : null; - - // get the correct file out of multiple based on the "index" option - if($source && is_int($this->options['index']) && is_array($source['name'])) { - $allSources = $source; - $source = array(); - - // get the correct value out of the $values array with all files - foreach($allSources as $key => $values) { - $source[$key] = isset($values[$this->options['index']]) ? $values[$this->options['index']] : null; - } - } - - // prevent duplicate ios uploads - // ios automatically uploads all images as image.jpg, - // which will lead to overwritten duplicates. - // this dirty hack will simply add a uniqid between the - // name and the extension to avoid duplicates - if($source && f::name($source['name']) == 'image' && detect::ios()) { - $source['name'] = 'image-' . uniqid() . '.' . ltrim(f::extension($source['name']), '.'); - } - - return $source; - - } - - public function to() { - - if(!is_null($this->to)) return $this->to; - - $source = $this->source(); - $name = f::name($source['name']); - $extension = f::extension($source['name']); - $safeName = f::safeName($name); - $safeExtension = str_replace('jpeg', 'jpg', str::lower($extension)); - - if(empty($safeExtension)) { - $safeExtension = f::mimeToExtension(f::mime($source['tmp_name'])); - } - - return $this->to = str::template($this->options['to'], array( - 'name' => $name, - 'filename' => $source['name'], - 'safeName' => $safeName, - 'safeFilename' => $safeName . r(!empty($safeExtension), '.' . $safeExtension), - 'extension' => $extension, - 'safeExtension' => $safeExtension - )); - - } - - /** - * Returns the maximum accepted file size - * - * @return int - */ - public function maxSize() { - $sizes = array(detect::maxPostSize(), detect::maxUploadSize()); - if($this->options['maxSize']) { - $sizes[] = $this->options['maxSize']; - } - return min($sizes); - } - - public function file() { - return $this->file; - } - - protected function move() { - - $source = $this->source(); - - if(is_null($source['name']) || is_null($source['tmp_name'])) { - $this->fail(static::ERROR_MISSING_FILE); - } - - if($source['error'] !== 0) { - - switch($source['error']) { - case UPLOAD_ERR_INI_SIZE: - case UPLOAD_ERR_FORM_SIZE: - $this->fail(static::ERROR_MAX_SIZE); - case UPLOAD_ERR_PARTIAL: - $this->fail(static::ERROR_PARTIAL_UPLOAD); - case UPLOAD_ERR_NO_FILE: - $this->fail(static::ERROR_MISSING_FILE); - case UPLOAD_ERR_NO_TMP_DIR: - $this->fail(static::ERROR_MISSING_TMP_DIR); - case UPLOAD_ERR_CANT_WRITE: - $this->fail(static::ERROR_MOVE_FAILED); - case UPLOAD_ERR_EXTENSION: - $this->fail(static::ERROR_UNACCEPTED); - default: - $this->fail(static::ERROR_FAILED_UPLOAD); - } - - } - - if(file_exists($this->to()) && $this->options['overwrite'] === false) { - $this->fail(static::ERROR_UNALLOWED_OVERWRITE); - } - - if($this->options['maxSize'] && $source['size'] > $this->options['maxSize']) { - $this->fail(static::ERROR_MAX_SIZE); - } - - if(is_callable($this->options['accept'])) { - $accepted = call($this->options['accept'], new Media($source['tmp_name'])); - if($accepted === false) { - $this->fail(static::ERROR_UNACCEPTED); - } - } - - if(!@move_uploaded_file($source['tmp_name'], $this->to())) { - $this->fail(static::ERROR_MOVE_FAILED); - } - - } - - protected function messages() { - return array( - static::ERROR_MISSING_FILE => 'The file is missing', - static::ERROR_MISSING_TMP_DIR => 'The /tmp directory is missing on your server', - static::ERROR_FAILED_UPLOAD => 'The upload failed', - static::ERROR_PARTIAL_UPLOAD => 'The file has been only been partially uploaded', - static::ERROR_UNALLOWED_OVERWRITE => 'The file exists and cannot be overwritten', - static::ERROR_MAX_SIZE => 'The file is too big. The maximum size is ' . f::niceSize($this->maxSize()), - static::ERROR_MOVE_FAILED => 'The file could not be moved', - static::ERROR_UNACCEPTED => 'The file is not accepted by the server' - ); - } - - protected function fail($code) { - - $messages = $this->messages(); - - if(!isset($messages[$code])) { - $code = static::ERROR_FAILED_UPLOAD; - } - - throw new Error($messages[$code], $code); - - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/url.php b/kirby/toolkit/lib/url.php deleted file mode 100644 index bedc9c6..0000000 --- a/kirby/toolkit/lib/url.php +++ /dev/null @@ -1,391 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Url { - - public static $home = '/'; - public static $to = null; - public static $current = null; - - public static function scheme($url = null) { - if(is_null($url)) { - if( - (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') || - server::get('SERVER_PORT') == '443' || - server::get('HTTP_X_FORWARDED_PORT') == '443' || - server::get('HTTP_X_FORWARDED_PROTO') == 'https' || - server::get('HTTP_X_FORWARDED_PROTO') == 'https, http' - ) { - return 'https'; - } else { - return 'http'; - } - } - return parse_url($url, PHP_URL_SCHEME); - - } - - /** - * Returns the current url with all bells and whistles - * - * @return string - */ - public static function current() { - if(!is_null(static::$current)) return static::$current; - return static::$current = static::base() . server::get('REQUEST_URI'); - } - - /** - * Returns the url for the current directory - * - * @return string - */ - public static function currentDir() { - return dirname(static::current()); - } - - /** - */ - public static function host($url = null) { - if(is_null($url)) $url = static::current(); - return parse_url($url, PHP_URL_HOST); - } - - /** - * Returns the port for the given url - * - * @return mixed - */ - public static function port($url = null) { - if(is_null($url)) $url = static::current(); - $port = intval(parse_url($url, PHP_URL_PORT)); - return v::between($port, 1, 65535) ? $port : false; - } - - /** - * Returns only the cleaned path of the url - */ - public static function path($url = null) { - - if(is_null($url)) $url = static::current(); - - // if a path is passed, let's pretend this is an absolute url - // to trick the url parser. It's a bit hacky but it works - if(!static::isAbsolute($url)) $url = 'http://0.0.0.0/' . $url; - - return trim(parse_url($url, PHP_URL_PATH), '/'); - - } - - /** - * Returns the correct separator for parameters - * depending on the operating system - * - * @return string - */ - public static function paramSeparator() { - return detect::windows() ? ';' : ':'; - } - - /** - * Returns the params in the url - */ - public static function params($url = null) { - if(is_null($url)) $url = static::current(); - $path = static::path($url); - if(empty($path)) return array(); - $params = array(); - foreach(explode('/', $path) as $part) { - $pos = strpos($part, static::paramSeparator()); - if($pos === false) continue; - $params[substr($part, 0, $pos)] = urldecode(substr($part, $pos+1)); - } - return $params; - } - - /** - * Returns the path without params - */ - public static function fragments($url = null) { - if(is_null($url)) $url = static::current(); - $path = static::path($url); - if(empty($path)) return null; - $frag = array(); - foreach(explode('/', $path) as $part) { - if(strpos($part, static::paramSeparator()) === false) $frag[] = $part; - } - return $frag; - } - - /** - * Returns the query as array - */ - public static function query($url = null) { - if(is_null($url)) $url = static::current(); - parse_str(parse_url($url, PHP_URL_QUERY), $array); - return $array; - } - - /** - * Checks if the url contains a query string - */ - public static function hasQuery($url = null) { - if(is_null($url)) $url = static::current(); - return str::contains($url, '?'); - } - - /** - */ - public static function hash($url = null) { - if(is_null($url)) $url = static::current(); - return parse_url($url, PHP_URL_FRAGMENT); - } - - public static function build($parts = array(), $url = null) { - - if(is_null($url)) $url = static::current(); - - $defaults = array( - 'scheme' => static::scheme($url), - 'host' => static::host($url), - 'port' => static::port($url), - 'fragments' => static::fragments($url), - 'params' => static::params($url), - 'query' => static::query($url), - 'hash' => static::hash($url), - ); - - $parts = array_merge($defaults, $parts); - $result = array(r(!empty($parts['scheme']), $parts['scheme'] . '://') . $parts['host'] . r(!empty($parts['port']), ':' . $parts['port'])); - - if(!empty($parts['fragments'])) $result[] = implode('/', $parts['fragments']); - if(!empty($parts['params'])) $result[] = static::paramsToString($parts['params']); - if(!empty($parts['query'])) $result[] = '?' . static::queryToString($parts['query']); - - return implode('/', $result) . (!empty($parts['hash']) ? '#' . $parts['hash'] : ''); - - } - - public static function queryToString($query = null) { - if(is_null($query)) $query = url::query(); - return http_build_query($query); - } - - public static function paramsToString($params = null) { - if(is_null($params)) $params = url::params(); - $result = array(); - foreach($params as $key => $val) $result[] = $key . static::paramSeparator() . $val; - return implode('/', $result); - } - - public static function stripPath($url = null) { - if(is_null($url)) $url = static::current(); - return static::build(array('fragments' => array(), 'params' => array()), $url); - } - - public static function stripFragments($url = null) { - if(is_null($url)) $url = static::current(); - return static::build(array('fragments' => array()), $url); - } - - public static function stripParams($url = null) { - if(is_null($url)) $url = static::current(); - return static::build(array('params' => array()), $url); - } - - /** - * Strips the query from the URL - * - * - * - * echo url::stripQuery('http://www.youtube.com/watch?v=9q_aXttJduk'); - * // output: http://www.youtube.com/watch - * - * - * - * @param string $url - * @return string - */ - public static function stripQuery($url = null) { - if(is_null($url)) $url = static::current(); - return static::build(array('query' => array()), $url); - } - - /** - * Strips a hash value from the URL - * - * - * - * echo url::stripHash('http://testurl.com/#somehash'); - * // output: http://testurl.com/ - * - * - * - * @param string $url - * @return string - */ - public static function stripHash($url) { - if(is_null($url)) $url = static::current(); - return static::build(array('hash' => ''), $url); - } - - /** - * Checks if an URL is absolute - * - * @return boolean - */ - public static function isAbsolute($url) { - // don't convert absolute urls - return (str::startsWith($url, 'http://') || str::startsWith($url, 'https://') || str::startsWith($url, '//')); - } - - /** - * Convert a relative path into an absolute URL - * - * @param string $path - * @param string $home - * @return string - */ - public static function makeAbsolute($path, $home = null) { - - if(static::isAbsolute($path)) return $path; - - // build the full url - $path = ltrim($path, '/'); - $home = is_null($home) ? static::$home : $home; - - if(empty($path)) return $home; - - return $home == '/' ? '/' . $path : $home . '/' . $path; - - } - - /** - * Tries to fix a broken url without protocol - * - * @param string $url - * @return string - */ - public static function fix($url) { - // make sure to not touch absolute urls - return (!preg_match('!^(https|http|ftp)\:\/\/!i', $url)) ? 'http://' . $url : $url; - } - - /** - * Returns the home url if defined - * - * @return string - */ - public static function home() { - return static::$home; - } - - /** - * The url smart handler. Must be defined before - * - * @return string - */ - public static function to() { - return call_user_func_array(static::$to, func_get_args()); - } - - /** - * Return the last url the user has been on if detectable - * - * @return string - */ - public static function last() { - return r::referer(); - } - - /** - * Returns the base url - * - * @param string $url - * @return string - */ - public static function base($url = null) { - if(is_null($url)) { - $port = server::get('SERVER_PORT'); - $port = in_array($port, array(80, 443)) ? null : $port; - return static::scheme() . '://' . server::get('SERVER_NAME', server::get('SERVER_ADDR')) . r($port, ':' . $port); - } else { - $port = static::port($url); - $scheme = static::scheme($url); - $host = static::host($url) . r(is_int($port), ':' . $port); - return r($scheme, $scheme . '://') . $host; - } - } - - /** - * Shortens a URL - * It removes http:// or https:// and uses str::short afterwards - * - * - * - * echo url::short('http://veryveryverylongurl.com', 30); - * // output: veryveryverylongurl.com - * - * - * - * @param string $url The URL to be shortened - * @param int $length The final number of characters the URL should have - * @param boolean $base True: only take the base of the URL. - * @param string $rep The element, which should be added if the string is too long. Ellipsis is the default. - * @return string The shortened URL - */ - public static function short($url, $length = false, $base = false, $rep = '…') { - - if($base) $url = static::base($url); - - // replace all the nasty stuff from the url - $url = str_replace(array('http://', 'https://', 'ftp://', 'www.'), '', $url); - - // try to remove the last / after the url - $url = rtrim($url, '/'); - - return ($length) ? str::short($url, $length, $rep) : $url; - - } - - /** - * Returns the URL for document root no - * matter what the path is. - * - * @return string - */ - public static function index() { - if(r::cli()) { - return '/'; - } else { - return static::base() . preg_replace('!\/index\.php$!i', '', server::get('SCRIPT_NAME')); - } - } - -} - -// basic home url setup -url::$home = url::base(); - -// basic url generator setup -url::$to = function($path = '/') { - - if(url::isAbsolute($path)) return $path; - - $path = ltrim($path, '/'); - - if(empty($path)) return url::home(); - - return url::home() . '/' . $path; - -}; diff --git a/kirby/toolkit/lib/v.php b/kirby/toolkit/lib/v.php deleted file mode 100644 index 62a408d..0000000 --- a/kirby/toolkit/lib/v.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class V { - - // an array with all installed validators - public static $validators = array(); - - /** - * Return the list of all validators - * - * @return array - */ - public static function validators() { - return static::$validators; - } - - /** - * Calls an installed validator and passes all arguments - * - * @param string $method - * @param array $arguments - * @return boolean - */ - public static function __callStatic($method, $arguments) { - - // check for missing validators - if(!isset(static::$validators[$method])) throw new Exception('The validator does not exist: ' . $method); - - return call_user_func_array(static::$validators[$method], $arguments); - - } - -} - - -/** - * Default set of validators - */ -v::$validators = array( - 'accepted' => function($value) { - return v::in($value, array(1, true, 'yes', 'true', '1', 'on')); - }, - 'denied' => function($value) { - return v::in($value, array(0, false, 'no', 'false', '0', 'off')); - }, - 'alpha' => function($value) { - return v::match($value, '/^([a-z])+$/i'); - }, - 'alphanum' => function($value) { - return v::match($value, '/^[a-z0-9]+$/i'); - }, - 'between' => function($value, $min, $max) { - return v::min($value, $min) && v::max($value, $max); - }, - 'date' => function($value) { - $time = strtotime($value); - if(!is_int($time)) return false; - - $year = date('Y', $time); - $month = date('m', $time); - $day = date('d', $time); - - return checkdate($month, $day, $year); - - }, - 'different' => function($value, $other) { - return $value !== $other; - }, - 'email' => function($value) { - return filter_var($value, FILTER_VALIDATE_EMAIL) !== false; - }, - 'filename' => function($value) { - return v::match($value, '/^[a-z0-9@._-]+$/i') && v::min($value, 2); - }, - 'in' => function($value, $in) { - return in_array($value, $in, true); - }, - 'integer' => function($value) { - return filter_var($value, FILTER_VALIDATE_INT) !== false; - }, - 'ip' => function($value) { - return filter_var($value, FILTER_VALIDATE_IP) !== false; - }, - 'match' => function($value, $preg) { - return preg_match($preg, $value) > 0; - }, - 'max' => function($value, $max) { - return size($value) <= $max; - }, - 'min' => function($value, $min) { - return size($value) >= $min; - }, - 'maxWords' => function($value, $max) { - return v::max(explode(' ', $value), $max); - }, - 'minWords' => function($value, $min) { - return v::min(explode(' ', $value), $min); - }, - 'notIn' => function($value, $notIn) { - return !v::in($value, $notIn); - }, - 'num' => function($value) { - return is_numeric($value); - }, - 'required' => function($key, $array) { - return !empty($array[$key]); - }, - 'same' => function($value, $other) { - return $value === $other; - }, - 'size' => function($value, $size) { - return size($value) == $size; - }, - 'url' => function($value) { - // In search for the perfect regular expression: https://mathiasbynens.be/demo/url-regex - $regex = '_^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$_iu'; - return preg_match($regex, $value) !== 0; - } -); diff --git a/kirby/toolkit/lib/visitor.php b/kirby/toolkit/lib/visitor.php deleted file mode 100644 index b42ff31..0000000 --- a/kirby/toolkit/lib/visitor.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Visitor { - - // banned ips - public static $banned = array(); - - // cache for the detected language code - protected static $acceptedLanguageCode = null; - - /** - * Returns the ip address of the current visitor - * - * @return string - */ - public static function ip() { - return getenv('REMOTE_ADDR'); - } - - /** - * Returns the user agent string of the current visitor - * - * @return string - */ - public static function ua() { - return isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null; - } - - /** - * A more readable but longer alternative for ua() - * - * @return string - */ - public static function userAgent() { - return static::ua(); - } - - /** - * Returns the user's accepted language - * - * @return string - */ - public static function acceptedLanguage() { - return isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : null; - } - - /** - * Returns the user's accepted language code - * - * @return string - */ - public static function acceptedLanguageCode() { - if(!is_null(static::$acceptedLanguageCode)) return static::$acceptedLanguageCode; - $detected = explode(',', static::acceptedLanguage()); - $detected = explode('-', $detected[0]); - return static::$acceptedLanguageCode = strtolower($detected[0]); - } - - /** - * Returns the referrer if available - * - * @return string - */ - public static function referrer() { - return r::referer(); - } - - /** - * Nobody can remember if it is written with on or two r - * - * @return string - */ - public static function referer() { - return r::referer(); - } - - /** - * Checks if the ip of the current visitor is banned - * - * @return boolean - */ - public static function banned() { - return in_array(static::ip(), static::$banned); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/lib/xml.php b/kirby/toolkit/lib/xml.php deleted file mode 100644 index d88dc87..0000000 --- a/kirby/toolkit/lib/xml.php +++ /dev/null @@ -1,144 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Xml { - - /** - * Converts a string to a xml-safe string - * Converts it to html-safe first and then it - * will replace html entities to xml entities - * - * - * - * echo xml::encode('some über crazy stuff'); - * // output: some über crazy stuff - * - * - * - * @param string $string - * @param boolean $html True: convert to html first - * @return string - */ - public static function encode($string, $html = true) { - - // convert raw text to html safe text - if($html) { - $string = html::encode($string, false); - } - - // convert html entities to xml entities - return strtr($string, html::entities()); - - } - - /** - * Removes all xml entities from a string - * and convert them to html entities first - * and remove all html entities afterwards. - * - * - * - * echo xml::decode('some über crazy stuff'); - * // output: some über crazy stuff - * - * - * - * @param string $string - * @return string - */ - public static function decode($string) { - // convert xml entities to html entities - $string = strtr($string, static::entities()); - return html::decode($string); - } - - /** - * Parses a XML string and returns an array - * - * @param string $xml - * @return mixed - */ - public static function parse($xml) { - - $xml = preg_replace('/(<\/?)(\w+):([^>]*>)/', '$1$2$3', $xml); - $xml = @simplexml_load_string($xml, null, LIBXML_NOENT | LIBXML_NOCDATA); - $xml = @json_encode($xml); - $xml = @json_decode($xml, true); - return (is_array($xml)) ? $xml : false; - - } - - /** - * Returns a translation table of xml entities to html entities - * - * @return array - */ - public static function entities() { - return array_flip(html::entities()); - } - - /** - * Creates an XML string from an array - * - * @param array $array The source array - * @param string $tag The name of the root element - * @param boolean $head Include the xml declaration head or not - * @param string $charset The charset, which should be used for the header - * @param int $level The indendation level - * @return string The XML string - */ - public static function create($array, $tag = 'root', $head = true, $charset = 'utf-8', $tab = ' ', $level = 0) { - $result = ($level == 0 && $head) ? '' . PHP_EOL : ''; - $nlevel = ($level + 1); - $attr = '@attributes'; - $attributes = html::attr(a::get($array, $attr)); - if(count($array) == 1 and $attributes) { - // return the self closed node - return str_repeat($tab, $level) . '<' . $tag . ($attributes ? ' ' . $attributes : '') . ' />' . PHP_EOL; - } else { - $result .= str_repeat($tab, $level) . '<' . $tag . ($attributes ? ' ' . $attributes . ' ' : '') . '>' . PHP_EOL; - } - foreach($array as $key => $value) { - $key = str::lower($key); - if($key == $attr) { - continue; - } - if(is_array($value)) { - $mtags = false; - foreach($value as $key2 => $value2) { - if($key2 == $attr) { - continue; - } - if(is_array($value2)) { - $result .= static::create($value2, $key2, $head, $charset, $tab, $nlevel); - } elseif(!is_numeric($key)) { - $result .= static::create($value, $key, $head, $charset, $tab, $nlevel); - } elseif(trim($value2) != '') { - $value2 = (!strstr($value2, '' : $value2; - $result .= str_repeat($tab, $nlevel) . '<' . $key2 . '>' . $value2 . '' . PHP_EOL; - } - $mtags = true; - } - if(!$mtags && count($value) > 0) { - $result .= static::create($value, $key, $head, $charset, $tab, $nlevel); - } - } elseif(trim($value) != '') { - $value = (!strstr($value, '' : $value; - $result .= str_repeat($tab, $nlevel) . (is_numeric($key) ? '' : '<' . $key . '>') . $value . (is_numeric($key) ? '' : '') . PHP_EOL; - } - } - return $result . str_repeat($tab, $level) . '' . PHP_EOL; - } - -} diff --git a/kirby/toolkit/lib/yaml.php b/kirby/toolkit/lib/yaml.php deleted file mode 100644 index b1fc8d5..0000000 --- a/kirby/toolkit/lib/yaml.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @link http://getkirby.com - * @copyright Bastian Allgeier - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -class Yaml { - - /** - * Creates a new yaml string from an array - * - * @param array $array - * @return string - */ - public static function encode($array) { - return preg_replace('!^---\n!', '', spyc::yamldump($array)); - } - - /** - * Creates a new yaml file from an array - * - * @param string $file - * @param array $array - * @return boolean - */ - public static function write($file, $array) { - return f::write($file, static::encode($array)); - } - - /** - * Parses a yaml string and returns the array - * - * @param string $yaml - * @return array - */ - public static function decode($yaml) { - return spyc::yamlload($yaml); - } - - /** - * Reads and parses a yaml file and returns the array - * - * @param string $file - * @return array - */ - public static function read($file) { - return spyc::yamlload($file); - } - -} \ No newline at end of file diff --git a/kirby/toolkit/readme.md b/kirby/toolkit/readme.md deleted file mode 100644 index 7a094e7..0000000 --- a/kirby/toolkit/readme.md +++ /dev/null @@ -1,32 +0,0 @@ -# Kirby Toolkit - -The Kirby 2 toolkit is a set of handy classes and helpers which make your life with PHP easier. - -[![Build Status](https://travis-ci.org/getkirby/toolkit.svg?branch=master)](https://travis-ci.org/getkirby/toolkit) - -## Installation - -```` -git pull https://github.com/getkirby/toolkit.git -```` - -Adding the toolkit to your app… - -```php - -``` - -## Requirements - -PHP 5.4+ - -## License - - - -## Author - -Bastian Allgeier - - - diff --git a/kirby/toolkit/vendors/abeautifulsite/SimpleImage.php b/kirby/toolkit/vendors/abeautifulsite/SimpleImage.php deleted file mode 100755 index 4af7f08..0000000 --- a/kirby/toolkit/vendors/abeautifulsite/SimpleImage.php +++ /dev/null @@ -1,1285 +0,0 @@ - - merging of forks, namespace support, PhpDoc editing, adaptive_resize() method, other fixes - * @license This software is licensed under the MIT license: http://opensource.org/licenses/MIT - * @copyright A Beautiful Site, LLC - * - */ - -namespace abeautifulsite; -use Exception; - -/** - * Class SimpleImage - * This class makes image manipulation in PHP as simple as possible. - * @package SimpleImage - * - */ -class SimpleImage { - - /** - * @var int Default output image quality - * - */ - public $quality = 80; - - protected $image, $filename, $original_info, $width, $height, $imagestring, $exif; - - /** - * Create instance and load an image, or create an image from scratch - * - * @param null|string $filename Path to image file (may be omitted to create image from scratch) - * @param int $width Image width (is used for creating image from scratch) - * @param int|null $height If omitted - assumed equal to $width (is used for creating image from scratch) - * @param null|string $color Hex color string, array(red, green, blue) or array(red, green, blue, alpha). - * Where red, green, blue - integers 0-255, alpha - integer 0-127
- * (is used for creating image from scratch) - * - * @throws Exception - * - */ - public function __construct($filename = null, $width = null, $height = null, $color = null) { - if ($filename !== null) { - $this->load($filename); - } elseif ($width !== null) { - $this->create($width, $height, $color); - } - } - - /** - * Destroy image resource - * - */ - public function __destruct() { - if( get_resource_type($this->image) === 'gd' ) { - imagedestroy($this->image); - } - } - - /** - * Adaptive resize - * - * This function has been deprecated and will be removed in an upcoming release. Please - * update your code to use the `thumbnail()` method instead. The arguments for both - * methods are exactly the same. - * - * @param int $width - * @param int|null $height If omitted - assumed equal to $width - * - * @return SimpleImage - * - */ - public function adaptive_resize($width, $height = null) { - - return $this->thumbnail($width, $height); - - } - - /** - * Rotates and/or flips an image automatically so the orientation will be correct (based on exif 'Orientation') - * - * @return SimpleImage - * - */ - public function auto_orient() { - - // stop if there's no exif data - if(!isset($this->original_info['exif']['Orientation'])) { - return $this; - } - - switch ($this->original_info['exif']['Orientation']) { - case 1: - // Do nothing - break; - case 2: - // Flip horizontal - $this->flip('x'); - break; - case 3: - // Rotate 180 counterclockwise - $this->rotate(-180); - break; - case 4: - // vertical flip - $this->flip('y'); - break; - case 5: - // Rotate 90 clockwise and flip vertically - $this->flip('y'); - $this->rotate(90); - break; - case 6: - // Rotate 90 clockwise - $this->rotate(90); - break; - case 7: - // Rotate 90 clockwise and flip horizontally - $this->flip('x'); - $this->rotate(90); - break; - case 8: - // Rotate 90 counterclockwise - $this->rotate(-90); - break; - } - - return $this; - - } - - /** - * Best fit (proportionally resize to fit in specified width/height) - * - * Shrink the image proportionally to fit inside a $width x $height box - * - * @param int $max_width - * @param int $max_height - * - * @return SimpleImage - * - */ - public function best_fit($max_width, $max_height) { - - // If it already fits, there's nothing to do - if ($this->width <= $max_width && $this->height <= $max_height) { - return $this; - } - - // Determine aspect ratio - $aspect_ratio = $this->height / $this->width; - - // Make width fit into new dimensions - if ($this->width > $max_width) { - $width = $max_width; - $height = $width * $aspect_ratio; - } else { - $width = $this->width; - $height = $this->height; - } - - // Make height fit into new dimensions - if ($height > $max_height) { - $height = $max_height; - $width = $height / $aspect_ratio; - } - - return $this->resize($width, $height); - - } - - /** - * Blur - * - * @param string $type selective|gaussian - * @param int $passes Number of times to apply the filter - * - * @return SimpleImage - * - */ - public function blur($type = 'selective', $passes = 1) { - switch (strtolower($type)) { - case 'gaussian': - $type = IMG_FILTER_GAUSSIAN_BLUR; - break; - default: - $type = IMG_FILTER_SELECTIVE_BLUR; - break; - } - for ($i = 0; $i < $passes; $i++) { - imagefilter($this->image, $type); - } - return $this; - } - - /** - * Brightness - * - * @param int $level Darkest = -255, lightest = 255 - * - * @return SimpleImage - * - */ - public function brightness($level) { - imagefilter($this->image, IMG_FILTER_BRIGHTNESS, $this->keep_within($level, -255, 255)); - return $this; - } - - /** - * Contrast - * - * @param int $level Min = -100, max = 100 - * - * @return SimpleImage - * - * - */ - public function contrast($level) { - imagefilter($this->image, IMG_FILTER_CONTRAST, $this->keep_within($level, -100, 100)); - return $this; - } - - /** - * Colorize - * - * @param string $color Hex color string, array(red, green, blue) or array(red, green, blue, alpha). - * Where red, green, blue - integers 0-255, alpha - integer 0-127 - * @param float|int $opacity 0-1 - * - * @return SimpleImage - * - */ - public function colorize($color, $opacity) { - $rgba = $this->normalize_color($color); - $alpha = $this->keep_within(127 - (127 * $opacity), 0, 127); - imagefilter($this->image, IMG_FILTER_COLORIZE, $this->keep_within($rgba['r'], 0, 255), $this->keep_within($rgba['g'], 0, 255), $this->keep_within($rgba['b'], 0, 255), $alpha); - return $this; - } - - /** - * Create an image from scratch - * - * @param int $width Image width - * @param int|null $height If omitted - assumed equal to $width - * @param null|string $color Hex color string, array(red, green, blue) or array(red, green, blue, alpha). - * Where red, green, blue - integers 0-255, alpha - integer 0-127 - * - * @return SimpleImage - * - */ - public function create($width, $height = null, $color = null) { - - $height = $height ?: $width; - $this->width = $width; - $this->height = $height; - $this->image = imagecreatetruecolor($width, $height); - $this->original_info = array( - 'width' => $width, - 'height' => $height, - 'orientation' => $this->get_orientation(), - 'exif' => null, - 'format' => 'png', - 'mime' => 'image/png' - ); - - if ($color !== null) { - $this->fill($color); - } - - return $this; - - } - - /** - * Crop an image - * - * @param int $x1 Left - * @param int $y1 Top - * @param int $x2 Right - * @param int $y2 Bottom - * - * @return SimpleImage - * - */ - public function crop($x1, $y1, $x2, $y2) { - - // Determine crop size - if ($x2 < $x1) { - list($x1, $x2) = array($x2, $x1); - } - if ($y2 < $y1) { - list($y1, $y2) = array($y2, $y1); - } - $crop_width = $x2 - $x1; - $crop_height = $y2 - $y1; - - // Perform crop - $new = imagecreatetruecolor($crop_width, $crop_height); - imagealphablending($new, false); - imagesavealpha($new, true); - imagecopyresampled($new, $this->image, 0, 0, $x1, $y1, $crop_width, $crop_height, $crop_width, $crop_height); - - // Update meta data - $this->width = $crop_width; - $this->height = $crop_height; - $this->image = $new; - - return $this; - - } - - /** - * Desaturate - * - * @param int $percentage Level of desaturization. - * - * @return SimpleImage - * - */ - public function desaturate($percentage = 100) { - - // Determine percentage - $percentage = $this->keep_within($percentage, 0, 100); - - if( $percentage === 100 ) { - imagefilter($this->image, IMG_FILTER_GRAYSCALE); - } else { - // Make a desaturated copy of the image - $new = imagecreatetruecolor($this->width, $this->height); - imagealphablending($new, false); - imagesavealpha($new, true); - imagecopy($new, $this->image, 0, 0, 0, 0, $this->width, $this->height); - imagefilter($new, IMG_FILTER_GRAYSCALE); - - // Merge with specified percentage - $this->imagecopymerge_alpha($this->image, $new, 0, 0, 0, 0, $this->width, $this->height, $percentage); - imagedestroy($new); - - } - - return $this; - } - - /** - * Edge Detect - * - * @return SimpleImage - * - */ - public function edges() { - imagefilter($this->image, IMG_FILTER_EDGEDETECT); - return $this; - } - - /** - * Emboss - * - * @return SimpleImage - * - */ - public function emboss() { - imagefilter($this->image, IMG_FILTER_EMBOSS); - return $this; - } - - /** - * Fill image with color - * - * @param string $color Hex color string, array(red, green, blue) or array(red, green, blue, alpha). - * Where red, green, blue - integers 0-255, alpha - integer 0-127 - * - * @return SimpleImage - * - */ - public function fill($color = '#000000') { - - $rgba = $this->normalize_color($color); - $fill_color = imagecolorallocatealpha($this->image, $rgba['r'], $rgba['g'], $rgba['b'], $rgba['a']); - imagealphablending($this->image, false); - imagesavealpha($this->image, true); - imagefilledrectangle($this->image, 0, 0, $this->width, $this->height, $fill_color); - - return $this; - - } - - /** - * Fit to height (proportionally resize to specified height) - * - * @param int $height - * - * @return SimpleImage - * - */ - public function fit_to_height($height) { - - $aspect_ratio = $this->height / $this->width; - $width = $height / $aspect_ratio; - - return $this->resize($width, $height); - - } - - /** - * Fit to width (proportionally resize to specified width) - * - * @param int $width - * - * @return SimpleImage - * - */ - public function fit_to_width($width) { - - $aspect_ratio = $this->height / $this->width; - $height = $width * $aspect_ratio; - - return $this->resize($width, $height); - - } - - /** - * Flip an image horizontally or vertically - * - * @param string $direction x|y - * - * @return SimpleImage - * - */ - public function flip($direction) { - - $new = imagecreatetruecolor($this->width, $this->height); - imagealphablending($new, false); - imagesavealpha($new, true); - - switch (strtolower($direction)) { - case 'y': - for ($y = 0; $y < $this->height; $y++) { - imagecopy($new, $this->image, 0, $y, 0, $this->height - $y - 1, $this->width, 1); - } - break; - default: - for ($x = 0; $x < $this->width; $x++) { - imagecopy($new, $this->image, $x, 0, $this->width - $x - 1, 0, 1, $this->height); - } - break; - } - - $this->image = $new; - - return $this; - - } - - /** - * Get the current height - * - * @return int - * - */ - public function get_height() { - return $this->height; - } - - /** - * Get the current orientation - * - * @return string portrait|landscape|square - * - */ - public function get_orientation() { - - if (imagesx($this->image) > imagesy($this->image)) { - return 'landscape'; - } - - if (imagesx($this->image) < imagesy($this->image)) { - return 'portrait'; - } - - return 'square'; - - } - - /** - * Get info about the original image - * - * @return array
 array(
-     *  width        => 320,
-     *  height       => 200,
-     *  orientation  => ['portrait', 'landscape', 'square'],
-     *  exif         => array(...),
-     *  mime         => ['image/jpeg', 'image/gif', 'image/png'],
-     *  format       => ['jpeg', 'gif', 'png']
-     * )
- * - */ - public function get_original_info() { - return $this->original_info; - } - - /** - * Get the current width - * - * @return int - * - */ - public function get_width() { - return $this->width; - } - - /** - * Invert - * - * @return SimpleImage - * - */ - public function invert() { - imagefilter($this->image, IMG_FILTER_NEGATE); - return $this; - } - - /** - * Load an image - * - * @param string $filename Path to image file - * - * @return SimpleImage - * @throws Exception - * - */ - public function load($filename) { - - // Require GD library - if (!extension_loaded('gd')) { - throw new Exception('Required extension GD is not loaded.'); - } - $this->filename = $filename; - return $this->get_meta_data(); - } - - /** - * Load a base64 string as image - * - * @param string $base64string base64 string - * - * @return SimpleImage - * - */ - public function load_base64($base64string) { - if (!extension_loaded('gd')) { - throw new Exception('Required extension GD is not loaded.'); - } - //remove data URI scheme and spaces from base64 string then decode it - $this->imagestring = base64_decode(str_replace(' ', '+',preg_replace('#^data:image/[^;]+;base64,#', '', $base64string))); - $this->image = imagecreatefromstring($this->imagestring); - return $this->get_meta_data(); - } - - /** - * Mean Remove - * - * @return SimpleImage - * - */ - public function mean_remove() { - imagefilter($this->image, IMG_FILTER_MEAN_REMOVAL); - return $this; - } - - /** - * Changes the opacity level of the image - * - * @param float|int $opacity 0-1 - * - * @throws Exception - * - */ - public function opacity($opacity) { - - // Determine opacity - $opacity = $this->keep_within($opacity, 0, 1) * 100; - - // Make a copy of the image - $copy = imagecreatetruecolor($this->width, $this->height); - imagealphablending($copy, false); - imagesavealpha($copy, true); - imagecopy($copy, $this->image, 0, 0, 0, 0, $this->width, $this->height); - - // Create transparent layer - $this->create($this->width, $this->height, array(0, 0, 0, 127)); - - // Merge with specified opacity - $this->imagecopymerge_alpha($this->image, $copy, 0, 0, 0, 0, $this->width, $this->height, $opacity); - imagedestroy($copy); - - return $this; - - } - - /** - * Outputs image without saving - * - * @param null|string $format If omitted or null - format of original file will be used, may be gif|jpg|png - * @param int|null $quality Output image quality in percents 0-100 - * - * @throws Exception - * - */ - public function output($format = null, $quality = null) { - - // Determine quality - $quality = $quality ?: $this->quality; - - // Determine mimetype - switch (strtolower($format)) { - case 'gif': - $mimetype = 'image/gif'; - break; - case 'jpeg': - case 'jpg': - imageinterlace($this->image, true); - $mimetype = 'image/jpeg'; - break; - case 'png': - $mimetype = 'image/png'; - break; - default: - $info = (empty($this->imagestring)) ? getimagesize($this->filename) : getimagesizefromstring($this->imagestring); - $mimetype = $info['mime']; - unset($info); - break; - } - - // Output the image - header('Content-Type: '.$mimetype); - switch ($mimetype) { - case 'image/gif': - imagegif($this->image); - break; - case 'image/jpeg': - imagejpeg($this->image, null, round($quality)); - break; - case 'image/png': - imagepng($this->image, null, round(9 * $quality / 100)); - break; - default: - throw new Exception('Unsupported image format: '.$this->filename); - } - } - - /** - * Outputs image as data base64 to use as img src - * - * @param null|string $format If omitted or null - format of original file will be used, may be gif|jpg|png - * @param int|null $quality Output image quality in percents 0-100 - * - * @return string - * @throws Exception - * - */ - public function output_base64($format = null, $quality = null) { - - // Determine quality - $quality = $quality ?: $this->quality; - - // Determine mimetype - switch (strtolower($format)) { - case 'gif': - $mimetype = 'image/gif'; - break; - case 'jpeg': - case 'jpg': - imageinterlace($this->image, true); - $mimetype = 'image/jpeg'; - break; - case 'png': - $mimetype = 'image/png'; - break; - default: - $info = getimagesize($this->filename); - $mimetype = $info['mime']; - unset($info); - break; - } - - // Output the image - ob_start(); - switch ($mimetype) { - case 'image/gif': - imagegif($this->image); - break; - case 'image/jpeg': - imagejpeg($this->image, null, round($quality)); - break; - case 'image/png': - imagepng($this->image, null, round(9 * $quality / 100)); - break; - default: - throw new Exception('Unsupported image format: '.$this->filename); - } - $image_data = ob_get_contents(); - ob_end_clean(); - - // Returns formatted string for img src - return 'data:'.$mimetype.';base64,'.base64_encode($image_data); - - } - - /** - * Overlay - * - * Overlay an image on top of another, works with 24-bit PNG alpha-transparency - * - * @param string $overlay An image filename or a SimpleImage object - * @param string $position center|top|left|bottom|right|top left|top right|bottom left|bottom right - * @param float|int $opacity Overlay opacity 0-1 - * @param int $x_offset Horizontal offset in pixels - * @param int $y_offset Vertical offset in pixels - * - * @return SimpleImage - * - */ - public function overlay($overlay, $position = 'center', $opacity = 1, $x_offset = 0, $y_offset = 0) { - - // Load overlay image - if( !($overlay instanceof SimpleImage) ) { - $overlay = new SimpleImage($overlay); - } - - // Convert opacity - $opacity = $opacity * 100; - - // Determine position - switch (strtolower($position)) { - case 'top left': - $x = 0 + $x_offset; - $y = 0 + $y_offset; - break; - case 'top right': - $x = $this->width - $overlay->width + $x_offset; - $y = 0 + $y_offset; - break; - case 'top': - $x = ($this->width / 2) - ($overlay->width / 2) + $x_offset; - $y = 0 + $y_offset; - break; - case 'bottom left': - $x = 0 + $x_offset; - $y = $this->height - $overlay->height + $y_offset; - break; - case 'bottom right': - $x = $this->width - $overlay->width + $x_offset; - $y = $this->height - $overlay->height + $y_offset; - break; - case 'bottom': - $x = ($this->width / 2) - ($overlay->width / 2) + $x_offset; - $y = $this->height - $overlay->height + $y_offset; - break; - case 'left': - $x = 0 + $x_offset; - $y = ($this->height / 2) - ($overlay->height / 2) + $y_offset; - break; - case 'right': - $x = $this->width - $overlay->width + $x_offset; - $y = ($this->height / 2) - ($overlay->height / 2) + $y_offset; - break; - case 'center': - default: - $x = ($this->width / 2) - ($overlay->width / 2) + $x_offset; - $y = ($this->height / 2) - ($overlay->height / 2) + $y_offset; - break; - } - - // Perform the overlay - $this->imagecopymerge_alpha($this->image, $overlay->image, $x, $y, 0, 0, $overlay->width, $overlay->height, $opacity); - - return $this; - - } - - /** - * Pixelate - * - * @param int $block_size Size in pixels of each resulting block - * - * @return SimpleImage - * - */ - public function pixelate($block_size = 10) { - imagefilter($this->image, IMG_FILTER_PIXELATE, $block_size, true); - return $this; - } - - /** - * Resize an image to the specified dimensions - * - * @param int $width - * @param int $height - * - * @return SimpleImage - * - */ - public function resize($width, $height) { - - // Generate new GD image - $new = imagecreatetruecolor($width, $height); - - if( $this->original_info['format'] === 'gif' ) { - // Preserve transparency in GIFs - $transparent_index = imagecolortransparent($this->image); - $palletsize = imagecolorstotal($this->image); - if ($transparent_index >= 0 && $transparent_index < $palletsize) { - $transparent_color = imagecolorsforindex($this->image, $transparent_index); - $transparent_index = imagecolorallocate($new, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']); - imagefill($new, 0, 0, $transparent_index); - imagecolortransparent($new, $transparent_index); - } - } else { - // Preserve transparency in PNGs (benign for JPEGs) - imagealphablending($new, false); - imagesavealpha($new, true); - } - - // Resize - imagecopyresampled($new, $this->image, 0, 0, 0, 0, $width, $height, $this->width, $this->height); - - // Update meta data - $this->width = $width; - $this->height = $height; - $this->image = $new; - - return $this; - - } - - /** - * Rotate an image - * - * @param int $angle 0-360 - * @param string $bg_color Hex color string, array(red, green, blue) or array(red, green, blue, alpha). - * Where red, green, blue - integers 0-255, alpha - integer 0-127 - * - * @return SimpleImage - * - */ - public function rotate($angle, $bg_color = '#000000') { - - // Perform the rotation - $rgba = $this->normalize_color($bg_color); - $bg_color = imagecolorallocatealpha($this->image, $rgba['r'], $rgba['g'], $rgba['b'], $rgba['a']); - $new = imagerotate($this->image, -($this->keep_within($angle, -360, 360)), $bg_color); - imagesavealpha($new, true); - imagealphablending($new, true); - - // Update meta data - $this->width = imagesx($new); - $this->height = imagesy($new); - $this->image = $new; - - return $this; - - } - - /** - * Save an image - * - * The resulting format will be determined by the file extension. - * - * @param null|string $filename If omitted - original file will be overwritten - * @param null|int $quality Output image quality in percents 0-100 - * @param null|string $format The format to use; determined by file extension if null - * - * @return SimpleImage - * @throws Exception - * - */ - public function save($filename = null, $quality = null, $format = null) { - - // Determine quality, filename, and format - $quality = $quality ?: $this->quality; - $filename = $filename ?: $this->filename; - if( $format === null ) { - $format = $this->file_ext($filename) ?: $this->original_info['format']; - } - - // Create the image - switch (strtolower($format)) { - case 'gif': - $result = imagegif($this->image, $filename); - break; - case 'jpg': - case 'jpeg': - imageinterlace($this->image, true); - $result = imagejpeg($this->image, $filename, round($quality)); - break; - case 'png': - $result = imagepng($this->image, $filename, round(9 * $quality / 100)); - break; - default: - throw new Exception('Unsupported format'); - } - - if (!$result) { - throw new Exception('Unable to save image: ' . $filename); - } - - return $this; - - } - - /** - * Sepia - * - * @return SimpleImage - * - */ - public function sepia() { - imagefilter($this->image, IMG_FILTER_GRAYSCALE); - imagefilter($this->image, IMG_FILTER_COLORIZE, 100, 50, 0); - return $this; - } - - /** - * Sketch - * - * @return SimpleImage - * - */ - public function sketch() { - imagefilter($this->image, IMG_FILTER_MEAN_REMOVAL); - return $this; - } - - /** - * Smooth - * - * @param int $level Min = -10, max = 10 - * - * @return SimpleImage - * - */ - public function smooth($level) { - imagefilter($this->image, IMG_FILTER_SMOOTH, $this->keep_within($level, -10, 10)); - return $this; - } - - /** - * Add text to an image - * - * @param string $text - * @param string $font_file - * @param float|int $font_size - * @param string $color - * @param string $position - * @param int $x_offset - * @param int $y_offset - * - * @return SimpleImage - * @throws Exception - * - */ - public function text($text, $font_file, $font_size = 12, $color = '#000000', $position = 'center', $x_offset = 0, $y_offset = 0) { - - // todo - this method could be improved to support the text angle - $angle = 0; - - // Determine text color - $rgba = $this->normalize_color($color); - $color = imagecolorallocatealpha($this->image, $rgba['r'], $rgba['g'], $rgba['b'], $rgba['a']); - - // Determine textbox size - $box = imagettfbbox($font_size, $angle, $font_file, $text); - if (empty($box)) { - throw new Exception('Unable to load font: '.$font_file); - } - $box_width = abs($box[6] - $box[2]); - $box_height = abs($box[7] - $box[1]); - - // Determine position - switch (strtolower($position)) { - case 'top left': - $x = 0 + $x_offset; - $y = 0 + $y_offset + $box_height; - break; - case 'top right': - $x = $this->width - $box_width + $x_offset; - $y = 0 + $y_offset + $box_height; - break; - case 'top': - $x = ($this->width / 2) - ($box_width / 2) + $x_offset; - $y = 0 + $y_offset + $box_height; - break; - case 'bottom left': - $x = 0 + $x_offset; - $y = $this->height - $box_height + $y_offset + $box_height; - break; - case 'bottom right': - $x = $this->width - $box_width + $x_offset; - $y = $this->height - $box_height + $y_offset + $box_height; - break; - case 'bottom': - $x = ($this->width / 2) - ($box_width / 2) + $x_offset; - $y = $this->height - $box_height + $y_offset + $box_height; - break; - case 'left': - $x = 0 + $x_offset; - $y = ($this->height / 2) - (($box_height / 2) - $box_height) + $y_offset; - break; - case 'right'; - $x = $this->width - $box_width + $x_offset; - $y = ($this->height / 2) - (($box_height / 2) - $box_height) + $y_offset; - break; - case 'center': - default: - $x = ($this->width / 2) - ($box_width / 2) + $x_offset; - $y = ($this->height / 2) - (($box_height / 2) - $box_height) + $y_offset; - break; - } - - // Add the text - imagesavealpha($this->image, true); - imagealphablending($this->image, true); - imagettftext($this->image, $font_size, $angle, $x, $y, $color, $font_file, $text); - - return $this; - - } - - /** - * Thumbnail - * - * This function attempts to get the image to as close to the provided dimensions as possible, and then crops the - * remaining overflow (from the center) to get the image to be the size specified. Useful for generating thumbnails. - * - * @param int $width - * @param int|null $height If omitted - assumed equal to $width - * - * @return SimpleImage - * - */ - public function thumbnail($width, $height = null) { - - // Determine height - $height = $height ?: $width; - - // Determine aspect ratios - $current_aspect_ratio = $this->height / $this->width; - $new_aspect_ratio = $height / $width; - - // Fit to height/width - if ($new_aspect_ratio > $current_aspect_ratio) { - $this->fit_to_height($height); - } else { - $this->fit_to_width($width); - } - $left = floor(($this->width / 2) - ($width / 2)); - $top = floor(($this->height / 2) - ($height / 2)); - - // Return trimmed image - return $this->crop($left, $top, $width + $left, $height + $top); - - } - - /** - * Returns the file extension of the specified file - * - * @param string $filename - * - * @return string - * - */ - protected function file_ext($filename) { - - if (!preg_match('/\./', $filename)) { - return ''; - } - - return preg_replace('/^.*\./', '', $filename); - - } - - /** - * Get meta data of image or base64 string - * - * @return SimpleImage - * @throws Exception - * - */ - protected function get_meta_data() { - //gather meta data - if(empty($this->imagestring)) { - $info = getimagesize($this->filename); - - switch ($info['mime']) { - case 'image/gif': - $this->image = imagecreatefromgif($this->filename); - break; - case 'image/jpeg': - $this->image = imagecreatefromjpeg($this->filename); - break; - case 'image/png': - $this->image = imagecreatefrompng($this->filename); - break; - default: - throw new Exception('Invalid image: '.$this->filename); - } - } elseif (function_exists('getimagesizefromstring')) { - $info = getimagesizefromstring($this->imagestring); - } else { - throw new Exception('PHP 5.4 is required to use method getimagesizefromstring'); - } - - $this->original_info = array( - 'width' => $info[0], - 'height' => $info[1], - 'orientation' => $this->get_orientation(), - 'exif' => function_exists('exif_read_data') && $info['mime'] === 'image/jpeg' && $this->imagestring === null ? $this->exif = @exif_read_data($this->filename) : null, - 'format' => preg_replace('/^image\//', '', $info['mime']), - 'mime' => $info['mime'] - ); - $this->width = $info[0]; - $this->height = $info[1]; - - imagesavealpha($this->image, true); - imagealphablending($this->image, true); - - return $this; - - } - - /** - * Same as PHP's imagecopymerge() function, except preserves alpha-transparency in 24-bit PNGs - * - * @param $dst_im - * @param $src_im - * @param $dst_x - * @param $dst_y - * @param $src_x - * @param $src_y - * @param $src_w - * @param $src_h - * @param $pct - * - * @link http://www.php.net/manual/en/function.imagecopymerge.php#88456 - * - */ - protected function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct) { - - // Get image width and height and percentage - $pct /= 100; - $w = imagesx($src_im); - $h = imagesy($src_im); - - // Turn alpha blending off - imagealphablending($src_im, false); - - // Find the most opaque pixel in the image (the one with the smallest alpha value) - $minalpha = 127; - for ($x = 0; $x < $w; $x++) { - for ($y = 0; $y < $h; $y++) { - $alpha = (imagecolorat($src_im, $x, $y) >> 24) & 0xFF; - if ($alpha < $minalpha) { - $minalpha = $alpha; - } - } - } - - // Loop through image pixels and modify alpha for each - for ($x = 0; $x < $w; $x++) { - for ($y = 0; $y < $h; $y++) { - // Get current alpha value (represents the TANSPARENCY!) - $colorxy = imagecolorat($src_im, $x, $y); - $alpha = ($colorxy >> 24) & 0xFF; - // Calculate new alpha - if ($minalpha !== 127) { - $alpha = 127 + 127 * $pct * ($alpha - 127) / (127 - $minalpha); - } else { - $alpha += 127 * $pct; - } - // Get the color index with new alpha - $alphacolorxy = imagecolorallocatealpha($src_im, ($colorxy >> 16) & 0xFF, ($colorxy >> 8) & 0xFF, $colorxy & 0xFF, $alpha); - // Set pixel with the new color + opacity - if (!imagesetpixel($src_im, $x, $y, $alphacolorxy)) { - return; - } - } - } - - // Copy it - imagesavealpha($dst_im, true); - imagealphablending($dst_im, true); - imagesavealpha($src_im, true); - imagealphablending($src_im, true); - imagecopy($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h); - - } - - /** - * Ensures $value is always within $min and $max range. - * - * If lower, $min is returned. If higher, $max is returned. - * - * @param int|float $value - * @param int|float $min - * @param int|float $max - * - * @return int|float - * - */ - protected function keep_within($value, $min, $max) { - - if ($value < $min) { - return $min; - } - - if ($value > $max) { - return $max; - } - - return $value; - - } - - /** - * Converts a hex color value to its RGB equivalent - * - * @param string $color Hex color string, array(red, green, blue) or array(red, green, blue, alpha). - * Where red, green, blue - integers 0-255, alpha - integer 0-127 - * - * @return array|bool - * - */ - protected function normalize_color($color) { - - if (is_string($color)) { - - $color = trim($color, '#'); - - if (strlen($color) == 6) { - list($r, $g, $b) = array( - $color[0].$color[1], - $color[2].$color[3], - $color[4].$color[5] - ); - } elseif (strlen($color) == 3) { - list($r, $g, $b) = array( - $color[0].$color[0], - $color[1].$color[1], - $color[2].$color[2] - ); - } else { - return false; - } - return array( - 'r' => hexdec($r), - 'g' => hexdec($g), - 'b' => hexdec($b), - 'a' => 0 - ); - - } elseif (is_array($color) && (count($color) == 3 || count($color) == 4)) { - - if (isset($color['r'], $color['g'], $color['b'])) { - return array( - 'r' => $this->keep_within($color['r'], 0, 255), - 'g' => $this->keep_within($color['g'], 0, 255), - 'b' => $this->keep_within($color['b'], 0, 255), - 'a' => $this->keep_within(isset($color['a']) ? $color['a'] : 0, 0, 127) - ); - } elseif (isset($color[0], $color[1], $color[2])) { - return array( - 'r' => $this->keep_within($color[0], 0, 255), - 'g' => $this->keep_within($color[1], 0, 255), - 'b' => $this->keep_within($color[2], 0, 255), - 'a' => $this->keep_within(isset($color[3]) ? $color[3] : 0, 0, 127) - ); - } - - } - return false; - } - -} diff --git a/kirby/toolkit/vendors/mimereader/mimereader.php b/kirby/toolkit/vendors/mimereader/mimereader.php deleted file mode 100644 index 6752376..0000000 --- a/kirby/toolkit/vendors/mimereader/mimereader.php +++ /dev/null @@ -1,776 +0,0 @@ -file = $file; - - if ( empty( self::$binary_characters ) ) { - self::$binary_characters .= "\x00\x01\x02\x03\x04\x05\x06\x07\0x08\x0B\x0E\x0F\x10\x11"; - self::$binary_characters .= "\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1C\x1D\x1E\x1F"; - } - if ( empty( self::$whitespace_characters ) ) { - self::$whitespace_characters .= "\x09\x0A\x0C\x0D\x20"; - } - if ( empty( self::$tag_terminating_characters ) ) { - self::$tag_terminating_characters .= "\x20\x3E"; - } - - if ( is_null( self::$image ) ) { - $image = &self::$image; - $image = array(); - - // Windows Icon - $image[] = array ( - 'mime' => 'image/vnd.microsoft.icon', - 'pattern' => "\x00\x00\x01\x00", - 'mask' => "\xFF\xFF\xFF\xFF", - 'ignore' => '', // none - ); - // "BM" - BMP signature - $image[] = array ( - 'mime' => 'image/bmp', - 'pattern' => "\x42\x4D", - 'mask' => "\xFF\xFF", - 'ignore' => '' - ); - // "GIF87a" - GIF signature - $image[] = array ( - 'mime' => 'image/gif', - 'pattern' => "\x47\x49\x46\x38\x37\x61", - 'mask' => "\xFF\xFF\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // "GIF89a" - GIF signature - $image[] = array ( - 'mime' => 'image/gif', - 'pattern' => "\x47\x49\x46\x38\x39\x61", - 'mask' => "\xFF\xFF\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // "RIFF" followed by 4 bytes followed by "WEBPVP" - $image[] = array ( - 'mime' => 'image/webp', - 'pattern' => "\x52\x49\x46\x46\x00\x00\x00\x00\x57\x45\x42\x50\x56\x50", - 'mask' => "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // A byte with only the highest bit set followed by the string "PNG" followed by CR LF SUB LF - PNG signature - $image[] = array ( - 'mime' => 'image/png', - 'pattern' => "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", - 'mask' => "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // JPEG start of image marker followed by another marker - $image[] = array ( - 'mime' => 'image/jpeg', - 'pattern' => "\xFF\xD8\xFF", - 'mask' => "\xFF\xFF\xFF", - 'ignore' => '' - ); - // PSD signature - $image[] = array ( - 'mime' => 'application/psd', - 'pattern' => "\x38\x42\x50\x53", - 'mask' => "\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - } - if ( is_null( self::$media ) ) { - $media = &self::$media; - $media = array(); - - // The WebM signature - $media[] = array ( - 'mime' => 'video/webm', - 'pattern' => "\x1A\x45\xDF\xA3", - 'mask' => "\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // The .snd signature - $media[] = array ( - 'mime' => 'audio/basic', - 'pattern' => "\x2E\x73\x6E\x64", - 'mask' => "\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // "FORM" followed by 4 bytes followed by "AIFF" - the AIFF signature - $media[] = array ( - 'mime' => 'audio/aiff', - 'pattern' => "\x46\x4F\x52\x4D\x00\x00\x00\x00\x41\x49\x46\x46", - 'mask' => "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // MP3 without ID3 tag /****** UNTESTED ******/ - $media[] = array ( - 'mime' => 'audio/mpeg', - 'pattern' => "\xFF\xFB", - 'mask' => "\xFF\xFF", - 'ignore' => '' - ); - // "ID3" and the ID3v2-tagged MP3 signature - $media[] = array ( - 'mime' => 'audio/mpeg', - 'pattern' => "\x49\x44\x33", - 'mask' => "\xFF\xFF\xFF", - 'ignore' => '' - ); - // "OggS" followed by NUL - The OGG signature - $media[] = array ( - 'mime' => 'application/ogg', - 'pattern' => "\x4F\x67\x67\x53\x00", - 'mask' => "\xFF\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // "MThd" followed by 4 bytes representing the number 6 in 32 bits (big endian) - MIDI signature - $media[] = array ( - 'mime' => 'audio/midi', - 'pattern' => "\x4D\x54\x68\x64\x00\x00\x00\x06", - 'mask' => "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // "RIFF" followed by 4 bytes followed by "AVI" - AVI signature - $media[] = array ( - 'mime' => 'video/avi', - 'pattern' => "\x52\x49\x46\x46\x00\x00\x00\x00\x41\x56\x49\x20", - 'mask' => "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // "RIFF" followed by 4 bytes followed by "WAVE" - WAVE signature - $media[] = array ( - 'mime' => 'audio/wave', - 'pattern' => "\x52\x49\x46\x46\x00\x00\x00\x00\x57\x41\x56\x45", - 'mask' => "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - } - if ( is_null( self::$fonts ) ) { - $fonts = &self::$fonts; - $fonts = array(); - - // 34 bytes followed by "LP" - Opentype signature - $fonts[] = array ( - 'mime' => 'application/vnd.ms-fontobject', - 'pattern' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" . - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4C\x50", - 'mask' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" . - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF", - 'ignore' => '' - ); - // 4 bytes representing version type 1 of true type font - $fonts[] = array ( - 'mime' => 'application/font-ttf', - 'pattern' => "\x00\x01\x00\x00", - 'mask' => "\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // "OTTO" - Opentype signature - $fonts[] = array ( - 'mime' => 'application/font-off', // application/vnd.ms-opentype - 'pattern' => "\x4F\x54\x54\x4F", - 'mask' => "\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // "ttcf" - Truetype Collection signature - $fonts[] = array ( - 'mime' => 'application/x-font-truetype-collection', - 'pattern' => "\x74\x74\x63\x66", - 'mask' => "\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // 'wOFF' - Web Open Font Format signature - $fonts[] = array ( - 'mime' => 'application/font-woff', - 'pattern' => "\x77\x4F\x46\x46", - 'mask' => "\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - } - if ( is_null( self::$archive ) ) { - $archive = &self::$archive; - $archive = array(); - - // GZIP signature - $archive[] = array ( - 'mime' => 'application/x-gzip', - 'pattern' => "\x1F\x8B\x08", - 'mask' => "\xFF\xFF\xFF", - 'ignore' => '' - ); - // "PK" followed by ETX, EOT - ZIP signature - $archive[] = array ( - 'mime' => 'application/zip', - 'pattern' => "\x50\x4B\x03\x04", - 'mask' => "\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // "Rar " followed by SUB, BEL, NUL - RAR signature - $archive[] = array ( - 'mime' => 'application/x-rar-compressed', - 'pattern' => "\x52\x61\x72\x20\x1A\x07\x00", - 'mask' => "\xFF\xFF\xFF\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - } - if ( is_null( self::$text ) ) { - $text = &self::$text; - $text = array(); - - // "%!PS-Adobe-" - Postscript signature - $text[] = array ( - 'mime' => 'application/postscript', - 'pattern' => "\x25\x50\x53\x2D\x41\x64\x6F\x62\x65", - 'mask' => "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - // UTF-16 Big Endian BOM text - $text[] = array ( - 'mime' => 'text/plain', - 'pattern' => "\xFF\xFE", - 'mask' => "\xFF\xFF", - 'ignore' => '' - ); - // UTF-16 Little Endian BOM text - $text[] = array ( - 'mime' => 'text/plain', - 'pattern' => "\xFE\xFF", - 'mask' => "\xFF\xFF", - 'ignore' => '' - ); - // UTF-8 BOM text - $text[] = array ( - 'mime' => 'text/plain', - 'pattern' => "\xEF\xBB\xBF", - 'mask' => "\xFF\xFF\xFF", - 'ignore' => '' - ); - } - if ( is_null( self::$others ) ) { - $others = &self::$others; - $others = array(); - - $others[] = array ( - 'mime' => 'WINDOWS EXECUTABLE', - 'pattern' => "\x4D\x5A", - 'mask' => "\xFF\xFF", - 'ignore' => '' - ); - $others[] = array ( - 'mime' => 'EXEC_LINKABLE', - 'pattern' => "\x7F\x45\x4C\x46", - 'mask' => "\xFF\xFF\xFF\xFF", - 'ignore' => '' - ); - - } - if ( is_null( self::$unknown ) ) { - $unknown = &self::$unknown; - $unknown = array(); - - // " 'text/html', - 'pattern' => "\x3C\x21\x44\x4F\x43\x54\x59\x50\x45\x20\x48\x54\x4D\x4C", - 'mask' => "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x48\x54\x4D\x4C", - 'mask' => "\xFF\xFF\xFF\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x48\x45\x41\x44", - 'mask' => "\xFF\xFF\xFF\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x53\x43\x52\x49\x50\x54", - 'mask' => "\xFF\xFF\xFF\xFF\xFF\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x49\x46\x52\x41\x4D\x45", - 'mask' => "\xFF\xFF\xFF\xFF\xFF\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x48\x31", - 'mask' => "\xFF\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x44\x49\x56", - 'mask' => "\xFF\xFF\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x46\x4F\x4E\x54", - 'mask' => "\xFF\xFF\xFF\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x54\x41\x42\x4C\x45", - 'mask' => "\xFF\xFF\xFF\xFF\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x41", - 'mask' => "\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x53\x54\x59\x4C\x45", - 'mask' => "\xFF\xFF\xFF\xFF\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x54\x49\x54\x4C\x45", - 'mask' => "\xFF\xFF\xFF\xFF\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x42", - 'mask' => "\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x42\x4F\x44\x59", - 'mask' => "\xFF\xFF\xFF\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x42\x52", - 'mask' => "\xFF\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // " 'text/html', - 'pattern' => "\x3C\x50", - 'mask' => "\xFF\xFF", - 'ignore' => self::$whitespace_characters - ); - // "$/', $Line['text'])) - { - $Block['closed'] = true; - } - - return $Block; - } - } - - protected function blockCommentContinue($Line, array $Block) - { - if (isset($Block['closed'])) - { - return; - } - - $Block['markup'] .= "\n" . $Line['body']; - - if (preg_match('/-->$/', $Line['text'])) - { - $Block['closed'] = true; - } - - return $Block; - } - - # - # Fenced Code - - protected function blockFencedCode($Line) - { - if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches)) - { - $Element = array( - 'name' => 'code', - 'text' => '', - ); - - if (isset($matches[1])) - { - $class = 'language-'.$matches[1]; - - $Element['attributes'] = array( - 'class' => $class, - ); - } - - $Block = array( - 'char' => $Line['text'][0], - 'element' => array( - 'name' => 'pre', - 'handler' => 'element', - 'text' => $Element, - ), - ); - - return $Block; - } - } - - protected function blockFencedCodeContinue($Line, $Block) - { - if (isset($Block['complete'])) - { - return; - } - - if (isset($Block['interrupted'])) - { - $Block['element']['text']['text'] .= "\n"; - - unset($Block['interrupted']); - } - - if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text'])) - { - $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1); - - $Block['complete'] = true; - - return $Block; - } - - $Block['element']['text']['text'] .= "\n".$Line['body'];; - - return $Block; - } - - protected function blockFencedCodeComplete($Block) - { - $text = $Block['element']['text']['text']; - - $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8'); - - $Block['element']['text']['text'] = $text; - - return $Block; - } - - # - # Header - - protected function blockHeader($Line) - { - if (isset($Line['text'][1])) - { - $level = 1; - - while (isset($Line['text'][$level]) and $Line['text'][$level] === '#') - { - $level ++; - } - - if ($level > 6) - { - return; - } - - $text = trim($Line['text'], '# '); - - $Block = array( - 'element' => array( - 'name' => 'h' . min(6, $level), - 'text' => $text, - 'handler' => 'line', - ), - ); - - return $Block; - } - } - - # - # List - - protected function blockList($Line) - { - list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]'); - - if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches)) - { - $Block = array( - 'indent' => $Line['indent'], - 'pattern' => $pattern, - 'element' => array( - 'name' => $name, - 'handler' => 'elements', - ), - ); - - $Block['li'] = array( - 'name' => 'li', - 'handler' => 'li', - 'text' => array( - $matches[2], - ), - ); - - $Block['element']['text'] []= & $Block['li']; - - return $Block; - } - } - - protected function blockListContinue($Line, array $Block) - { - if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches)) - { - if (isset($Block['interrupted'])) - { - $Block['li']['text'] []= ''; - - unset($Block['interrupted']); - } - - unset($Block['li']); - - $text = isset($matches[1]) ? $matches[1] : ''; - - $Block['li'] = array( - 'name' => 'li', - 'handler' => 'li', - 'text' => array( - $text, - ), - ); - - $Block['element']['text'] []= & $Block['li']; - - return $Block; - } - - if ($Line['text'][0] === '[' and $this->blockReference($Line)) - { - return $Block; - } - - if ( ! isset($Block['interrupted'])) - { - $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); - - $Block['li']['text'] []= $text; - - return $Block; - } - - if ($Line['indent'] > 0) - { - $Block['li']['text'] []= ''; - - $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); - - $Block['li']['text'] []= $text; - - unset($Block['interrupted']); - - return $Block; - } - } - - # - # Quote - - protected function blockQuote($Line) - { - if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches)) - { - $Block = array( - 'element' => array( - 'name' => 'blockquote', - 'handler' => 'lines', - 'text' => (array) $matches[1], - ), - ); - - return $Block; - } - } - - protected function blockQuoteContinue($Line, array $Block) - { - if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches)) - { - if (isset($Block['interrupted'])) - { - $Block['element']['text'] []= ''; - - unset($Block['interrupted']); - } - - $Block['element']['text'] []= $matches[1]; - - return $Block; - } - - if ( ! isset($Block['interrupted'])) - { - $Block['element']['text'] []= $Line['text']; - - return $Block; - } - } - - # - # Rule - - protected function blockRule($Line) - { - if (preg_match('/^(['.$Line['text'][0].'])([ ]*\1){2,}[ ]*$/', $Line['text'])) - { - $Block = array( - 'element' => array( - 'name' => 'hr' - ), - ); - - return $Block; - } - } - - # - # Setext - - protected function blockSetextHeader($Line, array $Block = null) - { - if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted'])) - { - return; - } - - if (chop($Line['text'], $Line['text'][0]) === '') - { - $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2'; - - return $Block; - } - } - - # - # Markup - - protected function blockMarkup($Line) - { - if ($this->markupEscaped) - { - return; - } - - if (preg_match('/^<(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches)) - { - $element = strtolower($matches[1]); - - if (in_array($element, $this->textLevelElements)) - { - return; - } - - $Block = array( - 'name' => $matches[1], - 'depth' => 0, - 'markup' => $Line['text'], - ); - - $length = strlen($matches[0]); - - $remainder = substr($Line['text'], $length); - - if (trim($remainder) === '') - { - if (isset($matches[2]) or in_array($matches[1], $this->voidElements)) - { - $Block['closed'] = true; - - $Block['void'] = true; - } - } - else - { - if (isset($matches[2]) or in_array($matches[1], $this->voidElements)) - { - return; - } - - if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder)) - { - $Block['closed'] = true; - } - } - - return $Block; - } - } - - protected function blockMarkupContinue($Line, array $Block) - { - if (isset($Block['closed'])) - { - return; - } - - if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open - { - $Block['depth'] ++; - } - - if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close - { - if ($Block['depth'] > 0) - { - $Block['depth'] --; - } - else - { - $Block['closed'] = true; - } - } - - if (isset($Block['interrupted'])) - { - $Block['markup'] .= "\n"; - - unset($Block['interrupted']); - } - - $Block['markup'] .= "\n".$Line['body']; - - return $Block; - } - - # - # Reference - - protected function blockReference($Line) - { - if (preg_match('/^\[(.+?)\]:[ ]*?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches)) - { - $id = strtolower($matches[1]); - - $Data = array( - 'url' => $matches[2], - 'title' => null, - ); - - if (isset($matches[3])) - { - $Data['title'] = $matches[3]; - } - - $this->DefinitionData['Reference'][$id] = $Data; - - $Block = array( - 'hidden' => true, - ); - - return $Block; - } - } - - # - # Table - - protected function blockTable($Line, array $Block = null) - { - if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted'])) - { - return; - } - - if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '') - { - $alignments = array(); - - $divider = $Line['text']; - - $divider = trim($divider); - $divider = trim($divider, '|'); - - $dividerCells = explode('|', $divider); - - foreach ($dividerCells as $dividerCell) - { - $dividerCell = trim($dividerCell); - - if ($dividerCell === '') - { - continue; - } - - $alignment = null; - - if ($dividerCell[0] === ':') - { - $alignment = 'left'; - } - - if (substr($dividerCell, - 1) === ':') - { - $alignment = $alignment === 'left' ? 'center' : 'right'; - } - - $alignments []= $alignment; - } - - # ~ - - $HeaderElements = array(); - - $header = $Block['element']['text']; - - $header = trim($header); - $header = trim($header, '|'); - - $headerCells = explode('|', $header); - - foreach ($headerCells as $index => $headerCell) - { - $headerCell = trim($headerCell); - - $HeaderElement = array( - 'name' => 'th', - 'text' => $headerCell, - 'handler' => 'line', - ); - - if (isset($alignments[$index])) - { - $alignment = $alignments[$index]; - - $HeaderElement['attributes'] = array( - 'style' => 'text-align: '.$alignment.';', - ); - } - - $HeaderElements []= $HeaderElement; - } - - # ~ - - $Block = array( - 'alignments' => $alignments, - 'identified' => true, - 'element' => array( - 'name' => 'table', - 'handler' => 'elements', - ), - ); - - $Block['element']['text'] []= array( - 'name' => 'thead', - 'handler' => 'elements', - ); - - $Block['element']['text'] []= array( - 'name' => 'tbody', - 'handler' => 'elements', - 'text' => array(), - ); - - $Block['element']['text'][0]['text'] []= array( - 'name' => 'tr', - 'handler' => 'elements', - 'text' => $HeaderElements, - ); - - return $Block; - } - } - - protected function blockTableContinue($Line, array $Block) - { - if (isset($Block['interrupted'])) - { - return; - } - - if ($Line['text'][0] === '|' or strpos($Line['text'], '|')) - { - $Elements = array(); - - $row = $Line['text']; - - $row = trim($row); - $row = trim($row, '|'); - - preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches); - - foreach ($matches[0] as $index => $cell) - { - $cell = trim($cell); - - $Element = array( - 'name' => 'td', - 'handler' => 'line', - 'text' => $cell, - ); - - if (isset($Block['alignments'][$index])) - { - $Element['attributes'] = array( - 'style' => 'text-align: '.$Block['alignments'][$index].';', - ); - } - - $Elements []= $Element; - } - - $Element = array( - 'name' => 'tr', - 'handler' => 'elements', - 'text' => $Elements, - ); - - $Block['element']['text'][1]['text'] []= $Element; - - return $Block; - } - } - - # - # ~ - # - - protected function paragraph($Line) - { - $Block = array( - 'element' => array( - 'name' => 'p', - 'text' => $Line['text'], - 'handler' => 'line', - ), - ); - - return $Block; - } - - # - # Inline Elements - # - - protected $InlineTypes = array( - '"' => array('SpecialCharacter'), - '!' => array('Image'), - '&' => array('SpecialCharacter'), - '*' => array('Emphasis'), - ':' => array('Url'), - '<' => array('UrlTag', 'EmailTag', 'Markup', 'SpecialCharacter'), - '>' => array('SpecialCharacter'), - '[' => array('Link'), - '_' => array('Emphasis'), - '`' => array('Code'), - '~' => array('Strikethrough'), - '\\' => array('EscapeSequence'), - ); - - # ~ - - protected $inlineMarkerList = '!"*_&[:<>`~\\'; - - # - # ~ - # - - public function line($text) - { - $markup = ''; - - # $excerpt is based on the first occurrence of a marker - - while ($excerpt = strpbrk($text, $this->inlineMarkerList)) - { - $marker = $excerpt[0]; - - $markerPosition = strpos($text, $marker); - - $Excerpt = array('text' => $excerpt, 'context' => $text); - - foreach ($this->InlineTypes[$marker] as $inlineType) - { - $Inline = $this->{'inline'.$inlineType}($Excerpt); - - if ( ! isset($Inline)) - { - continue; - } - - # makes sure that the inline belongs to "our" marker - - if (isset($Inline['position']) and $Inline['position'] > $markerPosition) - { - continue; - } - - # sets a default inline position - - if ( ! isset($Inline['position'])) - { - $Inline['position'] = $markerPosition; - } - - # the text that comes before the inline - $unmarkedText = substr($text, 0, $Inline['position']); - - # compile the unmarked text - $markup .= $this->unmarkedText($unmarkedText); - - # compile the inline - $markup .= isset($Inline['markup']) ? $Inline['markup'] : $this->element($Inline['element']); - - # remove the examined text - $text = substr($text, $Inline['position'] + $Inline['extent']); - - continue 2; - } - - # the marker does not belong to an inline - - $unmarkedText = substr($text, 0, $markerPosition + 1); - - $markup .= $this->unmarkedText($unmarkedText); - - $text = substr($text, $markerPosition + 1); - } - - $markup .= $this->unmarkedText($text); - - return $markup; - } - - # - # ~ - # - - protected function inlineCode($Excerpt) - { - $marker = $Excerpt['text'][0]; - - if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(? strlen($matches[0]), - 'element' => array( - 'name' => 'code', - 'text' => $text, - ), - ); - } - } - - protected function inlineEmailTag($Excerpt) - { - if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $Excerpt['text'], $matches)) - { - $url = $matches[1]; - - if ( ! isset($matches[2])) - { - $url = 'mailto:' . $url; - } - - return array( - 'extent' => strlen($matches[0]), - 'element' => array( - 'name' => 'a', - 'text' => $matches[1], - 'attributes' => array( - 'href' => $url, - ), - ), - ); - } - } - - protected function inlineEmphasis($Excerpt) - { - if ( ! isset($Excerpt['text'][1])) - { - return; - } - - $marker = $Excerpt['text'][0]; - - if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches)) - { - $emphasis = 'strong'; - } - elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches)) - { - $emphasis = 'em'; - } - else - { - return; - } - - return array( - 'extent' => strlen($matches[0]), - 'element' => array( - 'name' => $emphasis, - 'handler' => 'line', - 'text' => $matches[1], - ), - ); - } - - protected function inlineEscapeSequence($Excerpt) - { - if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters)) - { - return array( - 'markup' => $Excerpt['text'][1], - 'extent' => 2, - ); - } - } - - protected function inlineImage($Excerpt) - { - if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[') - { - return; - } - - $Excerpt['text']= substr($Excerpt['text'], 1); - - $Link = $this->inlineLink($Excerpt); - - if ($Link === null) - { - return; - } - - $Inline = array( - 'extent' => $Link['extent'] + 1, - 'element' => array( - 'name' => 'img', - 'attributes' => array( - 'src' => $Link['element']['attributes']['href'], - 'alt' => $Link['element']['text'], - ), - ), - ); - - $Inline['element']['attributes'] += $Link['element']['attributes']; - - unset($Inline['element']['attributes']['href']); - - return $Inline; - } - - protected function inlineLink($Excerpt) - { - $Element = array( - 'name' => 'a', - 'handler' => 'line', - 'text' => null, - 'attributes' => array( - 'href' => null, - 'title' => null, - ), - ); - - $extent = 0; - - $remainder = $Excerpt['text']; - - if (preg_match('/\[((?:[^][]|(?R))*)\]/', $remainder, $matches)) - { - $Element['text'] = $matches[1]; - - $extent += strlen($matches[0]); - - $remainder = substr($remainder, $extent); - } - else - { - return; - } - - if (preg_match('/^[(]((?:[^ ()]|[(][^ )]+[)])+)(?:[ ]+("[^"]*"|\'[^\']*\'))?[)]/', $remainder, $matches)) - { - $Element['attributes']['href'] = $matches[1]; - - if (isset($matches[2])) - { - $Element['attributes']['title'] = substr($matches[2], 1, - 1); - } - - $extent += strlen($matches[0]); - } - else - { - if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches)) - { - $definition = strlen($matches[1]) ? $matches[1] : $Element['text']; - $definition = strtolower($definition); - - $extent += strlen($matches[0]); - } - else - { - $definition = strtolower($Element['text']); - } - - if ( ! isset($this->DefinitionData['Reference'][$definition])) - { - return; - } - - $Definition = $this->DefinitionData['Reference'][$definition]; - - $Element['attributes']['href'] = $Definition['url']; - $Element['attributes']['title'] = $Definition['title']; - } - - $Element['attributes']['href'] = str_replace(array('&', '<'), array('&', '<'), $Element['attributes']['href']); - - return array( - 'extent' => $extent, - 'element' => $Element, - ); - } - - protected function inlineMarkup($Excerpt) - { - if ($this->markupEscaped or strpos($Excerpt['text'], '>') === false) - { - return; - } - - if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w*[ ]*>/s', $Excerpt['text'], $matches)) - { - return array( - 'markup' => $matches[0], - 'extent' => strlen($matches[0]), - ); - } - - if ($Excerpt['text'][1] === '!' and preg_match('/^/s', $Excerpt['text'], $matches)) - { - return array( - 'markup' => $matches[0], - 'extent' => strlen($matches[0]), - ); - } - - if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches)) - { - return array( - 'markup' => $matches[0], - 'extent' => strlen($matches[0]), - ); - } - } - - protected function inlineSpecialCharacter($Excerpt) - { - if ($Excerpt['text'][0] === '&' and ! preg_match('/^&#?\w+;/', $Excerpt['text'])) - { - return array( - 'markup' => '&', - 'extent' => 1, - ); - } - - $SpecialCharacter = array('>' => 'gt', '<' => 'lt', '"' => 'quot'); - - if (isset($SpecialCharacter[$Excerpt['text'][0]])) - { - return array( - 'markup' => '&'.$SpecialCharacter[$Excerpt['text'][0]].';', - 'extent' => 1, - ); - } - } - - protected function inlineStrikethrough($Excerpt) - { - if ( ! isset($Excerpt['text'][1])) - { - return; - } - - if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches)) - { - return array( - 'extent' => strlen($matches[0]), - 'element' => array( - 'name' => 'del', - 'text' => $matches[1], - 'handler' => 'line', - ), - ); - } - } - - protected function inlineUrl($Excerpt) - { - if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/') - { - return; - } - - if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) - { - $Inline = array( - 'extent' => strlen($matches[0][0]), - 'position' => $matches[0][1], - 'element' => array( - 'name' => 'a', - 'text' => $matches[0][0], - 'attributes' => array( - 'href' => $matches[0][0], - ), - ), - ); - - return $Inline; - } - } - - protected function inlineUrlTag($Excerpt) - { - if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches)) - { - $url = str_replace(array('&', '<'), array('&', '<'), $matches[1]); - - return array( - 'extent' => strlen($matches[0]), - 'element' => array( - 'name' => 'a', - 'text' => $url, - 'attributes' => array( - 'href' => $url, - ), - ), - ); - } - } - - # ~ - - protected function unmarkedText($text) - { - if ($this->breaksEnabled) - { - $text = preg_replace('/[ ]*\n/', "
\n", $text); - } - else - { - $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "
\n", $text); - $text = str_replace(" \n", "\n", $text); - } - - return $text; - } - - # - # Handlers - # - - protected function element(array $Element) - { - $markup = '<'.$Element['name']; - - if (isset($Element['attributes'])) - { - foreach ($Element['attributes'] as $name => $value) - { - if ($value === null) - { - continue; - } - - $markup .= ' '.$name.'="'.$value.'"'; - } - } - - if (isset($Element['text'])) - { - $markup .= '>'; - - if (isset($Element['handler'])) - { - $markup .= $this->{$Element['handler']}($Element['text']); - } - else - { - $markup .= $Element['text']; - } - - $markup .= ''; - } - else - { - $markup .= ' />'; - } - - return $markup; - } - - protected function elements(array $Elements) - { - $markup = ''; - - foreach ($Elements as $Element) - { - $markup .= "\n" . $this->element($Element); - } - - $markup .= "\n"; - - return $markup; - } - - # ~ - - protected function li($lines) - { - $markup = $this->lines($lines); - - $trimmedMarkup = trim($markup); - - if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '

') - { - $markup = $trimmedMarkup; - $markup = substr($markup, 3); - - $position = strpos($markup, "

"); - - $markup = substr_replace($markup, '', $position, 4); - } - - return $markup; - } - - # - # Deprecated Methods - # - - function parse($text) - { - $markup = $this->text($text); - - return $markup; - } - - # - # Static Methods - # - - static function instance($name = 'default') - { - if (isset(self::$instances[$name])) - { - return self::$instances[$name]; - } - - $instance = new static(); - - self::$instances[$name] = $instance; - - return $instance; - } - - private static $instances = array(); - - # - # Fields - # - - protected $DefinitionData; - - # - # Read-Only - - protected $specialCharacters = array( - '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', '|', - ); - - protected $StrongRegex = array( - '*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s', - '_' => '/^__((?:\\\\_|[^_]|_[^_]*_)+?)__(?!_)/us', - ); - - protected $EmRegex = array( - '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s', - '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us', - ); - - protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*(?:\s*=\s*(?:[^"\'=<>`\s]+|"[^"]*"|\'[^\']*\'))?'; - - protected $voidElements = array( - 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', - ); - - protected $textLevelElements = array( - 'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont', - 'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing', - 'i', 'rp', 'del', 'code', 'strike', 'marquee', - 'q', 'rt', 'ins', 'font', 'strong', - 's', 'tt', 'sub', 'mark', - 'u', 'xm', 'sup', 'nobr', - 'var', 'ruby', - 'wbr', 'span', - 'time', - ); -} diff --git a/kirby/vendors/parsedownextra.php b/kirby/vendors/parsedownextra.php deleted file mode 100644 index be6966d..0000000 --- a/kirby/vendors/parsedownextra.php +++ /dev/null @@ -1,526 +0,0 @@ -BlockTypes[':'] []= 'DefinitionList'; - $this->BlockTypes['*'] []= 'Abbreviation'; - - # identify footnote definitions before reference definitions - array_unshift($this->BlockTypes['['], 'Footnote'); - - # identify footnote markers before before links - array_unshift($this->InlineTypes['['], 'FootnoteMarker'); - } - - # - # ~ - - function text($text) - { - $markup = parent::text($text); - - # merge consecutive dl elements - - $markup = preg_replace('/<\/dl>\s+
\s+/', '', $markup); - - # add footnotes - - if (isset($this->DefinitionData['Footnote'])) - { - $Element = $this->buildFootnoteElement(); - - $markup .= "\n" . $this->element($Element); - } - - return $markup; - } - - # - # Blocks - # - - # - # Abbreviation - - protected function blockAbbreviation($Line) - { - if (preg_match('/^\*\[(.+?)\]:[ ]*(.+?)[ ]*$/', $Line['text'], $matches)) - { - $this->DefinitionData['Abbreviation'][$matches[1]] = $matches[2]; - - $Block = array( - 'hidden' => true, - ); - - return $Block; - } - } - - # - # Footnote - - protected function blockFootnote($Line) - { - if (preg_match('/^\[\^(.+?)\]:[ ]?(.*)$/', $Line['text'], $matches)) - { - $Block = array( - 'label' => $matches[1], - 'text' => $matches[2], - 'hidden' => true, - ); - - return $Block; - } - } - - protected function blockFootnoteContinue($Line, $Block) - { - if ($Line['text'][0] === '[' and preg_match('/^\[\^(.+?)\]:/', $Line['text'])) - { - return; - } - - if (isset($Block['interrupted'])) - { - if ($Line['indent'] >= 4) - { - $Block['text'] .= "\n\n" . $Line['text']; - - return $Block; - } - } - else - { - $Block['text'] .= "\n" . $Line['text']; - - return $Block; - } - } - - protected function blockFootnoteComplete($Block) - { - $this->DefinitionData['Footnote'][$Block['label']] = array( - 'text' => $Block['text'], - 'count' => null, - 'number' => null, - ); - - return $Block; - } - - # - # Definition List - - protected function blockDefinitionList($Line, $Block) - { - if ( ! isset($Block) or isset($Block['type'])) - { - return; - } - - $Element = array( - 'name' => 'dl', - 'handler' => 'elements', - 'text' => array(), - ); - - $terms = explode("\n", $Block['element']['text']); - - foreach ($terms as $term) - { - $Element['text'] []= array( - 'name' => 'dt', - 'handler' => 'line', - 'text' => $term, - ); - } - - $Block['element'] = $Element; - - $Block = $this->addDdElement($Line, $Block); - - return $Block; - } - - protected function blockDefinitionListContinue($Line, array $Block) - { - if ($Line['text'][0] === ':') - { - $Block = $this->addDdElement($Line, $Block); - - return $Block; - } - else - { - if (isset($Block['interrupted']) and $Line['indent'] === 0) - { - return; - } - - if (isset($Block['interrupted'])) - { - $Block['dd']['handler'] = 'text'; - $Block['dd']['text'] .= "\n\n"; - - unset($Block['interrupted']); - } - - $text = substr($Line['body'], min($Line['indent'], 4)); - - $Block['dd']['text'] .= "\n" . $text; - - return $Block; - } - } - - # - # Header - - protected function blockHeader($Line) - { - $Block = parent::blockHeader($Line); - - if (preg_match('/[ #]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE)) - { - $attributeString = $matches[1][0]; - - $Block['element']['attributes'] = $this->parseAttributeData($attributeString); - - $Block['element']['text'] = substr($Block['element']['text'], 0, $matches[0][1]); - } - - return $Block; - } - - # - # Markup - - protected function blockMarkupComplete($Block) - { - if ( ! isset($Block['void'])) - { - $Block['markup'] = $this->processTag($Block['markup']); - } - - return $Block; - } - - # - # Setext - - protected function blockSetextHeader($Line, array $Block = null) - { - $Block = parent::blockSetextHeader($Line, $Block); - - if (preg_match('/[ ]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE)) - { - $attributeString = $matches[1][0]; - - $Block['element']['attributes'] = $this->parseAttributeData($attributeString); - - $Block['element']['text'] = substr($Block['element']['text'], 0, $matches[0][1]); - } - - return $Block; - } - - # - # Inline Elements - # - - # - # Footnote Marker - - protected function inlineFootnoteMarker($Excerpt) - { - if (preg_match('/^\[\^(.+?)\]/', $Excerpt['text'], $matches)) - { - $name = $matches[1]; - - if ( ! isset($this->DefinitionData['Footnote'][$name])) - { - return; - } - - $this->DefinitionData['Footnote'][$name]['count'] ++; - - if ( ! isset($this->DefinitionData['Footnote'][$name]['number'])) - { - $this->DefinitionData['Footnote'][$name]['number'] = ++ $this->footnoteCount; # » & - } - - $Element = array( - 'name' => 'sup', - 'attributes' => array('id' => 'fnref'.$this->DefinitionData['Footnote'][$name]['count'].':'.$name), - 'handler' => 'element', - 'text' => array( - 'name' => 'a', - 'attributes' => array('href' => '#fn:'.$name, 'class' => 'footnote-ref'), - 'text' => $this->DefinitionData['Footnote'][$name]['number'], - ), - ); - - return array( - 'extent' => strlen($matches[0]), - 'element' => $Element, - ); - } - } - - private $footnoteCount = 0; - - # - # Link - - protected function inlineLink($Excerpt) - { - $Link = parent::inlineLink($Excerpt); - - $remainder = substr($Excerpt['text'], $Link['extent']); - - if (preg_match('/^[ ]*{('.$this->regexAttribute.'+)}/', $remainder, $matches)) - { - $Link['element']['attributes'] += $this->parseAttributeData($matches[1]); - - $Link['extent'] += strlen($matches[0]); - } - - return $Link; - } - - # - # ~ - # - - protected function unmarkedText($text) - { - $text = parent::unmarkedText($text); - - if (isset($this->DefinitionData['Abbreviation'])) - { - foreach ($this->DefinitionData['Abbreviation'] as $abbreviation => $meaning) - { - $pattern = '/\b'.preg_quote($abbreviation, '/').'\b/'; - - $text = preg_replace($pattern, ''.$abbreviation.'', $text); - } - } - - return $text; - } - - # - # Util Methods - # - - protected function addDdElement(array $Line, array $Block) - { - $text = substr($Line['text'], 1); - $text = trim($text); - - unset($Block['dd']); - - $Block['dd'] = array( - 'name' => 'dd', - 'handler' => 'line', - 'text' => $text, - ); - - if (isset($Block['interrupted'])) - { - $Block['dd']['handler'] = 'text'; - - unset($Block['interrupted']); - } - - $Block['element']['text'] []= & $Block['dd']; - - return $Block; - } - - protected function buildFootnoteElement() - { - $Element = array( - 'name' => 'div', - 'attributes' => array('class' => 'footnotes'), - 'handler' => 'elements', - 'text' => array( - array( - 'name' => 'hr', - ), - array( - 'name' => 'ol', - 'handler' => 'elements', - 'text' => array(), - ), - ), - ); - - uasort($this->DefinitionData['Footnote'], 'self::sortFootnotes'); - - foreach ($this->DefinitionData['Footnote'] as $definitionId => $DefinitionData) - { - if ( ! isset($DefinitionData['number'])) - { - continue; - } - - $text = $DefinitionData['text']; - - $text = parent::text($text); - - $numbers = range(1, $DefinitionData['count']); - - $backLinksMarkup = ''; - - foreach ($numbers as $number) - { - $backLinksMarkup .= ' '; - } - - $backLinksMarkup = substr($backLinksMarkup, 1); - - if (substr($text, - 4) === '

') - { - $backLinksMarkup = ' '.$backLinksMarkup; - - $text = substr_replace($text, $backLinksMarkup.'

', - 4); - } - else - { - $text .= "\n".'

'.$backLinksMarkup.'

'; - } - - $Element['text'][1]['text'] []= array( - 'name' => 'li', - 'attributes' => array('id' => 'fn:'.$definitionId), - 'text' => "\n".$text."\n", - ); - } - - return $Element; - } - - # ~ - - protected function parseAttributeData($attributeString) - { - $Data = array(); - - $attributes = preg_split('/[ ]+/', $attributeString, - 1, PREG_SPLIT_NO_EMPTY); - - foreach ($attributes as $attribute) - { - if ($attribute[0] === '#') - { - $Data['id'] = substr($attribute, 1); - } - else # "." - { - $classes []= substr($attribute, 1); - } - } - - if (isset($classes)) - { - $Data['class'] = implode(' ', $classes); - } - - return $Data; - } - - # ~ - - protected function processTag($elementMarkup) # recursive - { - # http://stackoverflow.com/q/1148928/200145 - libxml_use_internal_errors(true); - - $DOMDocument = new DOMDocument; - - # http://stackoverflow.com/q/11309194/200145 - $elementMarkup = mb_convert_encoding($elementMarkup, 'HTML-ENTITIES', 'UTF-8'); - - # http://stackoverflow.com/q/4879946/200145 - $DOMDocument->loadHTML($elementMarkup); - $DOMDocument->removeChild($DOMDocument->doctype); - $DOMDocument->replaceChild($DOMDocument->firstChild->firstChild->firstChild, $DOMDocument->firstChild); - - $elementText = ''; - - if ($DOMDocument->documentElement->getAttribute('markdown') === '1') - { - foreach ($DOMDocument->documentElement->childNodes as $Node) - { - $elementText .= $DOMDocument->saveHTML($Node); - } - - $DOMDocument->documentElement->removeAttribute('markdown'); - - $elementText = "\n".$this->text($elementText)."\n"; - } - else - { - foreach ($DOMDocument->documentElement->childNodes as $Node) - { - $nodeMarkup = $DOMDocument->saveHTML($Node); - - if ($Node instanceof DOMElement and ! in_array($Node->nodeName, $this->textLevelElements)) - { - $elementText .= $this->processTag($nodeMarkup); - } - else - { - $elementText .= $nodeMarkup; - } - } - } - - # because we don't want for markup to get encoded - $DOMDocument->documentElement->nodeValue = 'placeholder\x1A'; - - $markup = $DOMDocument->saveHTML($DOMDocument->documentElement); - $markup = str_replace('placeholder\x1A', $elementText, $markup); - - return $markup; - } - - # ~ - - protected function sortFootnotes($A, $B) # callback - { - return $A['number'] - $B['number']; - } - - # - # Fields - # - - protected $regexAttribute = '(?:[#.][-\w]+[ ]*)'; -} diff --git a/kirby/vendors/smartypants.php b/kirby/vendors/smartypants.php deleted file mode 100755 index 1f73456..0000000 --- a/kirby/vendors/smartypants.php +++ /dev/null @@ -1,1094 +0,0 @@ - -# -# Original SmartyPants -# Copyright (c) 2003-2004 John Gruber -# -# - - -define( 'SMARTYPANTS_VERSION', "1.5.1f" ); # Sun 23 Jan 2013 -define( 'SMARTYPANTSTYPOGRAPHER_VERSION', "1.0.1" ); # Sun 23 Jan 2013 - -# -# Default configuration: -# -# 1 -> "--" for em-dashes; no en-dash support -# 2 -> "---" for em-dashes; "--" for en-dashes -# 3 -> "--" for em-dashes; "---" for en-dashes -# See docs for more configuration options. -# -define( 'SMARTYPANTS_ATTR', c::get('smartypants.attr', 1) ); - -# Openning and closing smart double-quotes. -define( 'SMARTYPANTS_SMART_DOUBLEQUOTE_OPEN', c::get('smartypants.doublequote.open', '“') ); -define( 'SMARTYPANTS_SMART_DOUBLEQUOTE_CLOSE', c::get('smartypants.doublequote.close', '”') ); - -# Space around em-dashes. "He_—_or she_—_should change that." -define( 'SMARTYPANTS_SPACE_EMDASH', c::get('smartypants.space.emdash', ' ') ); - -# Space around en-dashes. "He_–_or she_–_should change that." -define( 'SMARTYPANTS_SPACE_ENDASH', c::get('smartypants.space.endash', ' ') ); - -# Space before a colon. "He said_: here it is." -define( 'SMARTYPANTS_SPACE_COLON', c::get('smartypants.space.colon', ' ') ); - -# Space before a semicolon. "That's what I said_; that's what he said." -define( 'SMARTYPANTS_SPACE_SEMICOLON', c::get('smartypants.space.semicolon', ' ') ); - -# Space before a question mark and an exclamation mark: "¡_Holà_! What_?" -define( 'SMARTYPANTS_SPACE_MARKS', c::get('smartypants.space.marks', ' ') ); - -# Space inside french quotes. "Voici la «_chose_» qui m'a attaqué." -define( 'SMARTYPANTS_SPACE_FRENCHQUOTE', c::get('smartypants.space.frenchquote', ' ') ); - -# Space as thousand separator. "On compte 10_000 maisons sur cette liste." -define( 'SMARTYPANTS_SPACE_THOUSAND', c::get('smartypants.space.thousand', ' ') ); - -# Space before a unit abreviation. "This 12_kg of matter costs 10_$." -define( 'SMARTYPANTS_SPACE_UNIT', c::get('smartypants.space.unit', ' ') ); - -# SmartyPants will not alter the content of these tags: -define( 'SMARTYPANTS_TAGS_TO_SKIP', c::get('smartypants.skip', 'pre|code|kbd|script|style|math') ); - - -# -# SmartyPants Parser Class -# - -class SmartyPants_Parser { - - # Options to specify which transformations to make: - var $do_nothing = 0; - var $do_quotes = 0; - var $do_backticks = 0; - var $do_dashes = 0; - var $do_ellipses = 0; - var $do_stupefy = 0; - var $convert_quot = 0; # should we translate " entities into normal quotes? - - function __construct($attr = SMARTYPANTS_ATTR) { - # - # Initialize a SmartyPants_Parser with certain attributes. - # - # Parser attributes: - # 0 : do nothing - # 1 : set all - # 2 : set all, using old school en- and em- dash shortcuts - # 3 : set all, using inverted old school en and em- dash shortcuts - # - # q : quotes - # b : backtick quotes (``double'' only) - # B : backtick quotes (``double'' and `single') - # d : dashes - # D : old school dashes - # i : inverted old school dashes - # e : ellipses - # w : convert " entities to " for Dreamweaver users - # - if ($attr == "0") { - $this->do_nothing = 1; - } - else if ($attr == "1") { - # Do everything, turn all options on. - $this->do_quotes = 1; - $this->do_backticks = 1; - $this->do_dashes = 1; - $this->do_ellipses = 1; - } - else if ($attr == "2") { - # Do everything, turn all options on, use old school dash shorthand. - $this->do_quotes = 1; - $this->do_backticks = 1; - $this->do_dashes = 2; - $this->do_ellipses = 1; - } - else if ($attr == "3") { - # Do everything, turn all options on, use inverted old school dash shorthand. - $this->do_quotes = 1; - $this->do_backticks = 1; - $this->do_dashes = 3; - $this->do_ellipses = 1; - } - else if ($attr == "-1") { - # Special "stupefy" mode. - $this->do_stupefy = 1; - } - else { - $chars = preg_split('//', $attr); - foreach ($chars as $c){ - if ($c == "q") { $this->do_quotes = 1; } - else if ($c == "b") { $this->do_backticks = 1; } - else if ($c == "B") { $this->do_backticks = 2; } - else if ($c == "d") { $this->do_dashes = 1; } - else if ($c == "D") { $this->do_dashes = 2; } - else if ($c == "i") { $this->do_dashes = 3; } - else if ($c == "e") { $this->do_ellipses = 1; } - else if ($c == "w") { $this->convert_quot = 1; } - else { - # Unknown attribute option, ignore. - } - } - } - } - - function transform($text) { - - if ($this->do_nothing) { - return $text; - } - - $tokens = $this->tokenizeHTML($text); - $result = ''; - $in_pre = 0; # Keep track of when we're inside
 or  tags.
-
-		$prev_token_last_char = ""; # This is a cheat, used to get some context
-									# for one-character tokens that consist of 
-									# just a quote char. What we do is remember
-									# the last character of the previous text
-									# token, to use as context to curl single-
-									# character quote tokens correctly.
-
-		foreach ($tokens as $cur_token) {
-			if ($cur_token[0] == "tag") {
-				# Don't mess with quotes inside tags.
-				$result .= $cur_token[1];
-				if (preg_match('@<(/?)(?:'.SMARTYPANTS_TAGS_TO_SKIP.')[\s>]@', $cur_token[1], $matches)) {
-					$in_pre = isset($matches[1]) && $matches[1] == '/' ? 0 : 1;
-				}
-			} else {
-				$t = $cur_token[1];
-				$last_char = substr($t, -1); # Remember last char of this token before processing.
-				if (! $in_pre) {
-					$t = $this->educate($t, $prev_token_last_char);
-				}
-				$prev_token_last_char = $last_char;
-				$result .= $t;
-			}
-		}
-
-		return $result;
-	}
-
-
-	function educate($t, $prev_token_last_char) {
-		$t = $this->processEscapes($t);
-
-		if ($this->convert_quot) {
-			$t = preg_replace('/"/', '"', $t);
-		}
-
-		if ($this->do_dashes) {
-			if ($this->do_dashes == 1) $t = $this->educateDashes($t);
-			if ($this->do_dashes == 2) $t = $this->educateDashesOldSchool($t);
-			if ($this->do_dashes == 3) $t = $this->educateDashesOldSchoolInverted($t);
-		}
-
-		if ($this->do_ellipses) $t = $this->educateEllipses($t);
-
-		# Note: backticks need to be processed before quotes.
-		if ($this->do_backticks) {
-			$t = $this->educateBackticks($t);
-			if ($this->do_backticks == 2) $t = $this->educateSingleBackticks($t);
-		}
-
-		if ($this->do_quotes) {
-			if ($t == "'") {
-				# Special case: single-character ' token
-				if (preg_match('/\S/', $prev_token_last_char)) {
-					$t = "’";
-				}
-				else {
-					$t = "‘";
-				}
-			}
-			else if ($t == '"') {
-				# Special case: single-character " token
-				if (preg_match('/\S/', $prev_token_last_char)) {
-					$t = "”";
-				}
-				else {
-					$t = "“";
-				}
-			}
-			else {
-				# Normal case:
-				$t = $this->educateQuotes($t);
-			}
-		}
-
-		if ($this->do_stupefy) $t = $this->stupefyEntities($t);
-		
-		return $t;
-	}
-
-
-	function educateQuotes($_) {
-	#
-	#   Parameter:  String.
-	#
-	#   Returns:    The string, with "educated" curly quote HTML entities.
-	#
-	#   Example input:  "Isn't this fun?"
-	#   Example output: “Isn’t this fun?”
-	#
-		# Make our own "punctuation" character class, because the POSIX-style
-		# [:PUNCT:] is only available in Perl 5.6 or later:
-		$punct_class = "[!\"#\\$\\%'()*+,-.\\/:;<=>?\\@\\[\\\\\]\\^_`{|}~]";
-
-		# Special case if the very first character is a quote
-		# followed by punctuation at a non-word-break. Close the quotes by brute force:
-		$_ = preg_replace(
-			array("/^'(?=$punct_class\\B)/", "/^\"(?=$punct_class\\B)/"),
-			array('’',                 '”'), $_);
-
-
-		# Special case for double sets of quotes, e.g.:
-		#   

He said, "'Quoted' words in a larger quote."

- $_ = preg_replace( - array("/\"'(?=\w)/", "/'\"(?=\w)/"), - array('“‘', '‘“'), $_); - - # Special case for decade abbreviations (the '80s): - $_ = preg_replace("/'(?=\\d{2}s)/", '’', $_); - - $close_class = '[^\ \t\r\n\[\{\(\-]'; - $dec_dashes = '&\#8211;|&\#8212;'; - - # Get most opening single quotes: - $_ = preg_replace("{ - ( - \\s | # a whitespace char, or -   | # a non-breaking space entity, or - -- | # dashes, or - &[mn]dash; | # named dash entities - $dec_dashes | # or decimal entities - &\\#x201[34]; # or hex - ) - ' # the quote - (?=\\w) # followed by a word character - }x", '\1‘', $_); - # Single closing quotes: - $_ = preg_replace("{ - ($close_class)? - ' - (?(1)| # If $1 captured, then do nothing; - (?=\\s | s\\b) # otherwise, positive lookahead for a whitespace - ) # char or an 's' at a word ending position. This - # is a special case to handle something like: - # \"Custer's Last Stand.\" - }xi", '\1’', $_); - - # Any remaining single quotes should be opening ones: - $_ = str_replace("'", '‘', $_); - - - # Get most opening double quotes: - $_ = preg_replace("{ - ( - \\s | # a whitespace char, or -   | # a non-breaking space entity, or - -- | # dashes, or - &[mn]dash; | # named dash entities - $dec_dashes | # or decimal entities - &\\#x201[34]; # or hex - ) - \" # the quote - (?=\\w) # followed by a word character - }x", '\1“', $_); - - # Double closing quotes: - $_ = preg_replace("{ - ($close_class)? - \" - (?(1)|(?=\\s)) # If $1 captured, then do nothing; - # if not, then make sure the next char is whitespace. - }x", '\1”', $_); - - # Any remaining quotes should be opening ones. - $_ = str_replace('"', '“', $_); - - return $_; - } - - - function educateBackticks($_) { - # - # Parameter: String. - # Returns: The string, with ``backticks'' -style double quotes - # translated into HTML curly quote entities. - # - # Example input: ``Isn't this fun?'' - # Example output: “Isn't this fun?” - # - - $_ = str_replace(array("``", "''",), - array('“', '”'), $_); - return $_; - } - - - function educateSingleBackticks($_) { - # - # Parameter: String. - # Returns: The string, with `backticks' -style single quotes - # translated into HTML curly quote entities. - # - # Example input: `Isn't this fun?' - # Example output: ‘Isn’t this fun?’ - # - - $_ = str_replace(array("`", "'",), - array('‘', '’'), $_); - return $_; - } - - - function educateDashes($_) { - # - # Parameter: String. - # - # Returns: The string, with each instance of "--" translated to - # an em-dash HTML entity. - # - - $_ = str_replace('--', '—', $_); - return $_; - } - - - function educateDashesOldSchool($_) { - # - # Parameter: String. - # - # Returns: The string, with each instance of "--" translated to - # an en-dash HTML entity, and each "---" translated to - # an em-dash HTML entity. - # - - # em en - $_ = str_replace(array("---", "--",), - array('—', '–'), $_); - return $_; - } - - - function educateDashesOldSchoolInverted($_) { - # - # Parameter: String. - # - # Returns: The string, with each instance of "--" translated to - # an em-dash HTML entity, and each "---" translated to - # an en-dash HTML entity. Two reasons why: First, unlike the - # en- and em-dash syntax supported by - # EducateDashesOldSchool(), it's compatible with existing - # entries written before SmartyPants 1.1, back when "--" was - # only used for em-dashes. Second, em-dashes are more - # common than en-dashes, and so it sort of makes sense that - # the shortcut should be shorter to type. (Thanks to Aaron - # Swartz for the idea.) - # - - # en em - $_ = str_replace(array("---", "--",), - array('–', '—'), $_); - return $_; - } - - - function educateEllipses($_) { - # - # Parameter: String. - # Returns: The string, with each instance of "..." translated to - # an ellipsis HTML entity. Also converts the case where - # there are spaces between the dots. - # - # Example input: Huh...? - # Example output: Huh…? - # - - $_ = str_replace(array("...", ". . .",), '…', $_); - return $_; - } - - - function stupefyEntities($_) { - # - # Parameter: String. - # Returns: The string, with each SmartyPants HTML entity translated to - # its ASCII counterpart. - # - # Example input: “Hello — world.” - # Example output: "Hello -- world." - # - - # en-dash em-dash - $_ = str_replace(array('–', '—'), - array('-', '--'), $_); - - # single quote open close - $_ = str_replace(array('‘', '’'), "'", $_); - - # double quote open close - $_ = str_replace(array('“', '”'), '"', $_); - - $_ = str_replace('…', '...', $_); # ellipsis - - return $_; - } - - - function processEscapes($_) { - # - # Parameter: String. - # Returns: The string, with after processing the following backslash - # escape sequences. This is useful if you want to force a "dumb" - # quote or other character to appear. - # - # Escape Value - # ------ ----- - # \\ \ - # \" " - # \' ' - # \. . - # \- - - # \` ` - # - $_ = str_replace( - array('\\\\', '\"', "\'", '\.', '\-', '\`'), - array('\', '"', ''', '.', '-', '`'), $_); - - return $_; - } - - - function tokenizeHTML($str) { - # - # Parameter: String containing HTML markup. - # Returns: An array of the tokens comprising the input - # string. Each token is either a tag (possibly with nested, - # tags contained therein, such as , or a - # run of text between tags. Each element of the array is a - # two-element array; the first is either 'tag' or 'text'; - # the second is the actual value. - # - # - # Regular expression derived from the _tokenize() subroutine in - # Brad Choate's MTRegex plugin. - # - # - $index = 0; - $tokens = array(); - - $match = '(?s:)|'. # comment - '(?s:<\?.*?\?>)|'. # processing instruction - # regular tags - '(?:<[/!$]?[-a-zA-Z0-9:]+\b(?>[^"\'>]+|"[^"]*"|\'[^\']*\')*>)'; - - $parts = preg_split("{($match)}", $str, -1, PREG_SPLIT_DELIM_CAPTURE); - - foreach ($parts as $part) { - if (++$index % 2 && $part != '') - $tokens[] = array('text', $part); - else - $tokens[] = array('tag', $part); - } - return $tokens; - } - -} - - -# -# SmartyPants Typographer Parser Class -# -class SmartyPantsTypographer_Parser extends SmartyPants_Parser { - - # Options to specify which transformations to make: - var $do_comma_quotes = 0; - var $do_guillemets = 0; - var $do_space_emdash = 0; - var $do_space_endash = 0; - var $do_space_colon = 0; - var $do_space_semicolon = 0; - var $do_space_marks = 0; - var $do_space_frenchquote = 0; - var $do_space_thousand = 0; - var $do_space_unit = 0; - - # Smart quote characters: - var $smart_doublequote_open = SMARTYPANTS_SMART_DOUBLEQUOTE_OPEN; - var $smart_doublequote_close = SMARTYPANTS_SMART_DOUBLEQUOTE_CLOSE; - var $smart_singlequote_open = '‘'; - var $smart_singlequote_close = '’'; # Also apostrophe. - - # Space characters for different places: - var $space_emdash = SMARTYPANTS_SPACE_EMDASH; - var $space_endash = SMARTYPANTS_SPACE_ENDASH; - var $space_colon = SMARTYPANTS_SPACE_COLON; - var $space_semicolon = SMARTYPANTS_SPACE_SEMICOLON; - var $space_marks = SMARTYPANTS_SPACE_MARKS; - var $space_frenchquote = SMARTYPANTS_SPACE_FRENCHQUOTE; - var $space_thousand = SMARTYPANTS_SPACE_THOUSAND; - var $space_unit = SMARTYPANTS_SPACE_UNIT; - - # Expression of a space (breakable or not): - var $space = '(?: | | |�*160;|�*[aA]0;)'; - - - - function __construct($attr = SMARTYPANTS_ATTR) { - # - # Initialize a SmartyPantsTypographer_Parser with certain attributes. - # - # Parser attributes: - # 0 : do nothing - # 1 : set all, except dash spacing - # 2 : set all, except dash spacing, using old school en- and em- dash shortcuts - # 3 : set all, except dash spacing, using inverted old school en and em- dash shortcuts - # - # Punctuation: - # q -> quotes - # b -> backtick quotes (``double'' only) - # B -> backtick quotes (``double'' and `single') - # c -> comma quotes (,,double`` only) - # g -> guillemets (<> only) - # d -> dashes - # D -> old school dashes - # i -> inverted old school dashes - # e -> ellipses - # w -> convert " entities to " for Dreamweaver users - # - # Spacing: - # : -> colon spacing +- - # ; -> semicolon spacing +- - # m -> question and exclamation marks spacing +- - # h -> em-dash spacing +- - # H -> en-dash spacing +- - # f -> french quote spacing +- - # t -> thousand separator spacing - - # u -> unit spacing +- - # (you can add a plus sign after some of these options denoted by + to - # add the space when it is not already present, or you can add a minus - # sign to completly remove any space present) - # - # Initialize inherited SmartyPants parser. - - parent::__construct($attr); - if ($attr == "1" || $attr == "2" || $attr == "3") { - # Do everything, turn all options on. - $this->do_comma_quotes = 1; - $this->do_guillemets = 1; - $this->do_space_emdash = 1; - $this->do_space_endash = 1; - $this->do_space_colon = 1; - $this->do_space_semicolon = 1; - $this->do_space_marks = 1; - $this->do_space_frenchquote = 1; - $this->do_space_thousand = 1; - $this->do_space_unit = 1; - } - else if ($attr == "-1") { - # Special "stupefy" mode. - $this->do_stupefy = 1; - } - else { - $chars = preg_split('//', $attr); - foreach ($chars as $c){ - if ($c == "c") { $current =& $this->do_comma_quotes; } - else if ($c == "g") { $current =& $this->do_guillemets; } - else if ($c == ":") { $current =& $this->do_space_colon; } - else if ($c == ";") { $current =& $this->do_space_semicolon; } - else if ($c == "m") { $current =& $this->do_space_marks; } - else if ($c == "h") { $current =& $this->do_space_emdash; } - else if ($c == "H") { $current =& $this->do_space_endash; } - else if ($c == "f") { $current =& $this->do_space_frenchquote; } - else if ($c == "t") { $current =& $this->do_space_thousand; } - else if ($c == "u") { $current =& $this->do_space_unit; } - else if ($c == "+") { - $current = 2; - unset($current); - } - else if ($c == "-") { - $current = -1; - unset($current); - } - else { - # Unknown attribute option, ignore. - } - $current = 1; - } - } - } - - - function educate($t, $prev_token_last_char) { - $t = parent::educate($t, $prev_token_last_char); - - if ($this->do_comma_quotes) $t = $this->educateCommaQuotes($t); - if ($this->do_guillemets) $t = $this->educateGuillemets($t); - - if ($this->do_space_emdash) $t = $this->spaceEmDash($t); - if ($this->do_space_endash) $t = $this->spaceEnDash($t); - if ($this->do_space_colon) $t = $this->spaceColon($t); - if ($this->do_space_semicolon) $t = $this->spaceSemicolon($t); - if ($this->do_space_marks) $t = $this->spaceMarks($t); - if ($this->do_space_frenchquote) $t = $this->spaceFrenchQuotes($t); - if ($this->do_space_thousand) $t = $this->spaceThousandSeparator($t); - if ($this->do_space_unit) $t = $this->spaceUnit($t); - - return $t; - } - - - function educateQuotes($_) { - # - # Parameter: String. - # - # Returns: The string, with "educated" curly quote HTML entities. - # - # Example input: "Isn't this fun?" - # Example output: “Isn’t this fun?” - # - $dq_open = $this->smart_doublequote_open; - $dq_close = $this->smart_doublequote_close; - $sq_open = $this->smart_singlequote_open; - $sq_close = $this->smart_singlequote_close; - - # Make our own "punctuation" character class, because the POSIX-style - # [:PUNCT:] is only available in Perl 5.6 or later: - $punct_class = "[!\"#\\$\\%'()*+,-.\\/:;<=>?\\@\\[\\\\\]\\^_`{|}~]"; - - # Special case if the very first character is a quote - # followed by punctuation at a non-word-break. Close the quotes by brute force: - $_ = preg_replace( - array("/^'(?=$punct_class\\B)/", "/^\"(?=$punct_class\\B)/"), - array($sq_close, $dq_close), $_); - - # Special case for double sets of quotes, e.g.: - #

He said, "'Quoted' words in a larger quote."

- $_ = preg_replace( - array("/\"'(?=\w)/", "/'\"(?=\w)/"), - array($dq_open.$sq_open, $sq_open.$dq_open), $_); - - # Special case for decade abbreviations (the '80s): - $_ = preg_replace("/'(?=\\d{2}s)/", $sq_close, $_); - - $close_class = '[^\ \t\r\n\[\{\(\-]'; - $dec_dashes = '&\#8211;|&\#8212;'; - - # Get most opening single quotes: - $_ = preg_replace("{ - ( - \\s | # a whitespace char, or -   | # a non-breaking space entity, or - -- | # dashes, or - &[mn]dash; | # named dash entities - $dec_dashes | # or decimal entities - &\\#x201[34]; # or hex - ) - ' # the quote - (?=\\w) # followed by a word character - }x", '\1'.$sq_open, $_); - # Single closing quotes: - $_ = preg_replace("{ - ($close_class)? - ' - (?(1)| # If $1 captured, then do nothing; - (?=\\s | s\\b) # otherwise, positive lookahead for a whitespace - ) # char or an 's' at a word ending position. This - # is a special case to handle something like: - # \"Custer's Last Stand.\" - }xi", '\1'.$sq_close, $_); - - # Any remaining single quotes should be opening ones: - $_ = str_replace("'", $sq_open, $_); - - - # Get most opening double quotes: - $_ = preg_replace("{ - ( - \\s | # a whitespace char, or -   | # a non-breaking space entity, or - -- | # dashes, or - &[mn]dash; | # named dash entities - $dec_dashes | # or decimal entities - &\\#x201[34]; # or hex - ) - \" # the quote - (?=\\w) # followed by a word character - }x", '\1'.$dq_open, $_); - - # Double closing quotes: - $_ = preg_replace("{ - ($close_class)? - \" - (?(1)|(?=\\s)) # If $1 captured, then do nothing; - # if not, then make sure the next char is whitespace. - }x", '\1'.$dq_close, $_); - - # Any remaining quotes should be opening ones. - $_ = str_replace('"', $dq_open, $_); - - return $_; - } - - - function educateCommaQuotes($_) { - # - # Parameter: String. - # Returns: The string, with ,,comma,, -style double quotes - # translated into HTML curly quote entities. - # - # Example input: ,,Isn't this fun?,, - # Example output: „Isn't this fun?„ - # - # Note: this is meant to be used alongside with backtick quotes; there is - # no language that use only lower quotations alone mark like in the example. - # - $_ = str_replace(",,", '„', $_); - return $_; - } - - - function educateGuillemets($_) { - # - # Parameter: String. - # Returns: The string, with << guillemets >> -style quotes - # translated into HTML guillemets entities. - # - # Example input: << Isn't this fun? >> - # Example output: „ Isn't this fun? „ - # - $_ = preg_replace("/(?:<|<){2}/", '«', $_); - $_ = preg_replace("/(?:>|>){2}/", '»', $_); - return $_; - } - - - function spaceFrenchQuotes($_) { - # - # Parameters: String, replacement character, and forcing flag. - # Returns: The string, with appropriates spaces replaced - # inside french-style quotes, only french quotes. - # - # Example input: Quotes in « French », »German« and »Finnish» style. - # Example output: Quotes in «_French_», »German« and »Finnish» style. - # - $opt = ( $this->do_space_frenchquote == 2 ? '?' : '' ); - $chr = ( $this->do_space_frenchquote != -1 ? $this->space_frenchquote : '' ); - - # Characters allowed immediatly outside quotes. - $outside_char = $this->space . '|\s|[.,:;!?\[\](){}|@*~=+-]|¡|¿'; - - $_ = preg_replace( - "/(^|$outside_char)(«|«|›|‹)$this->space$opt/", - "\\1\\2$chr", $_); - $_ = preg_replace( - "/$this->space$opt(»|»|‹|›)($outside_char|$)/", - "$chr\\1\\2", $_); - return $_; - } - - - function spaceColon($_) { - # - # Parameters: String, replacement character, and forcing flag. - # Returns: The string, with appropriates spaces replaced - # before colons. - # - # Example input: Ingredients : fun. - # Example output: Ingredients_: fun. - # - $opt = ( $this->do_space_colon == 2 ? '?' : '' ); - $chr = ( $this->do_space_colon != -1 ? $this->space_colon : '' ); - - $_ = preg_replace("/$this->space$opt(:)(\\s|$)/m", - "$chr\\1\\2", $_); - return $_; - } - - - function spaceSemicolon($_) { - # - # Parameters: String, replacement character, and forcing flag. - # Returns: The string, with appropriates spaces replaced - # before semicolons. - # - # Example input: There he goes ; there she goes. - # Example output: There he goes_; there she goes. - # - $opt = ( $this->do_space_semicolon == 2 ? '?' : '' ); - $chr = ( $this->do_space_semicolon != -1 ? $this->space_semicolon : '' ); - - $_ = preg_replace("/$this->space(;)(?=\\s|$)/m", - " \\1", $_); - $_ = preg_replace("/((?:^|\\s)(?>[^&;\\s]+|&#?[a-zA-Z0-9]+;)*)". - " $opt(;)(?=\\s|$)/m", - "\\1$chr\\2", $_); - return $_; - } - - - function spaceMarks($_) { - # - # Parameters: String, replacement character, and forcing flag. - # Returns: The string, with appropriates spaces replaced - # around question and exclamation marks. - # - # Example input: ¡ Holà ! What ? - # Example output: ¡_Holà_! What_? - # - $opt = ( $this->do_space_marks == 2 ? '?' : '' ); - $chr = ( $this->do_space_marks != -1 ? $this->space_marks : '' ); - - // Regular marks. - $_ = preg_replace("/$this->space$opt([?!]+)/", "$chr\\1", $_); - - // Inverted marks. - $imarks = "(?:¡|¡|¡|&#x[Aa]1;|¿|¿|¿|&#x[Bb][Ff];)"; - $_ = preg_replace("/($imarks+)$this->space$opt/", "\\1$chr", $_); - - return $_; - } - - - function spaceEmDash($_) { - # - # Parameters: String, two replacement characters separated by a hyphen (`-`), - # and forcing flag. - # - # Returns: The string, with appropriates spaces replaced - # around dashes. - # - # Example input: Then — without any plan — the fun happend. - # Example output: Then_—_without any plan_—_the fun happend. - # - $opt = ( $this->do_space_emdash == 2 ? '?' : '' ); - $chr = ( $this->do_space_emdash != -1 ? $this->space_emdash : '' ); - $_ = preg_replace("/$this->space$opt(—|—)$this->space$opt/", - "$chr\\1$chr", $_); - return $_; - } - - - function spaceEnDash($_) { - # - # Parameters: String, two replacement characters separated by a hyphen (`-`), - # and forcing flag. - # - # Returns: The string, with appropriates spaces replaced - # around dashes. - # - # Example input: Then — without any plan — the fun happend. - # Example output: Then_—_without any plan_—_the fun happend. - # - $opt = ( $this->do_space_endash == 2 ? '?' : '' ); - $chr = ( $this->do_space_endash != -1 ? $this->space_endash : '' ); - $_ = preg_replace("/$this->space$opt(–|–)$this->space$opt/", - "$chr\\1$chr", $_); - return $_; - } - - - function spaceThousandSeparator($_) { - # - # Parameters: String, replacement character, and forcing flag. - # Returns: The string, with appropriates spaces replaced - # inside numbers (thousand separator in french). - # - # Example input: Il y a 10 000 insectes amusants dans ton jardin. - # Example output: Il y a 10_000 insectes amusants dans ton jardin. - # - $chr = ( $this->do_space_thousand != -1 ? $this->space_thousand : '' ); - $_ = preg_replace('/([0-9]) ([0-9])/', "\\1$chr\\2", $_); - return $_; - } - - - var $units = ' - ### Metric units (with prefixes) - (?: - p | - µ | µ | &\#0*181; | &\#[xX]0*[Bb]5; | - [mcdhkMGT] - )? - (?: - [mgstAKNJWCVFSTHBL]|mol|cd|rad|Hz|Pa|Wb|lm|lx|Bq|Gy|Sv|kat| - Ω | Ohm | Ω | &\#0*937; | &\#[xX]0*3[Aa]9; - )| - ### Computers units (KB, Kb, TB, Kbps) - [kKMGT]?(?:[oBb]|[oBb]ps|flops)| - ### Money - ¢ | ¢ | &\#0*162; | &\#[xX]0*[Aa]2; | - M?(?: - £ | £ | &\#0*163; | &\#[xX]0*[Aa]3; | - ¥ | ¥ | &\#0*165; | &\#[xX]0*[Aa]5; | - € | € | &\#0*8364; | &\#[xX]0*20[Aa][Cc]; | - $ - )| - ### Other units - (?: ° | ° | &\#0*176; | &\#[xX]0*[Bb]0; ) [CF]? | - %|pt|pi|M?px|em|en|gal|lb|[NSEOW]|[NS][EOW]|ha|mbar - '; //x - - function spaceUnit($_) { - # - # Parameters: String, replacement character, and forcing flag. - # Returns: The string, with appropriates spaces replaced - # before unit symbols. - # - # Example input: Get 3 mol of fun for 3 $. - # Example output: Get 3_mol of fun for 3_$. - # - $opt = ( $this->do_space_unit == 2 ? '?' : '' ); - $chr = ( $this->do_space_unit != -1 ? $this->space_unit : '' ); - - $_ = preg_replace('/ - (?:([0-9])[ ]'.$opt.') # Number followed by space. - ('.$this->units.') # Unit. - (?![a-zA-Z0-9]) # Negative lookahead for other unit characters. - /x', - "\\1$chr\\2", $_); - - return $_; - } - - - function spaceAbbr($_) { - # - # Parameters: String, replacement character, and forcing flag. - # Returns: The string, with appropriates spaces replaced - # around abbreviations. - # - # Example input: Fun i.e. something pleasant. - # Example output: Fun i.e._something pleasant. - # - $opt = ( $this->do_space_abbr == 2 ? '?' : '' ); - - $_ = preg_replace("/(^|\s)($this->abbr_after) $opt/m", - "\\1\\2$this->space_abbr", $_); - $_ = preg_replace("/( )$opt($this->abbr_sp_before)(?![a-zA-Z'])/m", - "\\1$this->space_abbr\\2", $_); - return $_; - } - - - function stupefyEntities($_) { - # - # Adding angle quotes and lower quotes to SmartyPants's stupefy mode. - # - $_ = parent::stupefyEntities($_); - - $_ = str_replace(array('„', '«', '»'), '"', $_); - - return $_; - } - - - function processEscapes($_) { - # - # Adding a few more escapes to SmartyPants's escapes: - # - # Escape Value - # ------ ----- - # \, , - # \< < - # \> > - # - $_ = parent::processEscapes($_); - - $_ = str_replace( - array('\,', '\<', '\>', '\<', '\>'), - array(',', '<', '>', '<', '>'), $_); - - return $_; - } -} - - -/* - -PHP SmartyPants Typographer -=========================== - -Version History ---------------- - -1.0 (28 Jun 2006) - -* First public release of PHP SmartyPants Typographer. - - -Bugs ----- - -To file bug reports or feature requests (other than topics listed in the -Caveats section above) please send email to: - - - -If the bug involves quotes being curled the wrong way, please send example -text to illustrate. - - -### Algorithmic Shortcomings ### - -One situation in which quotes will get curled the wrong way is when -apostrophes are used at the start of leading contractions. For example: - - 'Twas the night before Christmas. - -In the case above, SmartyPants will turn the apostrophe into an opening -single-quote, when in fact it should be a closing one. I don't think -this problem can be solved in the general case -- every word processor -I've tried gets this wrong as well. In such cases, it's best to use the -proper HTML entity for closing single-quotes (`’`) by hand. - - -Copyright and License ---------------------- - -PHP SmartyPants & Typographer -Copyright (c) 2004-2006 Michel Fortin - -All rights reserved. - -Original SmartyPants -Copyright (c) 2003-2004 John Gruber - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -* Neither the name "SmartyPants" nor the names of its contributors may - be used to endorse or promote products derived from this software - without specific prior written permission. - -This software is provided by the copyright holders and contributors "as is" -and any express or implied warranties, including, but not limited to, the -implied warranties of merchantability and fitness for a particular purpose -are disclaimed. In no event shall the copyright owner or contributors be -liable for any direct, indirect, incidental, special, exemplary, or -consequential damages (including, but not limited to, procurement of -substitute goods or services; loss of use, data, or profits; or business -interruption) however caused and on any theory of liability, whether in -contract, strict liability, or tort (including negligence or otherwise) -arising in any way out of the use of this software, even if advised of the -possibility of such damage. - -*/ -?> \ No newline at end of file diff --git a/panel b/panel new file mode 160000 index 0000000..53ebd4b --- /dev/null +++ b/panel @@ -0,0 +1 @@ +Subproject commit 53ebd4b6964c02aab5671d2735f59ccc0178f144 diff --git a/panel/app/bootstrap.php b/panel/app/bootstrap.php deleted file mode 100644 index 2b73833..0000000 --- a/panel/app/bootstrap.php +++ /dev/null @@ -1,71 +0,0 @@ - 'panel.php', - - // global stuff - 'kirby\\panel\\login' => 'panel' . DS . 'login.php', - 'kirby\\panel\\translation' => 'panel' . DS . 'translation.php', - 'kirby\\panel\\autocomplete' => 'panel' . DS . 'autocomplete.php', - 'kirby\\panel\\roots' => 'panel' . DS . 'roots.php', - 'kirby\\panel\\urls' => 'panel' . DS . 'urls.php', - 'kirby\\panel\\view' => 'panel' . DS . 'view.php', - 'kirby\\panel\\layout' => 'panel' . DS . 'layout.php', - 'kirby\\panel\\snippet' => 'panel' . DS . 'snippet.php', - 'kirby\\panel\\installer' => 'panel' . DS . 'installer.php', - 'kirby\\panel\\widgets' => 'panel' . DS . 'widgets.php', - 'kirby\\panel\\topbar' => 'panel' . DS . 'topbar.php', - 'kirby\\panel\\search' => 'panel' . DS . 'search.php', - 'kirby\\panel\\structure' => 'panel' . DS . 'structure.php', - 'kirby\\panel\\structure\\store' => 'panel' . DS . 'structure' . DS . 'store.php', - 'kirby\\panel\\upload' => 'panel' . DS . 'upload.php', - - // controllers - 'kirby\\panel\\controllers\\base' => 'panel' . DS . 'controllers' . DS . 'base.php', - 'kirby\\panel\\controllers\\field' => 'panel' . DS . 'controllers' . DS . 'field.php', - - // form - 'kirby\\panel\\form' => 'panel' . DS . 'form.php', - 'kirby\\panel\\form\\plugins' => 'panel' . DS . 'form' . DS . 'plugins.php', - 'kirby\\panel\\form\\fieldoptions' => 'panel' . DS . 'form' . DS . 'fieldoptions.php', - - // models - 'kirby\\panel\\models\\site' => 'panel' . DS . 'models' . DS . 'site.php', - 'kirby\\panel\\models\\page' => 'panel' . DS . 'models' . DS . 'page.php', - 'kirby\\panel\\models\\page\\addbutton' => 'panel' . DS . 'models' . DS . 'page' . DS . 'addbutton.php', - 'kirby\\panel\\models\\page\\menu' => 'panel' . DS . 'models' . DS . 'page' . DS . 'menu.php', - 'kirby\\panel\\models\\page\\sidebar' => 'panel' . DS . 'models' . DS . 'page' . DS . 'sidebar.php', - 'kirby\\panel\\models\\page\\changes' => 'panel' . DS . 'models' . DS . 'page' . DS . 'changes.php', - 'kirby\\panel\\models\\page\\uploader' => 'panel' . DS . 'models' . DS . 'page' . DS . 'uploader.php', - 'kirby\\panel\\models\\page\\sorter' => 'panel' . DS . 'models' . DS . 'page' . DS . 'sorter.php', - 'kirby\\panel\\models\\page\\blueprint' => 'panel' . DS . 'models' . DS . 'page' . DS . 'blueprint.php', - 'kirby\\panel\\models\\page\\blueprint\\pages' => 'panel' . DS . 'models' . DS . 'page' . DS . 'blueprint' . DS . 'pages.php', - 'kirby\\panel\\models\\page\\blueprint\\files' => 'panel' . DS . 'models' . DS . 'page' . DS . 'blueprint' . DS . 'files.php', - 'kirby\\panel\\models\\page\\blueprint\\fields' => 'panel' . DS . 'models' . DS . 'page' . DS . 'blueprint' . DS . 'fields.php', - 'kirby\\panel\\models\\page\\blueprint\\field' => 'panel' . DS . 'models' . DS . 'page' . DS . 'blueprint' . DS . 'field.php', - 'kirby\\panel\\models\\page\\blueprint\\options' => 'panel' . DS . 'models' . DS . 'page' . DS . 'blueprint' . DS . 'options.php', - 'kirby\\panel\\models\\file' => 'panel' . DS . 'models' . DS . 'file.php', - 'kirby\\panel\\models\\file\\menu' => 'panel' . DS . 'models' . DS . 'file' . DS . 'menu.php', - 'kirby\\panel\\models\\user' => 'panel' . DS . 'models' . DS . 'user.php', - 'kirby\\panel\\models\\user\\blueprint' => 'panel' . DS . 'models' . DS . 'user' . DS . 'blueprint.php', - 'kirby\\panel\\models\\user\\avatar' => 'panel' . DS . 'models' . DS . 'user' . DS . 'avatar.php', - 'kirby\\panel\\models\\user\\history' => 'panel' . DS . 'models' . DS . 'user' . DS . 'history.php', - - // collections - 'kirby\\panel\\collections\\users' => 'panel' . DS . 'collections' . DS . 'users.php', - 'kirby\\panel\\collections\\files' => 'panel' . DS . 'collections' . DS . 'files.php', - 'kirby\\panel\\collections\\children' => 'panel' . DS . 'collections' . DS . 'children.php', - -), __DIR__ . DS . 'src'); - - -// some fallbacks for possible namespace issues and convenience -class_alias('Kirby\\Panel\\Form\\FieldOptions', 'FieldOptions'); -class_alias('Kirby\\Panel', 'Panel'); - -include(__DIR__ . DS . 'helpers.php'); - diff --git a/panel/app/config/routes.php b/panel/app/config/routes.php deleted file mode 100644 index 6607eef..0000000 --- a/panel/app/config/routes.php +++ /dev/null @@ -1,298 +0,0 @@ - 'login', - 'action' => 'AuthController::login', - 'filter' => 'isInstalled', - 'method' => 'GET|POST' - ), - array( - 'pattern' => 'logout', - 'action' => 'AuthController::logout', - 'method' => 'GET', - 'filter' => 'auth', - ), - - // Installation - array( - 'pattern' => 'install', - 'action' => 'InstallationController::index', - 'method' => 'GET|POST' - ), - - // Dashboard - array( - 'pattern' => '/', - 'action' => 'DashboardController::index', - 'filter' => array('auth', 'isInstalled'), - ), - - // Search - array( - 'pattern' => 'search', - 'action' => 'SearchController::results', - 'method' => 'GET|POST', - 'filter' => array('auth'), - ), - - // Options - array( - 'pattern' => 'options', - 'action' => 'OptionsController::index', - 'method' => 'GET|POST', - 'filter' => 'auth' - ), - - // Files - array( - 'pattern' => array( - 'site(/)file/(:any)/edit', - 'pages/(:all)/file/(:any)/edit', - ), - 'action' => 'FilesController::edit', - 'filter' => 'auth', - 'method' => 'POST|GET', - ), - array( - 'pattern' => array( - 'site(/)file/(:any)/context', - 'pages/(:all)/file/(:any)/context', - ), - 'action' => 'FilesController::context', - 'filter' => 'auth', - 'method' => 'GET', - ), - array( - 'pattern' => array( - 'site(/)file/(:any)/thumb', - 'pages/(:all)/file/(:any)/thumb', - ), - 'action' => 'FilesController::thumb', - 'filter' => 'auth', - 'method' => 'GET', - ), - array( - 'pattern' => array( - 'site(/)file/(:any)/delete', - 'pages/(:all)/file/(:any)/delete', - ), - 'action' => 'FilesController::delete', - 'filter' => 'auth', - 'method' => 'POST|GET', - ), - array( - 'pattern' => array( - 'site(/)file/(:any)/replace', - 'pages/(:all)/file/(:any)/replace', - ), - 'action' => 'FilesController::replace', - 'filter' => 'auth', - 'method' => 'POST', - ), - array( - 'pattern' => array( - 'site(/)files', - 'pages/(:all)/files', - ), - 'action' => 'FilesController::index', - 'filter' => 'auth', - 'method' => 'POST|GET', - ), - - // Field routes - array( - 'pattern' => array( - 'site(/)file/(:any)/field/(:any)/(:any)/(:all)', - 'pages/(:all)/file/(:any)/field/(:any)/(:any)/(:all)', - ), - 'action' => 'FieldController::forFile', - 'filter' => 'auth', - 'method' => 'GET|POST' - ), - array( - 'pattern' => array( - 'site(/)field/(:any)/(:any)/(:all)', - 'pages/(:all)/field/(:any)/(:any)/(:all)', - ), - 'action' => 'FieldController::forPage', - 'filter' => 'auth', - 'method' => 'GET|POST' - ), - array( - 'pattern' => array( - 'users/(:all)/field/(:any)/(:any)/(:all)', - ), - 'action' => 'FieldController::forUser', - 'filter' => 'auth', - 'method' => 'GET|POST' - ), - - // New Page - array( - 'pattern' => array( - 'site(/)add', - 'pages/(:all)/add', - ), - 'action' => 'PagesController::add', - 'filter' => 'auth', - 'method' => 'POST|GET' - ), - - // URL Settings - array( - 'pattern' => 'pages/(:all)/url', - 'action' => 'PagesController::url', - 'filter' => 'auth', - 'method' => 'POST|GET' - ), - - // Template Modal - array( - 'pattern' => 'pages/(:all)/template', - 'action' => 'PagesController::template', - 'filter' => 'auth', - 'method' => 'POST|GET' - ), - - // Toggle visibility - array( - 'pattern' => 'pages/(:all)/toggle', - 'action' => 'PagesController::toggle', - 'filter' => 'auth', - 'method' => 'POST|GET' - ), - - // Delete a page - array( - 'pattern' => 'pages/(:all)/delete', - 'action' => 'PagesController::delete', - 'filter' => 'auth', - 'method' => 'POST|GET' - ), - - // Keeping page changes - array( - 'pattern' => array( - 'site(/)keep', - 'pages/(:all)/keep', - ), - 'action' => 'PagesController::keep', - 'method' => 'GET|POST', - 'filter' => 'auth', - ), - - // Discarding page changes - array( - 'pattern' => array( - 'site(/)discard', - 'pages/(:all)/discard', - ), - 'action' => 'PagesController::discard', - 'method' => 'GET|POST', - 'filter' => 'auth', - ), - - // Page context menu - array( - 'pattern' => 'pages/(:all)/context', - 'action' => 'PagesController::context', - 'method' => 'GET', - 'filter' => 'auth', - ), - - // Upload a file - array( - 'pattern' => array( - 'site(/)upload', - 'pages/(:all)/upload', - ), - 'action' => 'FilesController::upload', - 'filter' => 'auth', - 'method' => 'POST' - ), - - // Subpages - array( - 'pattern' => array( - 'site(/)subpages', - 'pages/(:all)/subpages', - ), - 'action' => 'SubpagesController::index', - 'filter' => 'auth', - 'method' => 'POST|GET' - ), - - // Page - array( - 'pattern' => 'pages/(:all)/edit', - 'action' => 'PagesController::edit', - 'filter' => 'auth', - 'method' => 'POST|GET' - ), - - // Users - array( - 'pattern' => 'users', - 'action' => 'UsersController::index', - 'filter' => 'auth' - ), - array( - 'pattern' => 'users/add', - 'action' => 'UsersController::add', - 'filter' => 'auth', - 'method' => 'POST|GET' - ), - array( - 'pattern' => 'users/(:any)/edit', - 'action' => 'UsersController::edit', - 'filter' => 'auth', - 'method' => 'POST|GET' - ), - array( - 'pattern' => 'users/(:any)/delete', - 'action' => 'UsersController::delete', - 'filter' => 'auth', - 'method' => 'POST|GET' - ), - - // Avatars - array( - 'pattern' => 'users/(:any)/avatar', - 'action' => 'AvatarsController::upload', - 'filter' => 'auth', - 'method' => 'POST' - ), - array( - 'pattern' => 'users/(:any)/avatar/delete', - 'action' => 'AvatarsController::delete', - 'filter' => 'auth', - 'method' => 'POST|GET' - ), - - // Autocomplete - array( - 'pattern' => 'api/autocomplete/(:any)', - 'action' => 'AutocompleteController::index', - 'method' => 'POST', - 'filter' => 'auth', - ), - - // form assets - array( - 'pattern' => 'plugins/js', - 'action' => 'AssetsController::js', - 'method' => 'GET', - 'filter' => 'auth' - ), - array( - 'pattern' => 'plugins/css', - 'action' => 'AssetsController::css', - 'method' => 'GET', - 'filter' => 'auth' - ), - -); \ No newline at end of file diff --git a/panel/app/controllers/assets.php b/panel/app/controllers/assets.php deleted file mode 100644 index 705356f..0000000 --- a/panel/app/controllers/assets.php +++ /dev/null @@ -1,17 +0,0 @@ -plugins()->js(), 'text/javascript'); - } - - public function css() { - $form = new Form(); - return new Response($form->plugins()->css(), 'text/css'); - } - -} \ No newline at end of file diff --git a/panel/app/controllers/auth.php b/panel/app/controllers/auth.php deleted file mode 100644 index 5e0f399..0000000 --- a/panel/app/controllers/auth.php +++ /dev/null @@ -1,62 +0,0 @@ -layout('base', array( - 'content' => $this->view('auth/error', array( - 'error' => $e->getMessage() - )) - )); - } - - if($login->isAuthenticated()) { - $this->redirect(); - } - - if($login->isBlocked()) { - return $this->layout('base', array( - 'content' => $this->view('auth/block') - )); - } - - $self = $this; - $form = $this->form('auth/login', null, function($form) use($self, $login) { - - $data = $form->serialize(); - - try { - $login->attempt($data['username'], $data['password']); - $self->redirect(); - } catch(Exception $e) { - $form->alert(l('login.error')); - $form->fields->username->error = true; - $form->fields->password->error = true; - } - - }); - - return $this->layout('base', array( - 'bodyclass' => 'login', - 'content' => $this->view('auth/login', compact('form')) - )); - - } - - public function logout() { - - if($user = panel()->user()) { - $user->logout(); - } - - $this->redirect('login'); - - } - -} \ No newline at end of file diff --git a/panel/app/controllers/autocomplete.php b/panel/app/controllers/autocomplete.php deleted file mode 100644 index 6ec6b84..0000000 --- a/panel/app/controllers/autocomplete.php +++ /dev/null @@ -1,20 +0,0 @@ -result(); - } catch(Exception $e) { - $result = array(); - } - - return $this->json(array( - 'data' => $result - )); - - } - -} \ No newline at end of file diff --git a/panel/app/controllers/avatars.php b/panel/app/controllers/avatars.php deleted file mode 100644 index c82c2bf..0000000 --- a/panel/app/controllers/avatars.php +++ /dev/null @@ -1,49 +0,0 @@ -user($username); - - try { - $user->avatar()->upload(); - $this->notify(':)'); - } catch(Exception $e) { - $this->alert($e->getMessage()); - } - - $this->redirect($user); - - } - - public function delete($username) { - - $self = $this; - $user = $this->user($username); - $avatar = $user->avatar(); - - if(!$avatar->exists()) { - return $this->modal('error', array( - 'text' => l('users.avatar.missing'), - 'back' => $user->url() - )); - } - - $form = $avatar->form('delete', function($form) use($user, $avatar, $self) { - - try { - $avatar->delete(); - $self->notify(':)'); - $self->redirect($user); - } catch(Exception $e) { - $form->alert($e->getMessage()); - } - - }); - - return $this->modal('avatars/delete', compact('form')); - - } - -} \ No newline at end of file diff --git a/panel/app/controllers/dashboard.php b/panel/app/controllers/dashboard.php deleted file mode 100644 index 5f3f843..0000000 --- a/panel/app/controllers/dashboard.php +++ /dev/null @@ -1,13 +0,0 @@ -screen('dashboard/index', panel()->site(), array( - 'widgets' => new Kirby\Panel\Widgets() - )); - - } - -} \ No newline at end of file diff --git a/panel/app/controllers/error.php b/panel/app/controllers/error.php deleted file mode 100644 index cf6ee6f..0000000 --- a/panel/app/controllers/error.php +++ /dev/null @@ -1,35 +0,0 @@ -auth(); - - if(is_null($text)) { - $text = l('pages.error.missing'); - } - - if(server::get('HTTP_MODAL')) { - return $this->modal('error', array( - 'text' => $text, - 'back' => url::last(), - )); - } else { - return $this->screen('error/index', 'error', array( - 'text' => $text, - 'exception' => $exception - )); - } - - } - - public function auth() { - try { - $user = panel()->user(); - } catch(Exception $e) { - $this->redirect('login'); - } - } - -} \ No newline at end of file diff --git a/panel/app/controllers/field.php b/panel/app/controllers/field.php deleted file mode 100644 index ae571c3..0000000 --- a/panel/app/controllers/field.php +++ /dev/null @@ -1,82 +0,0 @@ -page($pageId); - $file = $page->file(File::decodeFilename($filename)); - - if(!$file) { - throw new Exception(l('files.error.missing.file')); - } - - $form = $file->form('edit', function() {}); - - return $this->route($file, $form, $fieldName, $fieldType, $path); - - } - - public function forPage($pageId, $fieldName, $fieldType, $path) { - - $page = $this->page($pageId); - $form = $page->form('edit', function() {}); - - return $this->route($page, $form, $fieldName, $fieldType, $path); - - } - - public function forUser($username, $fieldName, $fieldType, $path) { - - $user = panel()->user($username); - $form = $user->form('user', function() {}); - - return $this->route($user, $form, $fieldName, $fieldType, $path); - - } - - public function route($model, $form, $fieldName, $fieldType, $path) { - - $field = $form->fields()->$fieldName; - - if(!$field or $field->type() !== $fieldType) { - throw new Exception('Invalid field'); - } - - $routes = $field->routes(); - $router = new Router($routes); - - if($route = $router->run($path)) { - - if(is_callable($route->action()) and is_a($route->action(), 'Closure')) { - return call($route->action(), $route->arguments()); - } else { - - $controllerFile = $field->root() . DS . 'controller.php'; - $controllerName = $fieldType . 'FieldController'; - - if(!file_exists($controllerFile)) { - throw new Exception(l('fields.error.missing.controller')); - } - - require_once($controllerFile); - - if(!class_exists($controllerName)) { - throw new Exception(l('fields.error.missing.class')); - } - - $controller = new $controllerName($model, $field); - - return call(array($controller, $route->action()), $route->arguments()); - - } - - } else { - throw new Exception(l('fields.error.route.invalid')); - } - - } - -} \ No newline at end of file diff --git a/panel/app/controllers/files.php b/panel/app/controllers/files.php deleted file mode 100644 index 3740234..0000000 --- a/panel/app/controllers/files.php +++ /dev/null @@ -1,195 +0,0 @@ -page($id); - $files = $page->files(); - - // don't create the view if the page is not allowed to have files - if(!$page->canHaveFiles()) { - throw new Exception(l('files.index.error.disabled')); - } - - // sort action - $this->sort($page); - - return $this->screen('files/index', $files, array( - 'page' => $page, - 'files' => $files, - 'back' => $page->url('edit'), - 'sortable' => $page->canSortFiles(), - 'uploader' => $this->snippet('uploader', array('url' => $page->url('upload'))) - )); - - } - - public function edit($id, $filename) { - - $self = $this; - $page = $this->page($id); - - try { - $file = $this->file($page, $filename); - } catch(Exception $e) { - $this->alert(l('files.error.missing.file')); - $this->redirect($page); - } - - // setup the form and form action - $form = $file->form('edit', function($form) use($file, $page, $self) { - - $form->validate(); - - if(!$form->isValid()) { - return $self->alert(l('files.show.error.form')); - } - - try { - $file->update($form->serialize()); - $self->notify(':)'); - $self->redirect($file); - } catch(Exception $e) { - $self->alert($e->getMessage()); - } - - }); - - return $this->screen('files/edit', $file, array( - 'form' => $form, - 'page' => $page, - 'file' => $file, - 'returnTo' => url::last() == $page->url('files') ? $page->uri('files') : $page->uri('edit'), - 'uploader' => $this->snippet('uploader', array( - 'url' => $file->url('replace'), - 'accept' => $file->mime(), - 'multiple' => false - )) - )); - - } - - public function upload($id) { - - $page = $this->page($id); - - try { - $page->upload(); - $this->notify(':)'); - } catch(Exception $e) { - $this->alert($e->getMessage()); - } - - $this->redirect($page); - - } - - public function replace($id, $filename) { - - $page = $this->page($id); - $file = $this->file($page, $filename); - - try { - $file->replace(); - $this->notify(':)'); - } catch(Exception $e) { - $this->alert($e->getMessage()); - } - - $this->redirect($file); - - } - - public function context($id, $filename) { - - $page = $this->page($id); - $file = $this->file($page, $filename); - - return $file->menu(); - - } - - public function thumb($id, $filename) { - - $page = $this->page($id); - $file = $this->file($page, $filename); - $width = intval(get('width')); - $height = intval(get('height')); - - if(!$file->canHavePreview()) { - return response::error('No preview available', 404); - } - - if(!$file->canHaveThumb()) { - go($file->url()); - } - - if(get('crop') == true) { - $thumb = $file->crop($width, $height, 80); - } else { - $thumb = $file->resize($width, $height, 80); - } - - go($thumb->url()); - - } - - public function delete($id, $filename) { - - $self = $this; - $page = $this->page($id); - $file = $this->file($page, $filename); - $form = $this->form('files/delete', $file, function($form) use($file, $page, $self) { - - try { - $file->delete(); - $self->notify(':)'); - $self->redirect($page, 'edit'); - } catch(Exception $e) { - $form->alert($e->getMessage()); - } - - }); - - return $this->modal('files/delete', compact('form')); - - } - - protected function file($page, $filename) { - - $file = $page->file(File::decodeFilename($filename)); - - if(!$file) { - throw new Exception(l('files.error.missing.file')); - } - - return $file; - - } - - protected function sort($page) { - - if(!r::is('post') or get('action') != 'sort') return; - - $filenames = get('filenames'); - $counter = 0; - - foreach($filenames as $filename) { - if($file = $page->file($filename)) { - $counter++; - try { - $file->update('sort', $counter); - } catch(Exception $e) { - - } - } - } - - $this->redirect($page, 'files'); - - } - -} \ No newline at end of file diff --git a/panel/app/controllers/installation.php b/panel/app/controllers/installation.php deleted file mode 100644 index e9fc0b7..0000000 --- a/panel/app/controllers/installation.php +++ /dev/null @@ -1,76 +0,0 @@ -isCompleted()) { - $this->redirect(); - } else if($problems = $installer->problems()) { - return $this->problems($problems); - } else { - return $this->signup(); - } - - } - - protected function problems($problems) { - $form = $this->form('installation/check', array($problems)); - return $this->modal('index', compact('form')); - } - - protected function signup() { - - $self = $this; - $form = $this->form('installation/signup', array(), function($form) use($self) { - - $form->validate(); - - if(!$form->isValid()) { - return false; - } - - try { - - // fetch all the form data - $data = $form->serialize(); - - // make sure that the first user is an admin - $data['role'] = 'admin'; - - // try to create the new user - $user = site()->users()->create($data); - - // store the new username for the login screen - s::set('username', $user->username()); - - // try to login the user automatically - if($user->hasPanelAccess()) { - $user->login($data['password']); - } - - // redirect to the login - $self->redirect('login'); - - } catch(Exception $e) { - $form->alert($e->getMessage()); - } - - }); - - return $this->modal('index', compact('form')); - - } - - public function modal($view, $data = array()) { - return $this->layout('base', array( - 'bodyclass' => 'installation', - 'content' => $this->view('installation/' . $view, $data) - )); - } - -} \ No newline at end of file diff --git a/panel/app/controllers/options.php b/panel/app/controllers/options.php deleted file mode 100644 index d33c259..0000000 --- a/panel/app/controllers/options.php +++ /dev/null @@ -1,40 +0,0 @@ -site(); - $sidebar = $site->sidebar(); - $form = $site->form('edit', function($form) use($site, $self) { - - // validate all fields - $form->validate(); - - // stop at invalid fields - if(!$form->isValid()) { - return $self->alert(l('pages.show.error.form')); - } - - try { - $site->update($form->serialize()); - $self->notify(':)'); - return $self->redirect('options'); - } catch(Exception $e) { - return $self->alert($e->getMessage()); - } - - }); - - return $this->screen('options/index', $site, array( - 'site' => $site, - 'form' => $form, - 'files' => $sidebar->files(), - 'license' => panel()->license(), - 'uploader' => $this->snippet('uploader', array('url' => $site->url('upload'))) - )); - - } - -} \ No newline at end of file diff --git a/panel/app/controllers/pages.php b/panel/app/controllers/pages.php deleted file mode 100644 index 11d2d51..0000000 --- a/panel/app/controllers/pages.php +++ /dev/null @@ -1,218 +0,0 @@ -page($id); - $form = $parent->form('add', function($form) use($parent, $self) { - - $form->validate(); - - if(!$form->isValid()) { - return $form->alert(l('pages.add.error.template')); - } - - try { - - $data = $form->serialize(); - $page = $parent->children()->create($data['uid'], $data['template'], array( - 'title' => $data['title'] - )); - - $self->notify(':)'); - $this->redirect($page, 'edit'); - - } catch(Exception $e) { - $form->alert($e->getMessage()); - } - - }); - - return $this->modal('pages/add', compact('form')); - - } - - public function edit($id) { - - $self = $this; - - try { - $page = $this->page($id); - } catch(Exception $e) { - if($page = $this->page(dirname($id))) { - $this->alert(l('pages.error.missing')); - $this->redirect($page); - } - } - - $form = $page->form('edit', function($form) use($page, $self) { - - // validate all fields - $form->validate(); - - // stop at invalid fields - if(!$form->isValid()) { - return $self->alert(l('pages.show.error.form')); - } - - try { - $page->update($form->serialize()); - $self->notify(':)'); - return $self->redirect($page); - } catch(Exception $e) { - return $self->alert($e->getMessage()); - } - - }); - - return $this->screen('pages/edit', $page, array( - 'page' => $page, - 'sidebar' => $page->sidebar(), - 'form' => $form, - 'uploader' => $this->snippet('uploader', array('url' => $page->url('upload'))) - )); - - } - - public function delete($id) { - - $self = $this; - $page = $this->page($id); - - try { - $page->isDeletable(true); - } catch(Exception $e) { - return $this->modal('error', array( - 'headline' => l($e->getMessage() . '.headline'), - 'text' => l($e->getMessage() . '.text'), - 'back' => $page->url() - )); - } - - $form = $page->form('delete', function($form) use($page, $self) { - try { - $page->delete(); - $self->notify(':)'); - $self->redirect($page->parent()->isSite() ? '/' : $page->parent()); - } catch(Exception $e) { - $form->alert($e->getMessage()); - } - }); - - return $this->modal('pages/delete', compact('form')); - - } - - public function keep($id) { - $page = $this->page($id); - $page->changes()->keep(); - $this->redirect($page); - } - - public function discard($id) { - $page = $this->page($id); - $page->changes()->discard(); - $this->redirect($page); - } - - public function url($id) { - - $self = $this; - $page = $this->page($id); - - if(!$page->canChangeUrl()) { - return $this->modal('error', array( - 'headline' => l('error'), - 'text' => l('pages.url.error.rights'), - )); - } - - $form = $page->form('url', function($form) use($page, $self) { - - try { - $page->move(get('uid')); - $self->notify(':)'); - $self->redirect($page); - } catch(Exception $e) { - $form->alert($e->getMessage()); - $form->fields->uid->error = true; - } - - }); - - return $this->modal('pages/url', compact('form')); - - } - - public function template($id) { - - $self = $this; - $page = $this->page($id); - - if(!$page->canChangeTemplate()) { - return $this->modal('error', array( - 'headline' => l('error'), - 'text' => l('pages.template.error'), - )); - } - - if($info = get('info')) { - $prep = $page->prepareForNewTemplate($page->blueprint()->name(), $info); - return $this->snippet('template', $prep); - } - - $form = $page->form('template', function($form) use($page, $self) { - - try { - - $data = $form->serialize(); - - $page->changeTemplate(a::get($data, 'template')); - - $self->notify(':)'); - $self->redirect($page); - } catch(Exception $e) { - $form->alert($e->getMessage()); - } - - }); - - return $this->modal('pages/template', compact('form')); - - } - - public function toggle($id) { - - $self = $this; - $page = $this->page($id); - - if($page->isErrorPage()) { - return $this->modal('error', array( - 'headline' => l('error'), - 'text' => l('pages.toggle.error.error'), - )); - } - - $form = $page->form('toggle', function($form) use($page, $self) { - - try { - $page->toggle(get('position', 'last')); - $self->notify(':)'); - $self->redirect($page); - } catch(Exception $e) { - $form->alert($e->getMessage()); - } - - }); - - return $this->modal('pages/toggle', compact('form')); - - } - - public function context($id) { - return $this->page($id)->menu('context'); - } - -} \ No newline at end of file diff --git a/panel/app/controllers/search.php b/panel/app/controllers/search.php deleted file mode 100644 index b2a43ff..0000000 --- a/panel/app/controllers/search.php +++ /dev/null @@ -1,18 +0,0 @@ -view('search/results', array( - 'pages' => $search->pages(), - 'users' => $search->users(), - )); - - } - -} \ No newline at end of file diff --git a/panel/app/controllers/subpages.php b/panel/app/controllers/subpages.php deleted file mode 100644 index 7cac180..0000000 --- a/panel/app/controllers/subpages.php +++ /dev/null @@ -1,91 +0,0 @@ -page($id); - - // don't create the view if the page is not allowed to have subpages - if(!$page->canHaveSubpages()) { - throw new Exception(l('subpages.add.error')); - } - - // get the subpages - $visible = $this->visible($page); - $invisible = $this->invisible($page); - - // activate the sorting - $this->sort($page); - - return $this->screen('subpages/index', $page, array( - 'page' => $page, - 'addbutton' => $page->addbutton(), - 'sortable' => $page->blueprint()->pages()->sortable(), - 'flip' => $page->blueprint()->pages()->sort() == 'flip', - 'visible' => $visible, - 'invisible' => $invisible, - )); - - } - - protected function subpages($page, $type) { - - $pages = $page->children()->$type()->paginated('subpages/' . $type); - $pagination = $this->snippet('pagination', array( - 'pagination' => $pages->pagination(), - 'nextUrl' => $pages->pagination()->nextPageUrl(), - 'prevUrl' => $pages->pagination()->prevPageUrl(), - )); - - return new Obj(array( - 'pages' => $pages, - 'pagination' => $pagination, - 'start' => $pages->pagination()->numStart(), - 'total' => $pages->pagination()->items(), - 'firstPage' => $pages->pagination()->firstPageUrl(), - )); - - } - - protected function visible($page) { - return $this->subpages($page, 'visible'); - } - - protected function invisible($page) { - return $this->subpages($page, 'invisible'); - } - - protected function sort($page) { - - // handle sorting - if(r::is('post') and $action = get('action') and $id = get('id')) { - - $subpage = $this->page($page->id() . '/' . $id); - - switch($action) { - case 'sort': - try { - $subpage->sort(get('to')); - } catch(Exception $e) { - // no error handling, because if sorting - // breaks, the refresh will fix it. - } - break; - case 'hide': - try { - $subpage->hide(); - } catch(Exception $e) { - // no error handling, because if sorting - // breaks, the refresh will fix it. - } - break; - } - - $this->redirect($page, 'subpages'); - - } - - } - -} \ No newline at end of file diff --git a/panel/app/controllers/users.php b/panel/app/controllers/users.php deleted file mode 100644 index ba41eea..0000000 --- a/panel/app/controllers/users.php +++ /dev/null @@ -1,134 +0,0 @@ -users()->paginate(20, array('method' => 'query')); - $admin = panel()->user()->isAdmin(); - $pagination = $this->snippet('pagination', array( - 'pagination' => $users->pagination(), - 'nextUrl' => $users->pagination()->nextPageUrl(), - 'prevUrl' => $users->pagination()->prevPageUrl(), - )); - - return $this->screen('users/index', $users, array( - 'users' => $users, - 'admin' => $admin, - 'pagination' => $pagination - )); - - } - - public function add() { - - if(!panel()->user()->isAdmin()) { - $this->redirect('users'); - } - - $self = $this; - $form = $this->form('users/user', null, function($form) use($self) { - - $form->validate(); - - if(!$form->isValid()) { - return false; - } - - $data = $form->serialize(); - - try { - $user = panel()->users()->create($data); - $self->notify(':)'); - $self->redirect('users'); - } catch(Exception $e) { - $self->alert($e->getMessage()); - } - - }); - - return $this->screen('users/edit', 'user', array( - 'user' => null, - 'form' => $form, - 'writable' => is_writable(kirby()->roots()->accounts()), - 'uploader' => null - )); - - } - - public function edit($username) { - - $self = $this; - $user = $this->user($username); - - if(!panel()->user()->isAdmin() and !$user->isCurrent()) { - $this->redirect('users'); - } - - $form = $user->form('user', function($form) use($user, $self) { - - $form->validate(); - - if(!$form->isValid()) { - return false; - } - - $data = $form->serialize(); - - try { - $user->update($data); - $self->notify(':)'); - $self->redirect($user, 'edit'); - } catch(Exception $e) { - $self->alert($e->getMessage()); - } - - }); - - return $this->screen('users/edit', $user, array( - 'user' => $user, - 'form' => $form, - 'writable' => is_writable(kirby()->roots()->accounts()), - 'uploader' => $this->snippet('uploader', array( - 'url' => $user->url('avatar'), - 'accept' => 'image/jpeg,image/png,image/gif', - 'multiple' => false - )) - )); - - } - - public function delete($username) { - - $user = $this->user($username); - $self = $this; - - if(!panel()->user()->isAdmin() and !$user->isCurrent()) { - return $this->modal('error', array( - 'headline' => l('error'), - 'text' => l('users.delete.error.rights'), - 'back' => purl('users') - )); - } else { - - $form = $user->form('delete', function($form) use($user, $self) { - - try { - $user->delete(); - $self->notify(':)'); - $self->redirect('users'); - } catch(Exception $e) { - $form->alert($e->getMessage()); - } - - }); - - return $this->modal('users/delete', compact('form')); - - } - - } - -} \ No newline at end of file diff --git a/panel/app/fields/base/base.php b/panel/app/fields/base/base.php deleted file mode 100644 index 2d991ce..0000000 --- a/panel/app/fields/base/base.php +++ /dev/null @@ -1,191 +0,0 @@ - array(), 'css' => array()); - - public $id; - public $name; - public $input; - public $label; - public $icon; - public $type; - public $help; - public $value; - public $text; - public $autofocus; - public $placeholder; - public $options; - public $content; - public $readonly; - public $disabled; - public $required; - public $validate; - public $width; - public $default; - public $error = false; - public $parentField = false; - public $page; - public $model; - - public function root() { - $obj = new ReflectionClass($this); - return dirname($obj->getFileName()); - } - - public function validate() { - - try { - - if(!$this->validate) { - return true; - } else if(is_array($this->validate)) { - foreach($this->validate as $validator => $options) { - if(!is_null($options)) { - if(is_numeric($validator)) { - $result = call('v::' . $options, $this->value()); - } else { - $result = call('v::' . $validator, array($this->value(), $options)); - } - if(!$result) return false; - } - } - return true; - } else { - return call('v::' . $this->validate, $this->value()); - } - - } catch(Exception $e) { - return true; - } - - } - - public function result() { - return get($this->name()); - } - - public function __call($name, $args) { - return isset($this->{$name}) ? $this->{$name} : null; - } - - public function id() { - if(!is_null($this->id)) return $this->id; - return 'form-field-' . $this->name; - } - - public function label() { - - if(!$this->label) return null; - - $label = new Brick('label', $this->i18n($this->label)); - $label->addClass('label'); - $label->attr('for', $this->id()); - - if($this->required()) { - $label->append(new Brick('abbr', '*', array('title' => l::get('required', 'Required')))); - } - - return $label; - - } - - public function i18n($value) { - return i18n($value); - } - - public function icon() { - - if(empty($this->icon)) { - return null; - } else if($this->readonly() and empty($this->icon)) { - $this->icon = 'lock'; - } - - $i = new Brick('i'); - $i->addClass('icon fa fa-' . $this->icon); - - $icon = new Brick('div'); - $icon->addClass('field-icon'); - $icon->append($i); - - return $icon; - - } - - public function help() { - - if(!$this->help) return null; - - $help = new Brick('div'); - $help->addClass('field-help marginalia text'); - $help->html($this->i18n($this->help)); - return $help; - - } - - public function input() { - return $this->input; - } - - public function content() { - - $content = new Brick('div'); - $content->addClass('field-content'); - $content->append($this->input()); - $content->append($this->icon()); - return $content; - - } - - public function element() { - - $element = new Brick('div'); - - $element->addClass('field'); - $element->addClass('field-grid-item'); - - if($this->error) { - $element->addClass('field-with-error'); - } - - if($this->width) { - $element->addClass('field-grid-item-' . str_replace('/', '-', $this->width)); - } - - if($this->readonly) { - $element->addClass('field-is-readonly'); - } - - if($this->disabled) { - $element->addClass('field-is-disabled'); - } - - if($this->icon) { - $element->addClass('field-with-icon'); - } - - $element->addClass('field-name-' . $this->name); - - return $element; - - } - - public function template() { - - return $this->element() - ->append($this->label()) - ->append($this->content()) - ->append($this->help()); - - } - - public function __toString() { - try { - return (string)$this->template(); - } catch(Exception $e) { - return (string)$e->getMessage(); - } - } - -} \ No newline at end of file diff --git a/panel/app/fields/checkbox/checkbox.php b/panel/app/fields/checkbox/checkbox.php deleted file mode 100644 index c1db055..0000000 --- a/panel/app/fields/checkbox/checkbox.php +++ /dev/null @@ -1,46 +0,0 @@ -addClass('checkbox'); - $input->attr(array( - 'id' => $this->id(), - 'name' => $this->name(), - 'required' => $this->required(), - 'autofocus' => $this->autofocus(), - 'autocomplete' => $this->autocomplete(), - 'readonly' => $this->readonly(), - 'type' => 'checkbox', - 'checked' => v::accepted($this->value()), - )); - - $wrapper = parent::input(); - $wrapper->tag('label'); - $wrapper->text($this->i18n($this->text())); - $wrapper->attr('for', $this->id()); - $wrapper->removeAttr('id'); - $wrapper->addClass('input-with-checkbox'); - $wrapper->prepend($input); - - return $wrapper; - - } - - public function value() { - $value = parent::value(); - return empty($value) ? '0' : $value; - } - - public function result() { - $result = parent::result(); - return v::accepted($result) ? '1' : '0'; - } - - public function validate() { - return v::accepted($this->value()) or v::denied($this->value()); - } - -} \ No newline at end of file diff --git a/panel/app/fields/checkboxes/checkboxes.php b/panel/app/fields/checkboxes/checkboxes.php deleted file mode 100644 index fb100ae..0000000 --- a/panel/app/fields/checkboxes/checkboxes.php +++ /dev/null @@ -1,45 +0,0 @@ -replaceClass('radio', 'checkbox'); - $input->attr(array( - 'name' => $this->name() . '[]', - 'type' => 'checkbox', - 'value' => $value, - 'checked' => ($this->value === 'all') ? true : in_array($value, (array)$this->value()), - 'required' => false, - )); - - return $input; - - } - - public function value() { - - $value = InputListField::value(); - - if(is_array($value)) { - return $value; - } else { - return str::split($value, ','); - } - - } - - public function result() { - $result = parent::result(); - return is_array($result) ? implode(', ', $result) : ''; - } - - public function item($value, $text) { - $item = parent::item($value, $text); - $item->replaceClass('input-with-radio', 'input-with-checkbox'); - return $item; - } - -} diff --git a/panel/app/fields/date/assets/js/date.js b/panel/app/fields/date/assets/js/date.js deleted file mode 100755 index 8d97e6a..0000000 --- a/panel/app/fields/date/assets/js/date.js +++ /dev/null @@ -1,50 +0,0 @@ -(function($) { - - $.fn.date = function() { - - return this.each(function() { - - if($(this).data('pikaday')) { - return $(this); - } - - var input = $(this).attr('type', 'text'); - var hidden = input.next(); - var format = input.data('format'); - var val = input.val(); - var date = val ? moment(val).format(format) : null; - - input.attr('placeholder', format); - input.val(date); - - // don't initialize the datepicker on readonly fields - if(input.is('[readonly]')) { - return false; - } - - input.on('change', function() { - var val = input.val(); - if(val) { - hidden.val(moment(val, format).format('YYYY-MM-DD')); - } else { - hidden.val(''); - } - }); - - var pikaday = new Pikaday({ - field : this, - firstDay : 1, - format : format, - i18n : input.data('i18n'), - onSelect : function(date) { - hidden.val(moment(date).format('YYYY-MM-DD')); - } - }); - - $(this).data('pikaday', pikaday); - - }); - - }; - -})(jQuery); \ No newline at end of file diff --git a/panel/app/fields/date/date.php b/panel/app/fields/date/date.php deleted file mode 100644 index cd6648c..0000000 --- a/panel/app/fields/date/date.php +++ /dev/null @@ -1,63 +0,0 @@ - array( - 'date.js' - ) - ); - - public function __construct() { - - $this->type = 'date'; - $this->icon = 'calendar'; - $this->label = l::get('fields.date.label', 'Date'); - $this->format = 'YYYY-MM-DD'; - - } - - public function format() { - $format = str::upper($this->format); - return empty($format) ? 'YYYY-MM-DD' : $format; - } - - public function validate() { - return v::date($this->result()); - } - - public function value() { - if($this->override()) { - $this->value = $this->default(); - } - return !empty($this->value) ? date('Y-m-d', strtotime($this->value)) : null; - } - - public function input() { - - $input = parent::input(); - $input->removeAttr('name'); - $input->data(array( - 'field' => 'date', - 'format' => $this->format(), - 'i18n' => html(json_encode(array( - 'previousMonth' => '‹', - 'nextMonth' => '›', - 'months' => l::get('fields.date.months'), - 'weekdays' => l::get('fields.date.weekdays'), - 'weekdaysShort' => l::get('fields.date.weekdays.short') - )), false) - )); - - $hidden = new Brick('input', null); - $hidden->type = 'hidden'; - $hidden->name = $this->name(); - $hidden->value = $this->value(); - - return $input . $hidden; - - } - -} diff --git a/panel/app/fields/datetime/datetime.php b/panel/app/fields/datetime/datetime.php deleted file mode 100644 index 476eb7c..0000000 --- a/panel/app/fields/datetime/datetime.php +++ /dev/null @@ -1,86 +0,0 @@ -date = array( - 'format' => 'YYYY-MM-DD' - ); - - $this->time = array( - 'interval' => 60, - 'format' => 24 - ); - - } - - public function validate() { - - $result = $this->result(); - - if(empty($result)) { - return !$this->required(); - } else { - return v::date($result); - } - - } - - public function result() { - - $value = array_filter($this->value()); - - if(empty($value) or !isset($value['date']) or !isset($value['time'])) { - return ''; - } - - return a::get($value, 'date') . ' ' . a::get($value, 'time') . ':00'; - - } - - public function content() { - - if(is_array($this->value())) { - $timestamp = strtotime($this->result()); - } else { - $timestamp = strtotime($this->value()); - } - - $dateDefault = a::get($this->date, 'default', ($this->required() ? 'now' : false)); - $timeDefault = a::get($this->time, 'default', ($this->required() ? 'now' : false)); - - $dateValue = $timestamp ? date('Y-m-d', $timestamp) : $dateDefault; - $timeValue = $timestamp ? date('H:i', $timestamp) : $timeDefault; - - $date = form::field('date', array( - 'name' => $this->name() . '[date]', - 'value' => $dateValue, - 'format' => a::get($this->date, 'format', 'YYYY-MM-DD'), - 'id' => 'form-field-' . $this->name() . '-date', - 'required' => $this->required(), - 'readonly' => $this->readonly(), - )); - - $time = form::field('time', array( - 'name' => $this->name() . '[time]', - 'value' => $timeValue, - 'format' => a::get($this->time, 'format', 24), - 'interval' => a::get($this->time, 'interval', 60), - 'id' => 'form-field-' . $this->name() . '-time', - 'required' => $this->required(), - 'readonly' => $this->readonly(), - )); - - $grid = '
'; - $grid .= '
' . $date->content() . '
'; - $grid .= '
' . $time->content() . '
'; - $grid .= '
'; - - return $grid; - - } - -} \ No newline at end of file diff --git a/panel/app/fields/email/email.php b/panel/app/fields/email/email.php deleted file mode 100644 index aa112ed..0000000 --- a/panel/app/fields/email/email.php +++ /dev/null @@ -1,35 +0,0 @@ -type = 'email'; - $this->icon = 'envelope'; - $this->label = l::get('fields.email.label', 'Email'); - $this->placeholder = l::get('fields.email.placeholder', 'mail@example.com'); - $this->autocomplete = true; - - } - - public function input() { - - $input = parent::input(); - - if($this->autocomplete) { - $input->attr('autocomplete', 'off'); - $input->data(array( - 'field' => 'autocomplete', - 'url' => panel()->urls()->api() . '/autocomplete/emails?_csrf=' . panel()->csrf() - )); - } - - return $input; - - } - - public function validate() { - return v::email($this->result()); - } - -} \ No newline at end of file diff --git a/panel/app/fields/filename/filename.php b/panel/app/fields/filename/filename.php deleted file mode 100644 index 92974b3..0000000 --- a/panel/app/fields/filename/filename.php +++ /dev/null @@ -1,18 +0,0 @@ -addClass('field-icon'); - $icon->append('.' . $this->extension . ''); - - return $icon; - - } - -} diff --git a/panel/app/fields/headline/assets/css/headline.css b/panel/app/fields/headline/assets/css/headline.css deleted file mode 100644 index 00c0160..0000000 --- a/panel/app/fields/headline/assets/css/headline.css +++ /dev/null @@ -1,19 +0,0 @@ -.field-with-headline { - counter-increment: count; -} -.field-with-headline:first-child { - padding-top: 0; -} -.field-with-headline { - padding-top: 6em; -} -.field-with-headline .hgroup span { - padding-left: 1.5em; -} -.field-with-headline .hgroup:before { - position: absolute; - content: counter(count, decimal-leading-zero); - left: 0; - color: #8dae28; - font-weight: 400; -} diff --git a/panel/app/fields/headline/headline.php b/panel/app/fields/headline/headline.php deleted file mode 100644 index 4b9126b..0000000 --- a/panel/app/fields/headline/headline.php +++ /dev/null @@ -1,29 +0,0 @@ - array( - 'headline.css' - ) - ); - - public function result() { - return null; - } - - public function label() { - return null; - } - - public function content() { - return '

' . html($this->i18n($this->label)) . '

'; - } - - public function element() { - $element = parent::element(); - $element->addClass('field-with-headline'); - return $element; - } - -} diff --git a/panel/app/fields/hidden/hidden.php b/panel/app/fields/hidden/hidden.php deleted file mode 100644 index 33d61d7..0000000 --- a/panel/app/fields/hidden/hidden.php +++ /dev/null @@ -1,13 +0,0 @@ - 'hidden', - 'name' => $this->name(), - 'value' => $this->value() - )); - } - -} \ No newline at end of file diff --git a/panel/app/fields/image/assets/css/image.css b/panel/app/fields/image/assets/css/image.css deleted file mode 100644 index 9f01aba..0000000 --- a/panel/app/fields/image/assets/css/image.css +++ /dev/null @@ -1,19 +0,0 @@ -.field-with-image select { - margin-left: 3rem; -} -.field-with-image .input-preview { - position: absolute; - top: 2px; - left: 2px; - bottom: 2px; - width: 2.75em; - background: url(../images/pattern.png); -} -.field-with-image .input-preview figure { - display: block; - width: 100%; - height: 100%; - background-repeat: no-repeat; - background-position: center center; - background-size: cover; -} \ No newline at end of file diff --git a/panel/app/fields/image/assets/js/image.js b/panel/app/fields/image/assets/js/image.js deleted file mode 100644 index 8bf882b..0000000 --- a/panel/app/fields/image/assets/js/image.js +++ /dev/null @@ -1,55 +0,0 @@ -(function($) { - - $.fn.imagefield = function() { - - return this.each(function() { - - var field = $(this); - - // avoid multiple init - if(field.data('imagefield')) return true; - field.data('imagefield', true); - - var select = field.find('select'); - var preview = field.find('.input-preview figure'); - var link = preview.parent('a'); - - select.on('keydown change', function() { - - var option = select.find('option:selected'); - var url = option.data('url'); - var thumb = option.data('thumb'); - - if(option.val() === '') { - url = '#'; - } - - if(thumb) { - preview.attr('style', 'background-image: url(' + thumb + ')'); - } else { - preview.attr('style', 'background-image: none'); - } - - link.attr('href', url); - - }).trigger('change'); - - field.find('.input-preview').on('click', function() { - if($(this).attr('href') == '#') { - return false; - } - }); - - field.find('.input').droppable({ - hoverClass: 'over', - accept: $('.sidebar .draggable-file'), - drop: function(e, ui) { - $(this).find('select').val(ui.draggable.data('helper')).trigger('change'); - } - }); - - }); - - }; - -})(jQuery); \ No newline at end of file diff --git a/panel/app/fields/image/image.php b/panel/app/fields/image/image.php deleted file mode 100644 index 400aeb7..0000000 --- a/panel/app/fields/image/image.php +++ /dev/null @@ -1,94 +0,0 @@ -icon = 'image'; - } - - public function element() { - $element = parent::element(); - $element->addClass('field-with-image'); - $element->data('field', 'imagefield'); - return $element; - } - - public function image() { - return $this->page->image($this->value()); - } - - public function preview() { - - $figure = new Brick('figure'); - - if($image = $this->image()) { - $figure->attr('style', 'background-image: url(' . $image->crop(75)->url() . ')'); - $url = $image->url('edit'); - } else { - $figure->attr('style', 'background-image: url(' . $this->value() . ')'); - $url = ''; - } - - return '
' . $figure . ''; - - } - - public function input() { - return $this->preview() . parent::input(); - } - - public function option($filename, $image, $selected = false) { - - if($image == '') { - return new Brick('option', '', array( - 'value' => '', - 'selected' => $selected - )); - } else { - return new Brick('option', $image->filename(), array( - 'value' => $filename, - 'selected' => $selected, - 'data-url' => $image->url('edit'), - 'data-thumb' => $image->crop(75)->url() - )); - } - - } - - public function options() { - - $options = []; - - foreach($this->images() as $image) { - $options[$image->filename()] = $image; - } - - return $options; - - } - - public function images() { - - $images = $this->page->images(); - - if(!empty($this->extension)) { - - if(!is_array($this->extension)) { - $extensions = [$this->extension]; - } else { - $extensions = $this->extension; - } - - $images = $images->filter(function($image) use($extensions) { - return in_array(strtolower($image->extension()), $extensions); - }); - - } - - return $images; - - } - -} diff --git a/panel/app/fields/info/info.php b/panel/app/fields/info/info.php deleted file mode 100644 index 3f13ff3..0000000 --- a/panel/app/fields/info/info.php +++ /dev/null @@ -1,21 +0,0 @@ -addClass('field-with-icon'); - return $element; - } - - public function input() { - return '
' . kirbytext($this->i18n($this->text())) . '
'; - } - -} \ No newline at end of file diff --git a/panel/app/fields/input/input.php b/panel/app/fields/input/input.php deleted file mode 100644 index 73a8ce2..0000000 --- a/panel/app/fields/input/input.php +++ /dev/null @@ -1,37 +0,0 @@ -addClass('input'); - $input->attr(array( - 'type' => $this->type(), - 'value' => '', - 'required' => $this->required(), - 'name' => $this->name(), - 'autocomplete' => $this->autocomplete() === false ? 'off' : 'on', - 'autofocus' => $this->autofocus(), - 'placeholder' => $this->i18n($this->placeholder()), - 'readonly' => $this->readonly(), - 'disabled' => $this->disabled(), - 'id' => $this->id() - )); - - if(!is_array($this->value())) { - $input->val(html($this->value(), false)); - } - - if($this->readonly()) { - $input->attr('tabindex', '-1'); - $input->addClass('input-is-readonly'); - } - - return $input; - - } - -} \ No newline at end of file diff --git a/panel/app/fields/inputlist/inputlist.php b/panel/app/fields/inputlist/inputlist.php deleted file mode 100644 index 9ca8dc9..0000000 --- a/panel/app/fields/inputlist/inputlist.php +++ /dev/null @@ -1,83 +0,0 @@ -removeClass('input'); - return $input; - } - - public function options() { - return fieldoptions::build($this); - } - - public function item($value, $text) { - - $input = $this->input($value); - - $label = new Brick('label', $this->i18n($text)); - $label->addClass('input'); - $label->attr('data-focus', 'true'); - $label->prepend($input); - - if($this->readonly) { - $label->addClass('input-is-readonly'); - } - - return $label; - - } - - public function content() { - - $html = '
    '; - - switch($this->columns()) { - case 2: - $width = ' field-grid-item-1-2'; - break; - case 3: - $width = ' field-grid-item-1-3'; - break; - case 4: - $width = ' field-grid-item-1-4'; - break; - case 5: - $width = ' field-grid-item-1-5'; - break; - default: - $width = ''; - break; - } - - foreach($this->options() as $key => $value) { - $html .= '
  • '; - $html .= $this->item($key, $value); - $html .= '
  • '; - } - - $html .= '
'; - - $content = new Brick('div'); - $content->addClass('field-content'); - $content->append($html); - - return $content; - - } - - public function validate() { - if(is_array($this->value())) { - foreach($this->value() as $v) { - if(!array_key_exists($v, $this->options())) return false; - } - return true; - } else { - return array_key_exists($this->value(), $this->options()); - } - } - -} diff --git a/panel/app/fields/line/line.php b/panel/app/fields/line/line.php deleted file mode 100644 index b789b47..0000000 --- a/panel/app/fields/line/line.php +++ /dev/null @@ -1,19 +0,0 @@ -'; - } - - public function element() { - $element = parent::element(); - $element->addClass('field-with-line'); - return $element; - } - -} \ No newline at end of file diff --git a/panel/app/fields/number/number.php b/panel/app/fields/number/number.php deleted file mode 100644 index 2e8c838..0000000 --- a/panel/app/fields/number/number.php +++ /dev/null @@ -1,39 +0,0 @@ -type = 'number'; - $this->label = l::get('fields.number.label', 'Number'); - $this->placeholder = l::get('fields.number.placeholder', '#'); - $this->step = 1; - $this->min = false; - $this->max = false; - - } - - public function input() { - $input = parent::input(); - $input->attr('step', $this->step); - $input->attr('min', $this->min); - $input->attr('max', $this->max); - return $input; - } - - public function validate() { - - if(!v::num($this->result())) return false; - - if($this->validate and is_array($this->validate)) { - return parent::validate(); - } else { - if(is_numeric($this->min) and !v::min($this->result(), $this->min)) return false; - if(is_numeric($this->max) and !v::max($this->result(), $this->max)) return false; - } - - return true; - - } - -} diff --git a/panel/app/fields/page/page.php b/panel/app/fields/page/page.php deleted file mode 100644 index 00435bf..0000000 --- a/panel/app/fields/page/page.php +++ /dev/null @@ -1,25 +0,0 @@ -icon = 'chain'; - $this->label = l::get('fields.page.label', 'Page'); - $this->placeholder = l::get('fields.page.placeholder', 'path/to/page'); - - } - - public function input() { - - $input = parent::input(); - $input->data(array( - 'field' => 'autocomplete', - 'url' => panel()->urls()->api() . '/autocomplete/uris' - )); - - return $input; - - } - -} \ No newline at end of file diff --git a/panel/app/fields/password/password.php b/panel/app/fields/password/password.php deleted file mode 100644 index 9ed257a..0000000 --- a/panel/app/fields/password/password.php +++ /dev/null @@ -1,40 +0,0 @@ -type = 'password'; - $this->icon = 'key'; - $this->label = l('fields.password.label', 'Password'); - - } - - public function input() { - - $input = parent::input(); - - if($this->suggestion) { - $input->data(array( - 'field' => 'passwordSuggestion' - )); - } - - return $input; - - } - - public function help() { - if($this->suggestion and !$this->readonly) { - $this->help = $this->suggestion(); - } - return parent::help(); - } - - public function suggestion() { - return ''; - } - -} \ No newline at end of file diff --git a/panel/app/fields/radio/radio.php b/panel/app/fields/radio/radio.php deleted file mode 100644 index 39c4d0c..0000000 --- a/panel/app/fields/radio/radio.php +++ /dev/null @@ -1,41 +0,0 @@ -options(); - if(is_array($options)) { - reset($options); - $value = key($options); - } - } - return $value; - } - - public function input() { - - $val = func_get_arg(0); - $input = parent::input(); - $input->addClass('radio'); - $input->attr('type', 'radio'); - $input->val($val); - - if($this->readonly) { - $input->attr('disabled', true); - } - - $input->attr('checked', $val == $this->value()); - return $input; - - } - - public function item($value, $text) { - $item = parent::item($value, $text); - $item->addClass('input-with-radio'); - return $item; - } - -} diff --git a/panel/app/fields/select/select.php b/panel/app/fields/select/select.php deleted file mode 100644 index b1403b4..0000000 --- a/panel/app/fields/select/select.php +++ /dev/null @@ -1,74 +0,0 @@ -type = 'select'; - $this->options = array(); - $this->icon = 'chevron-down'; - - } - - public function options() { - return FieldOptions::build($this); - } - - public function option($value, $text, $selected = false) { - return new Brick('option', $this->i18n($text), array( - 'value' => $value, - 'selected' => $selected - )); - } - - public function input() { - - $select = new Brick('select'); - $select->addClass('selectbox'); - $select->attr(array( - 'name' => $this->name(), - 'id' => $this->id(), - 'required' => $this->required(), - 'autocomplete' => $this->autocomplete(), - 'autofocus' => $this->autofocus(), - 'readonly' => $this->readonly(), - 'disabled' => $this->disabled(), - )); - - $default = $this->default(); - - if(!$this->required()) { - $select->append($this->option('', '', $this->value() == '')); - } - - if($this->readonly()) { - $select->attr('tabindex', '-1'); - } - - foreach($this->options() as $value => $text) { - $select->append($this->option($value, $text, $this->value() == $value)); - } - - $inner = new Brick('div'); - $inner->addClass('selectbox-wrapper'); - $inner->append($select); - - $wrapper = new Brick('div'); - $wrapper->addClass('input input-with-selectbox'); - $wrapper->append($inner); - - if($this->readonly()) { - $wrapper->addClass('input-is-readonly'); - } else { - $wrapper->attr('data-focus', 'true'); - } - - return $wrapper; - - } - - public function validate() { - return array_key_exists($this->value(), $this->options()); - } - -} diff --git a/panel/app/fields/structure/assets/css/structure.css b/panel/app/fields/structure/assets/css/structure.css deleted file mode 100644 index ab59695..0000000 --- a/panel/app/fields/structure/assets/css/structure.css +++ /dev/null @@ -1,97 +0,0 @@ -.structure { - padding-bottom: .5em; -} -.structure-entry { - background: #fff; - border: 2px solid #ddd; - margin-bottom: .5em; -} -.structure-readonly .structure-entry { - background: #efefef; - color: #777; -} -.structure-entry:last-child { - margin-bottom: 0; -} -.structure-entry-content { - padding: 1em 1.5em; - border-bottom: 1px solid #efefef; -} -.structure[data-sortable=true] .structure-entry-content { - cursor: move; -} -.structure-entry-options .btn { - padding: .75em 1.5em; - width: 50%; - float: left; - border-right: 1px solid #efefef; -} -.structure-empty { - padding: 1.5em; - background: #ddd; -} -.fileview-sidebar .structure-empty { - background: none; - border-radius: 5px; - border: 1px dashed #ddd; - padding: 1rem 1.5rem 1.25rem; -} -.structure-empty a { - border-bottom: 2px solid #aaa; - margin-left: .5em; -} -.fileview-sidebar .structure-empty a { - display: inline-block; - margin-left: 0; -} -.structure-empty a:hover { - border-color: #000; -} -.structure-add-button { - cursor: pointer; -} - - -/* Table */ -.structure-table { - width: 100%; - border-spacing: 0; - border: 2px solid #ddd; - border-bottom: 1px solid #ddd; - border-right: 1px solid #ddd; - table-layout: fixed; -} -.structure-table td, .structure-table th { - background: #fff; - border-bottom: 1px solid #ddd; - border-right: 1px solid #ddd; - text-align: left; - vertical-align: top; -} -.structure-table th { - padding: .5em; - font-weight: 400; - color: #777; - font-style: italic; -} -.structure-table td a { - display: block; - padding: .5em; - overflow: hidden; - width: 100%; - text-overflow: ellipsis; - cursor: move; -} -.structure-table-options { - width: 3rem; - text-align: center; -} -.structure-table .structure-table-options a { - text-align: center; - cursor: pointer; -} - -.structure-sortable-helper { - border-top: 1px solid #ddd; - border-left: 1px solid #ddd; -} diff --git a/panel/app/fields/structure/assets/js/structure.js b/panel/app/fields/structure/assets/js/structure.js deleted file mode 100644 index dd6559e..0000000 --- a/panel/app/fields/structure/assets/js/structure.js +++ /dev/null @@ -1,53 +0,0 @@ -(function($) { - - var Structure = function(el) { - - var element = $(el); - var style = element.data('style'); - var api = element.data('api'); - var sortable = element.data('sortable'); - var entries = style == 'table' ? element.find('.structure-table tbody') : element.find('.structure-entries'); - - if(sortable === false) return false; - - entries.sortable({ - helper: function(e, ui) { - ui.children().each(function() { - $(this).width($(this).width()); - }); - return ui.addClass('structure-sortable-helper'); - }, - update: function() { - - var ids = []; - - $.each($(this).sortable('toArray'), function(i, id) { - ids.push(id.replace('structure-entry-', '')); - }); - - $.post(api, {ids: ids}, function() { - app.content.reload(); - }); - - } - }); - - }; - - $.fn.structure = function() { - - return this.each(function() { - - if($(this).data('structure')) { - return $(this); - } else { - var structure = new Structure(this); - $(this).data('structure', structure); - return $(this); - } - - }); - - }; - -})(jQuery); \ No newline at end of file diff --git a/panel/app/fields/structure/controller.php b/panel/app/fields/structure/controller.php deleted file mode 100644 index c38ab73..0000000 --- a/panel/app/fields/structure/controller.php +++ /dev/null @@ -1,93 +0,0 @@ -model(); - $structure = $this->structure($model); - $modalsize = $this->field()->modalsize(); - $form = $this->form('add', array($model, $structure), function($form) use($model, $structure, $self) { - - $form->validate(); - - if(!$form->isValid()) { - return false; - } - - $structure->add($form->serialize()); - $self->redirect($model); - - }); - - return $this->modal('add', compact('form', 'modalsize')); - - } - - public function update($entryId) { - - $self = $this; - $model = $this->model(); - $structure = $this->structure($model); - $entry = $structure->find($entryId); - - if(!$entry) { - return $this->modal('error', array( - 'text' => l('fields.structure.entry.error') - )); - } - - $modalsize = $this->field()->modalsize(); - $form = $this->form('update', array($model, $structure, $entry), function($form) use($model, $structure, $self, $entryId) { - - // run the form validator - $form->validate(); - - if(!$form->isValid()) { - return false; - } - - $structure->update($entryId, $form->serialize()); - $self->redirect($model); - - }); - - return $this->modal('update', compact('form', 'modalsize')); - - } - - public function delete($entryId) { - - $self = $this; - $model = $this->model(); - $structure = $this->structure($model); - $entry = $structure->find($entryId); - - if(!$entry) { - return $this->modal('error', array( - 'text' => l('fields.structure.entry.error') - )); - } - - $form = $this->form('delete', $model, function() use($self, $model, $structure, $entryId) { - $structure->delete($entryId); - $self->redirect($model); - }); - - return $this->modal('delete', compact('form')); - - } - - public function sort() { - $model = $this->model(); - $structure = $this->structure($model); - $structure->sort(get('ids')); - $this->redirect($model); - } - - protected function structure($model) { - return $model->structure()->forField($this->fieldname()); - } - -} \ No newline at end of file diff --git a/panel/app/fields/structure/forms/add.php b/panel/app/fields/structure/forms/add.php deleted file mode 100644 index 0e1b7b4..0000000 --- a/panel/app/fields/structure/forms/add.php +++ /dev/null @@ -1,11 +0,0 @@ -fields(), array(), $structure->field()); - $form->cancel($model); - $form->buttons->submit->value = l('add'); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/fields/structure/forms/delete.php b/panel/app/fields/structure/forms/delete.php deleted file mode 100644 index 6edc57e..0000000 --- a/panel/app/fields/structure/forms/delete.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - 'label' => 'fields.structure.delete.label', - 'type' => 'info', - ) - )); - - $form->style('delete'); - $form->cancel($model); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/fields/structure/forms/update.php b/panel/app/fields/structure/forms/update.php deleted file mode 100644 index cef432a..0000000 --- a/panel/app/fields/structure/forms/update.php +++ /dev/null @@ -1,12 +0,0 @@ -fields(), $entry->toArray(), $structure->field()); - - $form->cancel($model); - $form->buttons->submit->value = l('ok'); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/fields/structure/structure.php b/panel/app/fields/structure/structure.php deleted file mode 100644 index 659d99e..0000000 --- a/panel/app/fields/structure/structure.php +++ /dev/null @@ -1,162 +0,0 @@ - array( - 'structure.js' - ), - 'css' => array( - 'structure.css' - ) - ); - - public $fields = array(); - public $entry = null; - public $structure = null; - public $style = 'items'; - public $modalsize = 'medium'; - - public function routes() { - - return array( - array( - 'pattern' => 'add', - 'method' => 'get|post', - 'action' => 'add' - ), - array( - 'pattern' => 'sort', - 'method' => 'post', - 'action' => 'sort', - ), - array( - 'pattern' => '(:any)/update', - 'method' => 'get|post', - 'action' => 'update' - ), - array( - 'pattern' => '(:any)/delete', - 'method' => 'get|post', - 'action' => 'delete', - ) - ); - } - - public function modalsize() { - $sizes = array('small', 'medium', 'large'); - return in_array($this->modalsize, $sizes) ? $this->modalsize : 'medium'; - } - - public function style() { - $styles = array('table', 'items'); - return in_array($this->style, $styles) ? $this->style : 'items'; - } - - public function structure() { - if(!is_null($this->structure)) { - return $this->structure; - } else { - return $this->structure = $this->model->structure()->forField($this->name); - } - } - - public function fields() { - - $output = array(); - - foreach($this->structure->fields() as $k => $v) { - $v['name'] = $k; - $v['value'] = '{{' . $k . '}}'; - $output[] = $v; - } - - return $output; - - } - - public function entries() { - return $this->structure()->data(); - } - - public function result() { - /** - * Users store their data as plain yaml. - * So we need this hacky solution to give data - * as an array to the form serializer in case - * of users, in order to not mess up their data - */ - if(is_a($this->model, 'Kirby\\Panel\\Models\\User')) { - return $this->structure()->toArray(); - } else { - return $this->structure()->toYaml(); - } - } - - public function entry($data) { - - if(is_null($this->entry) or !is_string($this->entry)) { - $html = array(); - foreach($this->fields as $name => $field) { - if(isset($data->$name)) { - $html[] = $data->$name; - } - } - return implode('
', $html); - } else { - - $text = $this->entry; - - foreach((array)$data as $key => $value) { - if(is_array($value)) { - $value = implode(', ', array_values($value)); - } - $text = str_replace('{{' . $key . '}}', $value, $text); - } - - return $text; - - } - - } - - public function label() { - return null; - } - - public function headline() { - - if(!$this->readonly) { - - $add = new Brick('a'); - $add->html('' . l('fields.structure.add')); - $add->addClass('structure-add-button label-option'); - $add->data('modal', true); - $add->attr('href', purl($this->model, 'field/' . $this->name . '/structure/add')); - - } else { - $add = null; - } - - // make sure there's at least an empty label - if(!$this->label) { - $this->label = ' '; - } - - $label = parent::label(); - $label->addClass('structure-label'); - $label->append($add); - - return $label; - - } - - public function content() { - return tpl::load(__DIR__ . DS . 'template.php', array('field' => $this)); - } - - public function url($action) { - return purl($this->model(), 'field/' . $this->name() . '/structure/' . $action); - } - -} \ No newline at end of file diff --git a/panel/app/fields/structure/styles/items.php b/panel/app/fields/structure/styles/items.php deleted file mode 100644 index 16bb511..0000000 --- a/panel/app/fields/structure/styles/items.php +++ /dev/null @@ -1,18 +0,0 @@ -entries() as $entry): ?> -
-
- entry($entry) ?> -
- readonly()): ?> - - -
- \ No newline at end of file diff --git a/panel/app/fields/structure/styles/table.php b/panel/app/fields/structure/styles/table.php deleted file mode 100644 index 1d0aaa9..0000000 --- a/panel/app/fields/structure/styles/table.php +++ /dev/null @@ -1,36 +0,0 @@ - - - - fields() as $f): ?> - - - - - - - entries() as $entry): ?> - - fields() as $f): ?> - - - - - - -
- i18n($f['label']), false) ?> - -   -
- - {$f['name']})): ?> - {$f['name']}, false) ?> - -   - - - - - - -
\ No newline at end of file diff --git a/panel/app/fields/structure/template.php b/panel/app/fields/structure/template.php deleted file mode 100644 index 233c947..0000000 --- a/panel/app/fields/structure/template.php +++ /dev/null @@ -1,20 +0,0 @@ -
- - headline() ?> - -
- - entries()->count()): ?> -
- -
- - style() . '.php') ?> - -
- -
\ No newline at end of file diff --git a/panel/app/fields/structure/views/add.php b/panel/app/fields/structure/views/add.php deleted file mode 100644 index 28805da..0000000 --- a/panel/app/fields/structure/views/add.php +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/fields/structure/views/delete.php b/panel/app/fields/structure/views/delete.php deleted file mode 100644 index fd34175..0000000 --- a/panel/app/fields/structure/views/delete.php +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/fields/structure/views/update.php b/panel/app/fields/structure/views/update.php deleted file mode 100644 index 28805da..0000000 --- a/panel/app/fields/structure/views/update.php +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/fields/tags/tags.php b/panel/app/fields/tags/tags.php deleted file mode 100644 index d59cda9..0000000 --- a/panel/app/fields/tags/tags.php +++ /dev/null @@ -1,52 +0,0 @@ -icon = 'tag'; - $this->label = l::get('fields.tags.label', 'Tags'); - $this->index = 'siblings'; - $this->separator = ','; - $this->lower = false; - - } - - public function input() { - - $input = parent::input(); - $input->addClass('input-with-tags'); - $input->data(array( - 'field' => 'tags', - 'lowercase' => $this->lower ? 'true' : false, - 'separator' => $this->separator, - )); - - if(isset($this->data)) { - - $input->data('url', html(json_encode($this->data), false)); - - } else if($page = $this->page()) { - - $field = empty($this->field) ? $this->name() : $this->field; - $model = is_a($this->model, 'File') ? 'file' : 'page'; - - $query = array( - 'uri' => $page->id(), - 'index' => $this->index(), - 'field' => $field, - 'yaml' => $this->parentField, - 'model' => $model, - 'separator' => $this->separator(), - '_csrf' => panel()->csrf(), - ); - - $input->data('url', panel()->urls()->api() . '/autocomplete/field?' . http_build_query($query)); - - } - - return $input; - - } - -} diff --git a/panel/app/fields/tel/tel.php b/panel/app/fields/tel/tel.php deleted file mode 100644 index 61814a2..0000000 --- a/panel/app/fields/tel/tel.php +++ /dev/null @@ -1,11 +0,0 @@ -type = 'tel'; - $this->icon = 'phone'; - $this->label = l::get('fields.tel.label', 'Phone'); - } - -} \ No newline at end of file diff --git a/panel/app/fields/text/assets/css/counter.css b/panel/app/fields/text/assets/css/counter.css deleted file mode 100644 index c4b0990..0000000 --- a/panel/app/fields/text/assets/css/counter.css +++ /dev/null @@ -1,12 +0,0 @@ -.field-counter { - position: absolute; - z-index: -1; - right: 0; - top: 0; - text-align: right; - font-size: .9em; - line-height: 1.66666666666667; -} -.field-counter.outside-range { - color: #b3000a; -} \ No newline at end of file diff --git a/panel/app/fields/text/assets/js/counter.js b/panel/app/fields/text/assets/js/counter.js deleted file mode 100644 index 2ef5458..0000000 --- a/panel/app/fields/text/assets/js/counter.js +++ /dev/null @@ -1,34 +0,0 @@ -(function($) { - - $.fn.counter = function() { - - return this.each(function() { - - var counter = $(this); - - if(counter.data('counter')) { - return counter; - } - - var field = counter.parent('.field').find('.input'); - var length = $.trim(field.val()).length; - var max = field.data('max'); - var min = field.data('min'); - - field.keyup(function() { - length = $.trim(field.val()).length; - counter.text(length + (max ? '/' + max : '')); - if((max && length > max) || (min && length < min)) { - counter.addClass('outside-range'); - } else { - counter.removeClass('outside-range'); - } - }).trigger('keyup'); - - counter.data('counter', true); - - }); - - }; - -}(jQuery)); \ No newline at end of file diff --git a/panel/app/fields/text/text.php b/panel/app/fields/text/text.php deleted file mode 100644 index 8150a7f..0000000 --- a/panel/app/fields/text/text.php +++ /dev/null @@ -1,76 +0,0 @@ - 0, - 'max' => null - ); - - static public $assets = array( - 'js' => array( - 'counter.js' - ) - ); - - public function min() { - return isset($this->validate['min']) ? $this->validate['min'] : false; - } - - public function max() { - return isset($this->validate['max']) ? $this->validate['max'] : false; - } - - public function input() { - - $input = parent::input(); - - if(!$this->readonly() && ($this->min() || $this->max())) { - $input->data('max', $this->max())->data('min', $this->min()); - } - - return $input; - - } - - public function outsideRange($length) { - - if($this->min() && $length < $this->min()) return true; - if($this->max() && $length > $this->max()) return true; - - return false; - - } - - public function counter() { - - if(!$this->min() && !$this->max() || $this->readonly()) return null; - - $counter = new Brick('div'); - $counter->addClass('field-counter marginalia text'); - - $length = str::length($this->value()); - - if($this->outsideRange($length)) { - $counter->addClass('outside-range'); - } - - $counter->data('field', 'counter'); - $counter->html($length . ($this->max() ? '/' . $this->max() : '')); - - return $counter; - - } - - public function template() { - - return $this->element() - ->append($this->label()) - ->append($this->content()) - ->append($this->counter()) - ->append($this->help()); - - } - -} diff --git a/panel/app/fields/textarea/assets/js/editor.js b/panel/app/fields/textarea/assets/js/editor.js deleted file mode 100644 index 9f95dc1..0000000 --- a/panel/app/fields/textarea/assets/js/editor.js +++ /dev/null @@ -1,64 +0,0 @@ -(function($) { - - $.fn.editor = function() { - - return this.each(function() { - - if($(this).data('editor')) { - return $(this); - } - - var textarea = $(this); - var buttons = textarea.parent().find('.field-buttons'); - - // start autosizing - textarea.autosize(); - - buttons.find('.btn').on('click.editorButton', function(e) { - - textarea.focus(); - var button = $(this); - - if(button.data('action')) { - app.modal.open(button.data('action'), window.location.href); - } else { - - var sel = textarea.getSelection(); - var tpl = button.data('tpl'); - var text = button.data('text'); - - if(sel.length > 0) text = sel; - - var tag = tpl.replace('{text}', text); - - textarea.insertAtCursor(tag); - textarea.trigger('autosize.resize'); - - } - - return false; - - }); - - buttons.find('[data-editor-shortcut]').each(function(i, el) { - var key = $(this).data('editor-shortcut'); - var action = function(e) { - $(el).trigger('click'); - return false; - }; - - textarea.bind('keydown', key, action); - - if(key.match(/meta\+/)) { - textarea.bind('keydown', key.replace('meta+', 'ctrl+'), action); - } - - }); - - textarea.data('editor', true); - - }); - - }; - -})(jQuery); \ No newline at end of file diff --git a/panel/app/fields/textarea/buttons.php b/panel/app/fields/textarea/buttons.php deleted file mode 100644 index c6750d8..0000000 --- a/panel/app/fields/textarea/buttons.php +++ /dev/null @@ -1,90 +0,0 @@ -textarea = $textarea; - - if(!is_array($buttons)) { - $this->buttons = array_keys(static::$setup); - } else { - $this->buttons = $buttons; - } - - } - - public function __toString() { - - $html = ''; - - return $html; - - } - -} - -buttons::$setup = array( - 'bold' => array( - 'label' => l::get('fields.textarea.buttons.bold.label'), - 'text' => l::get('fields.textarea.buttons.bold.text'), - 'shortcut' => 'meta+b', - 'template' => '**{text}**', - 'icon' => 'bold' - ), - 'italic' => array( - 'label' => l::get('fields.textarea.buttons.italic.label'), - 'text' => l::get('fields.textarea.buttons.italic.text'), - 'shortcut' => 'meta+i', - 'template' => '*{text}*', - 'icon' => 'italic' - ), - 'link' => array( - 'label' => l::get('fields.textarea.buttons.link.label'), - 'shortcut' => 'meta+shift+l', - 'action' => 'link', - 'icon' => 'chain' - ), - 'email' => array( - 'label' => l::get('fields.textarea.buttons.email.label'), - 'shortcut' => 'meta+shift+e', - 'action' => 'email', - 'icon' => 'envelope' - ), -); \ No newline at end of file diff --git a/panel/app/fields/textarea/controller.php b/panel/app/fields/textarea/controller.php deleted file mode 100644 index 2d3d21b..0000000 --- a/panel/app/fields/textarea/controller.php +++ /dev/null @@ -1,23 +0,0 @@ -model(); - $form = $this->form('link', array($page, $this->fieldname())); - - return $this->modal('link', compact('form')); - - } - - public function email($textarea = null) { - - $page = $this->model(); - $form = $this->form('email', array($page, $this->fieldname())); - - return $this->modal('email', compact('form')); - - } - -} \ No newline at end of file diff --git a/panel/app/fields/textarea/forms/email.php b/panel/app/fields/textarea/forms/email.php deleted file mode 100644 index f1e3f3c..0000000 --- a/panel/app/fields/textarea/forms/email.php +++ /dev/null @@ -1,27 +0,0 @@ - array( - 'label' => 'editor.email.address.label', - 'type' => 'email', - 'placeholder' => 'editor.email.address.placeholder', - 'autofocus' => 'true', - 'required' => 'true', - ), - 'text' => array( - 'label' => 'editor.email.text.label', - 'type' => 'text', - 'help' => 'editor.email.text.help', - 'icon' => 'font' - ) - )); - - $form->data('textarea', 'form-field-' . $textarea); - $form->style('editor'); - $form->cancel($page); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/fields/textarea/forms/link.php b/panel/app/fields/textarea/forms/link.php deleted file mode 100644 index 27feca6..0000000 --- a/panel/app/fields/textarea/forms/link.php +++ /dev/null @@ -1,28 +0,0 @@ - array( - 'label' => 'editor.link.url.label', - 'type' => 'text', - 'placeholder' => 'http://', - 'autofocus' => 'true', - 'required' => 'true', - 'icon' => 'chain' - ), - 'text' => array( - 'label' => 'editor.link.text.label', - 'type' => 'text', - 'help' => 'editor.link.text.help', - 'icon' => 'font' - ), - )); - - $form->data('textarea', 'form-field-' . $textarea); - $form->style('editor'); - $form->cancel($page); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/fields/textarea/textarea.php b/panel/app/fields/textarea/textarea.php deleted file mode 100644 index c751b8d..0000000 --- a/panel/app/fields/textarea/textarea.php +++ /dev/null @@ -1,94 +0,0 @@ - array( - 'editor.js' - ) - ); - - public function __construct() { - $this->label = l::get('fields.textarea.label', 'Text'); - $this->buttons = true; - $this->min = 0; - $this->max = false; - } - - public function routes() { - return array( - array( - 'pattern' => 'link', - 'action' => 'link', - 'method' => 'get|post' - ), - array( - 'pattern' => 'email', - 'action' => 'email', - 'method' => 'get|post' - ), - ); - } - - public function input() { - - $input = parent::input(); - $input->tag('textarea'); - $input->removeAttr('type'); - $input->removeAttr('value'); - $input->html($this->value() ? htmlentities($this->value(), ENT_NOQUOTES, 'UTF-8') : false); - $input->data('field', 'editor'); - - return $input; - - } - - public function result() { - // Convert all line-endings to UNIX format - return str_replace(array("\r\n", "\r"), "\n", parent::result()); - } - - public function element() { - - $element = parent::element(); - $element->addClass('field-with-textarea'); - - if($this->buttons and !$this->readonly) { - $element->addClass('field-with-buttons'); - } - - return $element; - - } - - public function content() { - - $content = parent::content(); - - if($this->buttons and !$this->readonly) { - $content->append($this->buttons()); - } - - return $content; - - } - - public function buttons() { - require_once(__DIR__ . DS . 'buttons.php'); - return new Buttons($this, $this->buttons); - } - - public function validate() { - - if($this->validate and is_array($this->validate)) { - return parent::validate(); - } else { - if($this->min and !v::min($this->result(), $this->min)) return false; - if($this->max and !v::max($this->result(), $this->max)) return false; - } - - return true; - - } - -} diff --git a/panel/app/fields/textarea/views/email.php b/panel/app/fields/textarea/views/email.php deleted file mode 100644 index df5b0a1..0000000 --- a/panel/app/fields/textarea/views/email.php +++ /dev/null @@ -1,47 +0,0 @@ - - - \ No newline at end of file diff --git a/panel/app/fields/textarea/views/link.php b/panel/app/fields/textarea/views/link.php deleted file mode 100644 index a61317b..0000000 --- a/panel/app/fields/textarea/views/link.php +++ /dev/null @@ -1,53 +0,0 @@ - - - \ No newline at end of file diff --git a/panel/app/fields/time/time.php b/panel/app/fields/time/time.php deleted file mode 100644 index 84de37f..0000000 --- a/panel/app/fields/time/time.php +++ /dev/null @@ -1,69 +0,0 @@ -icon = 'clock-o'; - $this->interval = 60; - $this->format = 24; - } - - public function interval() { - if($this->interval <= 0) { - $this->interval = 60; - } - return $this->interval; - } - - public function value() { - - if($this->override()) { - $value = $this->default(); - } else { - $value = parent::value(); - } - - if(!empty($value)) { - - if($value == 'now') { - $value = date($this->format(), time()); - } - - $time = round((strtotime($value) - strtotime('00:00')) / ($this->interval() * 60)) * ($this->interval() * 60) + strtotime('00:00'); - $value = date($this->format(), $time); - - } - - return $value; - - } - - public function format() { - return $this->format == 12 ? 'h:i A' : 'H:i'; - } - - public function options() { - - $time = strtotime('00:00'); - $end = strtotime('23:59'); - $options = array(); - $format = $this->format(); - - while($time < $end) { - - $now = date($format, $time); - $time += 60 * $this->interval(); - - $options[$now] = $now; - - } - - return $options; - - } - -} diff --git a/panel/app/fields/title/title.php b/panel/app/fields/title/title.php deleted file mode 100644 index 236da5b..0000000 --- a/panel/app/fields/title/title.php +++ /dev/null @@ -1,40 +0,0 @@ -label = l::get('fields.title.label', 'Title'); - $this->icon = 'font'; - $this->required = true; - - } - - public function help() { - - if($this->page and !$this->page->isSite()) { - - if(!empty($this->help)) { - $this->help = $this->i18n($this->help); - $this->help .= '
'; - } - - // build a readable version of the page slug - $slug = ltrim($this->page->parent()->slug() . '/', '/') . $this->page->slug(); - - // TODO: move this to the css file - $style = 'padding-left: .5rem; color: #777; border:none'; - - if($this->page->canChangeUrl()) { - $this->help .= '→' . $slug . ''; - } else { - $this->help .= '→' . $slug . ''; - } - - } - - return parent::help(); - - } - -} diff --git a/panel/app/fields/toggle/toggle.php b/panel/app/fields/toggle/toggle.php deleted file mode 100644 index 411524d..0000000 --- a/panel/app/fields/toggle/toggle.php +++ /dev/null @@ -1,38 +0,0 @@ -text())) { - case 'yes/no': - $true = l::get('fields.toggle.yes'); - $false = l::get('fields.toggle.no'); - break; - case 'on/off': - $true = l::get('fields.toggle.on'); - $false = l::get('fields.toggle.off'); - break; - } - - return array( - 'true' => $true, - 'false' => $false - ); - - } - - public function value() { - $value = parent::value(); - - if(in_array($value, array('yes', 'true', true, 1, 'on'), true)) { - return 'true'; - } else { - return 'false'; - } - - } - -} diff --git a/panel/app/fields/url/assets/js/url.js b/panel/app/fields/url/assets/js/url.js deleted file mode 100644 index 600a684..0000000 --- a/panel/app/fields/url/assets/js/url.js +++ /dev/null @@ -1,38 +0,0 @@ -(function($) { - - $.fn.urlfield = function() { - - return this.each(function() { - - var $this = $(this); - - if($this.data('urlfield')) { - return; - } else { - $this.data('urlfield', true); - } - - var $icon = $this.next('.field-icon'); - - $icon.css({ - 'cursor': 'pointer', - 'pointer-events': 'auto' - }); - - $icon.on('click', function() { - - var url = $.trim($this.val()); - - if(url !== '' && $this.is(':valid')) { - window.open(url); - } else { - $this.focus(); - } - - }); - - }); - - }; - -})(jQuery); \ No newline at end of file diff --git a/panel/app/fields/url/url.php b/panel/app/fields/url/url.php deleted file mode 100644 index 06b07f7..0000000 --- a/panel/app/fields/url/url.php +++ /dev/null @@ -1,30 +0,0 @@ - array( - 'url.js' - ) - ); - - public function __construct() { - - $this->type = 'url'; - $this->icon = 'chain'; - $this->label = l::get('fields.url.label', 'URL'); - $this->placeholder = 'http://'; - - } - - public function validate() { - return v::url($this->value()); - } - - public function input() { - $input = parent::input(); - $input->data('field', 'urlfield'); - return $input; - } - -} \ No newline at end of file diff --git a/panel/app/fields/user/user.php b/panel/app/fields/user/user.php deleted file mode 100644 index 1a215ec..0000000 --- a/panel/app/fields/user/user.php +++ /dev/null @@ -1,22 +0,0 @@ -type = 'text'; - $this->icon = 'user'; - $this->label = l::get('fields.user.label', 'User'); - $this->options = array(); - - foreach(kirby()->site()->users() as $user) { - $this->options[$user->username()] = $user->username(); - } - - } - - public function value() { - $value = parent::value(); - return empty($value) ? site()->user()->username() : parent::value(); - } - -} diff --git a/panel/app/forms/auth/login.php b/panel/app/forms/auth/login.php deleted file mode 100644 index 04622f4..0000000 --- a/panel/app/forms/auth/login.php +++ /dev/null @@ -1,30 +0,0 @@ - array( - 'label' => 'login.username.label', - 'type' => 'text', - 'icon' => 'user', - 'required' => true, - 'autofocus' => true, - 'default' => s::get('username') - ), - 'password' => array( - 'label' => 'login.password.label', - 'type' => 'password', - 'required' => true - ) - )); - - $form->attr('autocomplete', 'off'); - $form->data('autosubmit', 'native'); - $form->style('centered'); - - $form->buttons->submit->value = l('login.button'); - - return $form; - -}; - diff --git a/panel/app/forms/avatars/delete.php b/panel/app/forms/avatars/delete.php deleted file mode 100644 index 946337f..0000000 --- a/panel/app/forms/avatars/delete.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - 'type' => 'info' - ) - )); - - $form->fields->image->text = '(image: ' . $avatar->url() . ' class: avatar avatar-full avatar-centered)'; - $form->centered = true; - $form->style('delete'); - - return $form; - -}; - - diff --git a/panel/app/forms/editor/email.php b/panel/app/forms/editor/email.php deleted file mode 100644 index 77d0ace..0000000 --- a/panel/app/forms/editor/email.php +++ /dev/null @@ -1,26 +0,0 @@ - array( - 'label' => 'editor.email.address.label', - 'type' => 'email', - 'placeholder' => 'editor.email.address.placeholder', - 'autofocus' => 'true', - 'required' => 'true', - ), - 'text' => array( - 'label' => 'editor.email.text.label', - 'type' => 'text', - 'help' => 'editor.email.text.help', - ) - )); - - $form->data('textarea', 'form-field-' . $textarea); - $form->style('editor'); - $form->cancel($page, 'show'); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/forms/editor/link.php b/panel/app/forms/editor/link.php deleted file mode 100644 index a2e5002..0000000 --- a/panel/app/forms/editor/link.php +++ /dev/null @@ -1,26 +0,0 @@ - array( - 'label' => 'editor.link.url.label', - 'type' => 'text', - 'placeholder' => 'http://', - 'autofocus' => 'true', - 'required' => 'true', - ), - 'text' => array( - 'label' => 'editor.link.text.label', - 'type' => 'text', - 'help' => 'editor.link.text.help', - ), - )); - - $form->data('textarea', 'form-field-' . $textarea); - $form->style('editor'); - $form->cancel($page, 'show'); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/forms/files/delete.php b/panel/app/forms/files/delete.php deleted file mode 100644 index e67771e..0000000 --- a/panel/app/forms/files/delete.php +++ /dev/null @@ -1,20 +0,0 @@ - array( - 'label' => 'files.delete.headline', - 'type' => 'text', - 'readonly' => true, - 'icon' => false, - 'default' => $file->filename() - ) - )); - - $form->style('delete'); - $form->cancel($file); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/forms/files/edit.php b/panel/app/forms/files/edit.php deleted file mode 100644 index 120f512..0000000 --- a/panel/app/forms/files/edit.php +++ /dev/null @@ -1,47 +0,0 @@ -type(); - $info[] = $file->niceSize(); - - if((string)$file->dimensions() != '0 x 0') { - $info[] = $file->dimensions(); - } - - // setup the default fields - $fields = array( - '_name' => array( - 'label' => 'files.show.name.label', - 'type' => 'filename', - 'extension' => $file->extension(), - 'required' => true, - 'default' => $file->name(), - ), - '_info' => array( - 'label' => 'files.show.info.label', - 'type' => 'text', - 'readonly' => true, - 'icon' => 'info', - 'default' => implode(' / ', $info), - ), - '_link' => array( - 'label' => 'files.show.link.label', - 'type' => 'text', - 'readonly' => true, - 'icon' => 'chain', - 'default' => $file->url() - ) - ); - - $form = new Kirby\Panel\Form(array_merge($fields, $file->getFormFields()), $file->getFormData()); - - $form->centered = true; - $form->buttons->cancel = ''; - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/forms/installation/check.php b/panel/app/forms/installation/check.php deleted file mode 100644 index ca9ff52..0000000 --- a/panel/app/forms/installation/check.php +++ /dev/null @@ -1,35 +0,0 @@ - array( - 'type' => 'info' - ) - )); - - if(count($problems) > 1) { - $info = new Brick('ol'); - foreach($problems as $problem) { - $info->append('
  • ' . $problem . '
  • '); - } - } else { - $info = new Brick('p'); - foreach($problems as $problem) { - $info->append($problem); - } - } - - // add the list of problems to the info field - $form->fields->info->text = (string)$info; - - // setup the retry button - $form->buttons->submit->value = l('installation.check.retry'); - $form->buttons->submit->autofocus = true; - - $form->style('centered'); - $form->alert(l('installation.check.text')); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/forms/installation/signup.php b/panel/app/forms/installation/signup.php deleted file mode 100644 index 681931d..0000000 --- a/panel/app/forms/installation/signup.php +++ /dev/null @@ -1,58 +0,0 @@ -translations() as $translation) { - $translations[$translation->code()] = $translation->title(); - } - - $form = new Kirby\Panel\Form(array( - - 'username' => array( - 'label' => 'installation.signup.username.label', - 'type' => 'text', - 'icon' => 'user', - 'placeholder' => 'installation.signup.username.placeholder', - 'required' => true, - 'autocomplete' => false, - 'autofocus' => true, - ), - - 'password' => array( - 'label' => 'installation.signup.password.label', - 'type' => 'password', - 'required' => true, - 'autocomplete' => false, - 'suggestion' => true, - ), - - 'email' => array( - 'label' => 'installation.signup.email.label', - 'placeholder' => 'installation.signup.email.placeholder', - 'type' => 'email', - 'required' => true, - 'autocomplete' => false, - ), - - 'language' => array( - 'label' => 'installation.signup.language.label', - 'type' => 'select', - 'required' => true, - 'autocomplete' => false, - 'default' => kirby()->option('panel.language', 'en'), - 'options' => $translations - ) - - )); - - $form->attr('autocomplete', 'off'); - $form->data('autosubmit', 'native'); - $form->style('centered'); - - $form->buttons->submit->value = l('installation.signup.button'); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/forms/pages/add.php b/panel/app/forms/pages/add.php deleted file mode 100644 index 25a0490..0000000 --- a/panel/app/forms/pages/add.php +++ /dev/null @@ -1,44 +0,0 @@ -blueprint()->pages()->template() as $template) { - $options[$template->name()] = $template->title(); - } - - $form = new Kirby\Panel\Form(array( - 'title' => array( - 'label' => 'pages.add.title.label', - 'type' => 'title', - 'placeholder' => 'pages.add.title.placeholder', - 'autocomplete' => false, - 'autofocus' => true, - 'required' => true - ), - 'uid' => array( - 'label' => 'pages.add.url.label', - 'type' => 'text', - 'icon' => 'chain', - 'autocomplete' => false, - 'required' => true, - ), - 'template' => array( - 'label' => 'pages.add.template.label', - 'type' => 'select', - 'options' => $options, - 'default' => key($options), - 'required' => true, - 'readonly' => count($options) == 1 ? true : false, - 'icon' => count($options) == 1 ? $page->blueprint()->pages()->template()->first()->icon() : 'chevron-down', - ) - )); - - $form->cancel($page->isSite() ? '/' : $page); - - $form->buttons->submit->val(l('add')); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/forms/pages/delete.php b/panel/app/forms/pages/delete.php deleted file mode 100644 index f791f97..0000000 --- a/panel/app/forms/pages/delete.php +++ /dev/null @@ -1,21 +0,0 @@ - array( - 'label' => 'pages.delete.headline', - 'type' => 'text', - 'readonly' => true, - 'icon' => false, - 'default' => $page->title(), - 'help' => $page->id(), - ) - )); - - $form->style('delete'); - $form->cancel($page); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/forms/pages/edit.php b/panel/app/forms/pages/edit.php deleted file mode 100644 index e2359a9..0000000 --- a/panel/app/forms/pages/edit.php +++ /dev/null @@ -1,45 +0,0 @@ -getFormFields(), $page->getFormData()); - - // add the blueprint name as css class - $form->addClass('form-blueprint-' . $page->blueprint()->name()); - - // center the submit button - $form->centered = true; - - // set the keep api - $form->data('keep', $page->url('keep')); - - // set the autofocus on the title field - $form->fields->title->autofocus = true; - - // add the changes alert - if($page->changes()->differ()) { - - // display unsaved changes - $alert = new Brick('div'); - $alert->addClass('text'); - $alert->append('' . l('pages.show.changes.text') . ''); - - $form->buttons->prepend('changes', $alert); - $form->buttons->cancel->attr('href', $page->url('discard')); - $form->buttons->cancel->html(l('pages.show.changes.button')); - - // add wide buttons - $form->buttons->cancel->addClass('btn-wide'); - $form->buttons->submit->addClass('btn-wide'); - - } else { - // remove the cancel button - $form->buttons->cancel = ''; - } - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/forms/pages/template.php b/panel/app/forms/pages/template.php deleted file mode 100644 index bdaa1cc..0000000 --- a/panel/app/forms/pages/template.php +++ /dev/null @@ -1,36 +0,0 @@ -parent()->blueprint()->pages()->template() as $template) { - $options[$template->name()] = $template->title(); - } - - // create the form - $form = new Kirby\Panel\Form(array( - 'template' => array( - 'label' => 'pages.template.select.label', - 'type' => 'select', - 'options' => $options, - 'default' => key($options), - 'required' => true, - 'readonly' => count($options) == 1 ? true : false, - 'icon' => count($options) == 1 ? $page->blueprint()->pages()->template()->first()->icon() : 'chevron-down', - 'autofocus' => true - ), - 'disclaimer' => array( - 'type' => 'info', - 'text' => '' - ) - ), array( - 'template' => $page->intendedTemplate() - )); - - $form->buttons->submit->val(l('change')); - $form->cancel($page); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/forms/pages/toggle.php b/panel/app/forms/pages/toggle.php deleted file mode 100644 index 08cdffe..0000000 --- a/panel/app/forms/pages/toggle.php +++ /dev/null @@ -1,52 +0,0 @@ -parent(); - $blueprint = $parent->blueprint(); - $siblings = $parent->children()->visible(); - - // sorting needed - if($blueprint->pages()->num()->mode() == 'default' and $siblings->count() > 0) { - - $options = array('' => l('pages.toggle.invisible'), '-' => '-'); - $n = 1; - - foreach($siblings as $sibling) { - $options[$n] = $n; - $n++; - } - - if($page->isInvisible()) { - $options[$n] = $n; - } - - $form = new Kirby\Panel\Form(array( - 'position' => array( - 'label' => l('pages.toggle.position'), - 'type' => 'select', - 'required' => true, - 'default' => $page->num(), - 'options' => $options - ) - )); - - } else { - - $form = new Kirby\Panel\Form(array( - 'confirmation' => array( - 'type' => 'info', - 'text' => $page->isVisible() ? l('pages.toggle.hide') : l('pages.toggle.publish') - ) - )); - - } - - $form->buttons->submit->value = l('change'); - $form->buttons->submit->autofocus = true; - - $form->cancel($page); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/forms/pages/url.php b/panel/app/forms/pages/url.php deleted file mode 100644 index 110569e..0000000 --- a/panel/app/forms/pages/url.php +++ /dev/null @@ -1,34 +0,0 @@ - 'btn btn-icon label-option', - 'href' => '#', - 'data-title' => str::slug($page->title()) - )); - - // url preview - $preview = new Brick('div', '', array('class' => 'uid-preview')); - $preview->append(ltrim($page->parent()->uri() . '/', '/')); - $preview->append('' . $page->slug() . ''); - - // create the form - $form = new Kirby\Panel\Form(array( - 'uid' => array( - 'label' => l('pages.url.uid.label') . $option, - 'type' => 'text', - 'icon' => 'chain', - 'autofocus' => true, - 'help' => $preview, - 'default' => $page->slug() - ) - )); - - $form->buttons->submit->val(l('change')); - $form->cancel($page); - - return $form; - -}; \ No newline at end of file diff --git a/panel/app/forms/users/delete.php b/panel/app/forms/users/delete.php deleted file mode 100644 index 150b7ea..0000000 --- a/panel/app/forms/users/delete.php +++ /dev/null @@ -1,22 +0,0 @@ - array( - 'label' => 'users.delete.headline', - 'type' => 'text', - 'readonly' => true, - 'icon' => false, - 'default' => $user->username(), - 'help' => $user->email(), - ) - )); - - $form->style('delete'); - $form->cancel($user, 'edit'); - - return $form; - -}; - diff --git a/panel/app/forms/users/user.php b/panel/app/forms/users/user.php deleted file mode 100644 index 5aca291..0000000 --- a/panel/app/forms/users/user.php +++ /dev/null @@ -1,120 +0,0 @@ -data() : array(); - $translations = array(); - $roles = array(); - - // make sure the password is never shown in the form - unset($content['password']); - - // add all languages - foreach(panel()->translations() as $code => $translation) { - $translations[$code] = $translation->title(); - } - - // add all roles - foreach(site()->roles() as $role) { - $roles[$role->id()] = $role->name(); - } - - // the default set of fields - $fields = array( - - 'username' => array( - 'label' => 'users.form.username.label', - 'type' => 'text', - 'icon' => 'user', - 'autofocus' => $mode != 'edit', - 'required' => true, - 'help' => $mode == 'edit' ? 'users.form.username.readonly' : 'users.form.username.help', - 'readonly' => $mode == 'edit', - ), - - 'firstName' => array( - 'label' => 'users.form.firstname.label', - 'autofocus' => $mode == 'edit', - 'type' => 'text', - 'width' => '1/2', - ), - - 'lastName' => array( - 'label' => 'users.form.lastname.label', - 'type' => 'text', - 'width' => '1/2', - ), - - 'email' => array( - 'label' => 'users.form.email.label', - 'type' => 'email', - 'required' => true, - 'autocomplete' => false - ), - - 'password' => array( - 'label' => $mode == 'edit' ? 'users.form.password.new.label' : 'users.form.password.label', - 'required' => $mode == 'add', - 'type' => 'password', - 'width' => '1/2', - 'suggestion' => true, - ), - - 'passwordConfirmation' => array( - 'label' => $mode == 'edit' ? 'users.form.password.new.confirm.label' : 'users.form.password.confirm.label', - 'required' => $mode == 'add', - 'type' => 'password', - 'width' => '1/2', - ), - - 'language' => array( - 'label' => 'users.form.language.label', - 'type' => 'select', - 'required' => true, - 'width' => '1/2', - 'default' => kirby()->option('panel.language', 'en'), - 'options' => $translations - ), - - 'role' => array( - 'label' => 'users.form.role.label', - 'type' => 'select', - 'required' => true, - 'width' => '1/2', - 'default' => site()->roles()->findDefault()->id(), - 'options' => $roles, - 'readonly' => (!panel()->user()->isAdmin() or ($user and $user->isLastAdmin())) - ), - - ); - - if($user) { - - // add all custom fields - foreach($user->blueprint()->fields()->toArray() as $name => $field) { - - if(array_key_exists($name, $fields)) { - continue; - } - - $fields[$name] = $field; - - } - - } - - // setup the form with all fields - $form = new Kirby\Panel\Form($fields, $content); - - // setup the url for the cancel button - $form->cancel('users'); - - if($mode == 'add') { - $form->buttons->submit->value = l('add'); - } - - return $form; - -}; - diff --git a/panel/app/helpers.php b/panel/app/helpers.php deleted file mode 100644 index cb8bc53..0000000 --- a/panel/app/helpers.php +++ /dev/null @@ -1,75 +0,0 @@ -'; -} - -function i($icon, $position = null) { - echo icon($icon, $position); -} - -function __($var) { - echo htmlspecialchars($var); -} - -function _l($key, $default = null) { - echo htmlspecialchars(l($key, $default)); -} - -function i18n($value) { - - if(empty($value)) { - return null; - } else if(is_array($value)) { - $translation = a::get($value, panel()->translation()->code()); - - if(empty($translation)) { - // try to fallback to the default language at least - $translation = a::get($value, kirby()->option('panel.language'), $this->name()); - } - - return $translation; - } else if(is_string($value) and $translation = l::get($value)) { - return $translation; - } else { - return $value; - } - -} - -function _u($obj = '', $action = false) { - echo purl($obj, $action); -} - -function purl($obj = '/', $action = false) { - - if(empty($obj) or is_string($obj)) { - $base = panel()->urls()->index(); - return ($obj == '/' or empty($obj)) ? $base . '/' : rtrim($base . '/' . $obj, '/'); - } else if(is_a($obj, 'Kirby\\Panel\\Models\\Site')) { - return $obj->url(!$action ? 'edit' : $action); - } else if(is_a($obj, 'Kirby\\Panel\\Models\\Page')) { - return $obj->url(!$action ? 'edit' : $action); - } else if(is_a($obj, 'Kirby\\Panel\\Models\\File')) { - return $obj->url(!$action ? 'edit' : $action); - } else if(is_a($obj, 'Kirby\\Panel\\Models\\User')) { - return $obj->url(!$action ? 'edit' : $action); - } - -} - -function slugTable() { - $table = array(); - foreach(str::$ascii as $key => $value) { - $key = trim($key, '/'); - foreach(str::split($key, '|') as $needle) { - $table[$needle] = $value; - } - } - - return json_encode($table, JSON_UNESCAPED_UNICODE); -} \ No newline at end of file diff --git a/panel/app/layouts/app.php b/panel/app/layouts/app.php deleted file mode 100644 index 1193fcb..0000000 --- a/panel/app/layouts/app.php +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - <?php __($title) ?> - - - - - - option('panel.stylesheet')): ?> - - - - - - - - - - - -
    - - -
    - - - \ No newline at end of file diff --git a/panel/app/layouts/base.php b/panel/app/layouts/base.php deleted file mode 100644 index d968aff..0000000 --- a/panel/app/layouts/base.php +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - <?php __($title) ?> - - - - option('panel.stylesheet')): ?> - - - - - - - - - - \ No newline at end of file diff --git a/panel/app/layouts/fatal.php b/panel/app/layouts/fatal.php deleted file mode 100644 index fd6e049..0000000 --- a/panel/app/layouts/fatal.php +++ /dev/null @@ -1,32 +0,0 @@ - - - - Kirby Panel - - - - - - -

    Panel Error:

    -

    - -

    -

    - Find more info on: getkirby.com -

    - - \ No newline at end of file diff --git a/panel/app/snippets/breadcrumb.php b/panel/app/snippets/breadcrumb.php deleted file mode 100644 index 461820c..0000000 --- a/panel/app/snippets/breadcrumb.php +++ /dev/null @@ -1,19 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/snippets/languages.php b/panel/app/snippets/languages.php deleted file mode 100644 index d91995f..0000000 --- a/panel/app/snippets/languages.php +++ /dev/null @@ -1,21 +0,0 @@ -count() > 1): ?> - -
    - - - code()) ?> - - - - -
    - - diff --git a/panel/app/snippets/menu.php b/panel/app/snippets/menu.php deleted file mode 100644 index ecf362d..0000000 --- a/panel/app/snippets/menu.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - - \ No newline at end of file diff --git a/panel/app/snippets/meta.php b/panel/app/snippets/meta.php deleted file mode 100644 index d6b4cb7..0000000 --- a/panel/app/snippets/meta.php +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/panel/app/snippets/pages/sidebar.php b/panel/app/snippets/pages/sidebar.php deleted file mode 100644 index 03b68ff..0000000 --- a/panel/app/snippets/pages/sidebar.php +++ /dev/null @@ -1,19 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/snippets/pages/sidebar/file.php b/panel/app/snippets/pages/sidebar/file.php deleted file mode 100644 index e7ab043..0000000 --- a/panel/app/snippets/pages/sidebar/file.php +++ /dev/null @@ -1,6 +0,0 @@ -
  • - canHavePreview(), ' data-url="' . $file->crop(75)->url() . '"') ?> data-helper="filename()) ?>" data-text="dragText()) ?>" href="url('edit')) ?>"> - icon() . __($file->filename()) ?> - - -
  • \ No newline at end of file diff --git a/panel/app/snippets/pages/sidebar/files.php b/panel/app/snippets/pages/sidebar/files.php deleted file mode 100644 index bf8fbca..0000000 --- a/panel/app/snippets/pages/sidebar/files.php +++ /dev/null @@ -1,27 +0,0 @@ -

    - - isSite(), l('metatags.files'), l('pages.show.files.title')) ?> - - - - - - - canHaveMoreFiles()) : ?> - - - - - - -

    - -count()): ?> - - -

    - \ No newline at end of file diff --git a/panel/app/snippets/pages/sidebar/subpage.php b/panel/app/snippets/pages/sidebar/subpage.php deleted file mode 100644 index 78e36e6..0000000 --- a/panel/app/snippets/pages/sidebar/subpage.php +++ /dev/null @@ -1,7 +0,0 @@ -
  • - - icon() ?>title()) ?> - displayNum()) ?> - - -
  • \ No newline at end of file diff --git a/panel/app/snippets/pages/sidebar/subpages.php b/panel/app/snippets/pages/sidebar/subpages.php deleted file mode 100644 index aa9ab9d..0000000 --- a/panel/app/snippets/pages/sidebar/subpages.php +++ /dev/null @@ -1,42 +0,0 @@ -

    - - - - - - - - - - modal(), ' data-modal') ?> href="url()) ?>"> - - - - - - - -

    - -count()): ?> - - - - - -

    - - - modal(), ' data-modal') ?> href="url()) ?>"> - - - - - - -

    - \ No newline at end of file diff --git a/panel/app/snippets/pagination.php b/panel/app/snippets/pagination.php deleted file mode 100644 index 3ffeb5a..0000000 --- a/panel/app/snippets/pagination.php +++ /dev/null @@ -1,14 +0,0 @@ -pages() > 1): ?> - - \ No newline at end of file diff --git a/panel/app/snippets/search.php b/panel/app/snippets/search.php deleted file mode 100644 index d7b83b4..0000000 --- a/panel/app/snippets/search.php +++ /dev/null @@ -1,10 +0,0 @@ - - - - - \ No newline at end of file diff --git a/panel/app/snippets/subpages/subpage.php b/panel/app/snippets/subpages/subpage.php deleted file mode 100644 index b680a91..0000000 --- a/panel/app/snippets/subpages/subpage.php +++ /dev/null @@ -1,29 +0,0 @@ -
    -
    -
    - title()) ?> -
    -
    - -
    \ No newline at end of file diff --git a/panel/app/snippets/template.php b/panel/app/snippets/template.php deleted file mode 100644 index 2aab7f5..0000000 --- a/panel/app/snippets/template.php +++ /dev/null @@ -1,27 +0,0 @@ - -
    -

    - - -

    - - -

    - - - -

    - - -

    - - - -

    - - -

    - - -
    - \ No newline at end of file diff --git a/panel/app/snippets/uploader.php b/panel/app/snippets/uploader.php deleted file mode 100644 index ff5be50..0000000 --- a/panel/app/snippets/uploader.php +++ /dev/null @@ -1,20 +0,0 @@ - isset($multiple) ? $multiple : true, - 'accept' => isset($accept) ? $accept : false -)); - -?> - - - \ No newline at end of file diff --git a/panel/app/src/panel.php b/panel/app/src/panel.php deleted file mode 100644 index 7a66812..0000000 --- a/panel/app/src/panel.php +++ /dev/null @@ -1,559 +0,0 @@ - '5.4.0', - 'toolkit' => '2.2.2', - 'kirby' => '2.2.1' - ); - - static public $instance; - - public $kirby; - public $site; - public $path; - public $roots; - public $routes = array(); - public $router = null; - public $route = null; - public $translation = null; - public $translations = null; - public $csrf = null; - - static public function instance() { - return static::$instance; - } - - static public function version() { - return static::$version; - } - - public function defaults() { - - return array( - 'panel.language' => 'en', - 'panel.stylesheet' => null, - 'panel.kirbytext' => true, - 'panel.session.timeout' => 1440, - 'panel.session.lifetime' => 0, - 'panel.info.license' => true, - 'panel.info.versions' => true, - 'panel.widgets' => array( - 'pages' => true, - 'site' => true, - 'account' => true, - 'history' => true - ), - ); - - } - - public function __construct($kirby, $root) { - - // check requirements - $this->requirements(); - - // store the instance as a singleton - static::$instance = $this; - - $this->kirby = $kirby; - $this->roots = new \Kirby\Panel\Roots($this, $root); - $this->urls = new \Kirby\Panel\Urls($this, $root); - - // add the panel default options - $this->kirby->options = array_merge($this->defaults(), $this->kirby->options); - - // setup the blueprints roots - UserBlueprint::$root = $this->kirby->roots()->blueprints() . DS . 'users'; - PageBlueprint::$root = $this->kirby->roots()->blueprints(); - - // load the site object - $this->site = $this->site(); - - // setup the session - $this->session(); - - // setup the multilang site stuff - $this->multilang(); - - // load all Kirby extensions (methods, tags, smartypants) - $this->kirby->extensions(); - $this->kirby->plugins(); - - // setup the form plugin - form::$root = array( - 'default' => $this->roots->fields, - 'custom' => $this->kirby->roots()->fields() - ); - - // force ssl if set in config - if($this->kirby->option('ssl') and !r::secure()) { - // rebuild the current url with https - go(url::build(array('scheme' => 'https'))); - } - - // load all available routes - $this->routes = array_merge($this->routes, require($this->roots->config . DS . 'routes.php')); - - // start the router - $this->router = new Router($this->routes); - - // register router filters - $this->router->filter('auth', function() use($kirby) { - try { - $user = panel()->user(); - } catch(Exception $e) { - panel()->redirect('login'); - } - }); - - // check for a completed installation - $this->router->filter('isInstalled', function() use($kirby) { - $installer = new Installer(); - if(!$installer->isCompleted()) { - panel()->redirect('install'); - } - }); - - // check for valid csrf tokens. Can be used for get requests - // since all post requests are blocked anyway - $this->router->filter('csrf', function() { - panel()->csrfCheck(); - }); - - // csrf protection for every post request - if(r::is('post')) { - $this->csrfCheck(); - } - - } - - public function session() { - - // setup the session - s::$timeout = $this->kirby->option('panel.session.timeout', 120); - s::$cookie['lifetime'] = $this->kirby->option('panel.session.lifetime', 0); - - // start the session - s::start(); - - } - - public function requirements() { - - if(!version_compare(PHP_VERSION, static::$requires['php'], '>=')) { - throw new Exception('Your PHP version is too old. Please upgrade to ' . static::$requires['php'] . ' or newer.'); - } - - if(!detect::mbstring()) { - throw new Exception('The mbstring extension must be installed'); - } - - if(!version_compare(toolkit::version(), static::$requires['toolkit'], '>=')) { - throw new Exception('Your Toolkit version is too old. Please upgrade to ' . static::$requires['toolkit'] . ' or newer.'); - } - - if(!version_compare(kirby::version(), static::$requires['kirby'], '>=')) { - throw new Exception('Your Kirby version is too old. Please upgrade to ' . static::$requires['kirby'] . ' or newer.'); - } - - } - - public function csrf() { - - if(!is_null($this->csrf)) return $this->csrf; - - // see if there's a token in the session - $token = s::get('csrf'); - - // create a new csrf token if not available yet - if(str::length($token) !== 32) { - $token = str::random(32); - } - - // store the new token in the session - s::set('csrf', $token); - - // create a new csrf token - return $this->csrf = $token; - - } - - public function csrfCheck() { - - $csrf = get('csrf'); - - if(empty($csrf) or $csrf !== s::get('csrf')) { - - try { - $this->user()->logout(); - } catch(Exception $e) {} - - $this->redirect('login'); - - } - - } - - public function kirby() { - return $this->kirby; - } - - public function site() { - - // return the site object if it has already been stored - if(!is_null($this->site)) return $this->site; - - // load the original site first to load all branch files - $this->kirby->site(); - - // create a new panel site object - return $this->site = new Site($this->kirby); - - } - - public function multilang() { - - if(!$this->site->multilang()) { - $language = null; - } else if($language = get('language') or $language = s::get('lang')) { - // $language is already set - } else { - $language = null; - } - - // set the path and lang for the original site object - $this->kirby->site()->visit('/', $language); - - // set the path and lang for the panel site object - $this->site->visit('/', $language); - - // store the language code - if($this->site->multilang()) { - s::set('lang', $this->site->language()->code()); - } - - } - - public function page($id) { - if($page = (empty($id) or $id == '/') ? $this->site() : $this->site()->find($id)) { - return $page; - } else { - throw new Exception(l('pages.error.missing')); - } - } - - public function roots() { - return $this->roots; - } - - public function routes($routes = null) { - if(is_null($routes)) return $this->routes; - return $this->routes = array_merge($this->routes, (array)$routes); - } - - public function urls() { - return $this->urls; - } - - public function form($id, $data = array(), $submit = null) { - - if(file_exists($id)) { - $file = $id; - } else { - $file = $this->roots->forms . DS . $id . '.php'; - } - - if(!file_exists($file)) { - throw new Exception(l('form.error.missing')); - } - - $callback = require($file); - - if(!is_callable($callback)) { - throw new Exception(l('form.construct.error.invalid')); - } - - $form = call($callback, $data); - - if(is_callable($submit)) { - $form->on('submit', $submit); - } - - return $form; - - } - - public function translations() { - - if(!is_null($this->translations)) return $this->translations; - - $this->translations = new Collection; - - foreach(dir::read($this->roots()->translations()) as $dir) { - // filter out everything but directories - if(!is_dir($this->roots()->translations() . DS . $dir)) continue; - - // create the translation object - $translation = new Translation($this, $dir); - $this->translations->append($translation->code(), $translation); - } - - return $this->translations; - - } - - public function translation() { - - if(!is_null($this->translation)) return $this->translation; - - // get the default language code from the options - $lang = $this->kirby()->option('panel.language', 'en'); - $user = $this->site()->user(); - - if($user && $user->language()) { - $lang = $user->language(); - } - - return $this->translation = new Translation($this, $lang); - - } - - public function language() { - return $this->translation; - } - - public function direction() { - return $this->translation->direction(); - } - - public function launch($path = null) { - - // set the timezone for all date functions - date_default_timezone_set($this->kirby->options['timezone']); - - // load the current translation - $this->translation()->load(); - - $this->path = $this->kirby->path(); - $this->route = $this->router->run($this->path); - - // set the current url - $this->urls->current = rtrim($this->urls->index() . '/' . $this->path, '/'); - - ob_start(); - - try { - - // react on invalid routes - if(!$this->route) { - throw new Exception(l('routes.error.invalid')); - } - - if(is_callable($this->route->action())) { - $response = call($this->route->action(), $this->route->arguments()); - } else { - $response = $this->response(); - } - - } catch(Exception $e) { - require_once($this->roots->controllers . DS . 'error.php'); - $controller = new ErrorController(); - $response = $controller->index($e->getMessage(), $e); - } - - // check for a valid response object - if(is_a($response, 'Response')) { - echo $response; - } else { - echo new Response($response); - } - - ob_end_flush(); - - } - - public function response() { - - // let's find the controller and controller action - $controllerParts = str::split($this->route->action(), '::'); - $controllerUri = $controllerParts[0]; - $controllerAction = $controllerParts[1]; - $controllerFile = $this->roots->controllers . DS . strtolower(str_replace('Controller', '', $controllerUri)) . '.php'; - $controllerName = basename($controllerUri); - - // react on missing controllers - if(!file_exists($controllerFile)) { - throw new Exception(l('controller.error.invalid')); - } - - // load the controller - require_once($controllerFile); - - // check for the called action - if(!method_exists($controllerName, $controllerAction)) { - throw new Exception(l('controller.error.action')); - } - - // run the controller - $controller = new $controllerName; - - // call the action and pass all arguments from the router - return call(array($controller, $controllerAction), $this->route->arguments()); - - } - - public function license() { - - $key = c::get('license'); - $type = 'trial'; - - /** - * Hey stranger, - * - * So this is the mysterious place where the panel checks for - * valid licenses. As you can see, this is not reporting - * back to any server and the license keys are rather simple to - * hack. If you really feel like removing the warning in the panel - * or tricking Kirby into believing you bought a valid license even - * if you didn't, go for it! But remember that literally thousands of - * hours of work have gone into Kirby in order to make your - * life as a developer, designer, publisher, etc. easier. If this - * doesn't mean anything to you, you are probably a lost case anyway. - * - * Have a great day! - * - * Bastian - */ - if(str::startsWith($key, 'K2-PRO') and str::length($key) == 39) { - $type = 'Kirby 2 Professional'; - } else if(str::startsWith($key, 'K2-PERSONAL') and str::length($key) == 44) { - $type = 'Kirby 2 Personal'; - } else if(str::startsWith($key, 'MD-') and str::length($key) == 35) { - $type = 'Kirby 1'; - } else if(str::startsWith($key, 'BETA') and str::length($key) == 9) { - $type = 'Kirby 1'; - } else if(str::length($key) == 32) { - $type = 'Kirby 1'; - } else { - $key = null; - } - - return new Obj(array( - 'key' => $key, - 'local' => $this->isLocal(), - 'type' => $type, - )); - - } - - public function isLocal() { - $localhosts = array('::1', '127.0.0.1', '0.0.0.0'); - return (in_array(server::get('SERVER_ADDR'), $localhosts) || server::get('SERVER_NAME') == 'localhost'); - } - - public function notify($text) { - s::set('message', array( - 'type' => 'notification', - 'text' => $text, - )); - } - - public function alert($text) { - s::set('message', array( - 'type' => 'error', - 'text' => $text, - )); - } - - public function redirect($obj = '/', $action = false, $force = false) { - - if($force === false and $redirect = get('_redirect')) { - $url = purl($redirect); - } else { - $url = purl($obj, $action); - } - - if(r::ajax()) { - - $user = $this->site()->user(); - - die(response::json(array( - 'direction' => $this->direction(), - 'user' => $user ? $user->username() : false, - 'url' => $url - ))); - - } else { - go($url); - } - - } - - public function users() { - return $this->site()->users(); - } - - public function user($username = null) { - if($user = $this->site()->user($username)) { - return $user; - } else { - throw new Exception(l('users.error.missing')); - } - } - - public static function fatal($e, $root) { - - $message = $e->getMessage() ? $e->getMessage() : 'Error without a useful message :('; - $where = implode('
    ', [ - '', - '', - 'It happened here:', - 'File: ' . str_replace($root, '/panel', $e->getFile()) . '', - 'Line: ' . $e->getLine() . '' - ]); - - // load the fatal screen - return tpl::load($root . DS . 'app' . DS . 'layouts' . DS . 'fatal.php', [ - 'css' => url::index() . '/assets/css/panel.css', - 'content' => $message . $where - ]); - - } - -} diff --git a/panel/app/src/panel/autocomplete.php b/panel/app/src/panel/autocomplete.php deleted file mode 100644 index 2460759..0000000 --- a/panel/app/src/panel/autocomplete.php +++ /dev/null @@ -1,119 +0,0 @@ -panel = $panel; - $this->site = $panel->site(); - $this->method = $method; - $this->params = $params; - } - - public function result() { - - $method = 'autocomplete' . $this->method; - - if(!method_exists($this, $method)) { - throw new Exception(l('autocomplete.method.error')); - } - - $result = array_values((array)$this->$method($this->params)); - - // sort results alphabetically - sort($result); - - return $result; - - } - - public function autocompleteUsernames() { - return $this->panel->users()->map(function($user) { - return $user->username(); - })->toArray(); - } - - public function autocompleteEmails() { - return $this->panel->users()->map(function($user) { - return $user->email(); - })->toArray(); - } - - public function autocompleteUris() { - return $this->site->index()->map(function($page) { - return $page->id(); - })->toArray(); - } - - public function autocompleteField($params = array()) { - - $defaults = array( - 'index' => 'siblings', - 'uri' => '/', - 'field' => 'tags', - 'yaml' => false, - 'model' => 'page', - 'separator' => true - ); - - $options = array_merge($defaults, $params); - $page = $this->panel->page($options['uri']); - $pages = $this->pages($page, $options['index'], $options); - $yaml = $options['yaml']; - - if($yaml or $options['model'] == 'file') { - $result = array(); - foreach($pages as $p) { - if($yaml) { - $index = $p->$yaml()->toStructure(); - } elseif($options['model'] == 'file') { - $index = $p->files(); - } - $values = $index->pluck($options['field'], $options['separator'], true); - $result = array_merge($result, $values); - } - $result = array_unique($result); - } else { - $result = $pages->pluck($options['field'], $options['separator'], true); - } - - return $result; - - } - - public function pages($page, $index, $params = array()) { - - switch($index) { - case 'self': - return new Pages(array($page)); - break; - case 'siblings': - case 'children': - return $page->$index(); - break; - case 'template': - $template = a::get($params, 'template', $page->template()); - return $this->site->index()->filterBy('template', $template); - break; - case 'pages': - case 'all': - return $this->site->index(); - break; - default: - return $page->children(); - break; - } - - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/collections/children.php b/panel/app/src/panel/collections/children.php deleted file mode 100644 index 6b1ee83..0000000 --- a/panel/app/src/panel/collections/children.php +++ /dev/null @@ -1,129 +0,0 @@ -reset(); - - $inventory = $page->inventory(); - - foreach($inventory['children'] as $dirname) { - $child = new Page($page, $dirname); - $this->data[$child->id()] = $child; - } - - $sort = $page->blueprint()->pages()->sort(); - - switch($sort) { - case 'flip': - $cloned = $this->flip(); - $this->data = $cloned->data; - break; - default; - $parts = str::split($sort, ' '); - if(count($parts) > 0) { - $cloned = call(array($this, 'sortBy'), $parts); - $this->data = $cloned->data; - } - break; - } - - } - - public function create($uid, $template, $content = array()) { - - if(empty($template)) { - throw new Exception(l('pages.add.error.template')); - } - - $uid = empty($uid) ? str::random(32) : $uid; - $blueprint = new Blueprint($template); - $data = array(); - - foreach($blueprint->fields(null) as $key => $field) { - $data[$key] = $field->default(); - } - - $data = array_merge($data, $content); - - // create the new page and convert it to a page model - $page = new Page($this->page, parent::create($uid, $template, $data)->dirname()); - - if(!$page) { - throw new Exception(l('pages.add.error.create')); - } - - kirby()->trigger('panel.page.create', $page); - - // subpage builder - foreach((array)$page->blueprint()->pages()->build() as $build) { - $missing = a::missing($build, array('title', 'template', 'uid')); - if(!empty($missing)) continue; - $subpage = $page->children()->create($build['uid'], $build['template'], array('title' => $build['title'])); - if(isset($build['num'])) $subpage->sort($build['num']); - } - - return $page; - - } - - public function paginated($mode = 'sidebar') { - - if($limit = $this->page->blueprint()->pages()->limit()) { - - $hash = sha1($this->page->id()); - - switch($mode) { - case 'sidebar': - $id = 'pages.' . $hash; - $var = 'page'; - break; - case 'subpages/visible': - $id = 'subpages.visible.' . $hash; - $var = 'visible'; - break; - case 'subpages/invisible': - $id = 'subpages.invisible.' . $hash; - $var = 'invisible'; - break; - } - - // filter out hidden pages - $children = $this->filter(function($child) { - return $child->blueprint()->hide() === false; - }); - - $children = $children->paginate($limit, array( - 'page' => get($var, s::get($id)), - 'omitFirstPage' => false, - 'variable' => $var, - 'method' => 'query', - 'redirect' => false - )); - - // store the last page - s::set($id, $children->pagination()->page()); - - return $children; - - } else { - return $this; - } - - } - - -} diff --git a/panel/app/src/panel/collections/files.php b/panel/app/src/panel/collections/files.php deleted file mode 100644 index 777590c..0000000 --- a/panel/app/src/panel/collections/files.php +++ /dev/null @@ -1,51 +0,0 @@ -kirby = $page->kirby; - $this->site = $page->site; - $this->page = $page; - - // make sure the inventory is always fresh - $this->page->reset(); - - $inventory = $page->inventory(); - - foreach($inventory['files'] as $filename) { - $file = new File($this, $filename); - $this->data[strtolower($file->filename())] = $file; - } - - if($this->page->canSortFiles()) { - $sorted = $this->sortBy('sort', 'asc'); - $this->data = $sorted->data; - } - - if($this->page->blueprint()->files()->sort() == 'flip') { - $flipped = $this->flip(); - $this->data = $flipped->data; - } - - } - - public function topbar($topbar) { - - $page = $this->page(); - - if($page->isSite()) { - $topbar->append(purl('options'), l('metatags')); - } - - $page->topbar($topbar); - - $topbar->append($page->url('files'), l('files')); - - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/collections/users.php b/panel/app/src/panel/collections/users.php deleted file mode 100644 index e9f819a..0000000 --- a/panel/app/src/panel/collections/users.php +++ /dev/null @@ -1,39 +0,0 @@ -map(function($user) { - return new User($user->username()); - }); - - } - - public function topbar($topbar) { - $topbar->append(purl('users'), l('users')); - } - - public function create($data) { - - if($data['password'] !== $data['passwordconfirmation']) { - throw new Exception(l('users.form.error.password.confirm')); - } - - unset($data['passwordconfirmation']); - - $user = parent::create($data); - kirby()->trigger('panel.user.create', $user); - return new User($user->username()); - - } - - -} \ No newline at end of file diff --git a/panel/app/src/panel/controllers/base.php b/panel/app/src/panel/controllers/base.php deleted file mode 100644 index 1c6b864..0000000 --- a/panel/app/src/panel/controllers/base.php +++ /dev/null @@ -1,121 +0,0 @@ -redirect($obj, $action, $force); - } - - public function notify($message) { - panel()->notify($message); - } - - public function alert($message) { - panel()->alert($message); - } - - public function form($id, $data = array(), $submit = null) { - return panel()->form($id, $data, $submit); - } - - public function page($id) { - return panel()->page($id); - } - - public function user($username = null) { - return panel()->user($username); - } - - public function layout($type, $data = array()) { - - $version = panel()->version(); - $base = panel()->urls()->index(); - $cssbase = panel()->urls()->css(); - $jsbase = panel()->urls()->js(); - - $defaults = array( - 'title' => panel()->site()->title() . ' | Panel', - 'direction' => panel()->direction(), - 'meta' => $this->snippet('meta'), - 'css' => css($cssbase . '/panel.min.css?v=' . $version), - 'js' => js($jsbase . '/dist/panel.min.js?v=' . $version), - 'content' => '', - 'bodyclass' => '', - ); - - switch($type) { - case 'app': - $defaults['topbar'] = ''; - $defaults['csrf'] = panel()->csrf(); - $defaults['formcss'] = css($cssbase . '/form.min.css?v=' . $version); - $defaults['formjs'] = js($jsbase . '/dist/form.min.js?v=' . $version); - $defaults['appjs'] = js($jsbase . '/dist/app.min.js?v=' . $version); - - // plugin stuff - $defaults['pluginscss'] = css($base . '/plugins/css?v=' . $version); - $defaults['pluginsjs'] = js($base . '/plugins/js?v=' . $version); - - break; - case 'base': - break; - } - - $data = array_merge($defaults, $data); - - if(r::ajax() and $type == 'app') { - $panel = panel(); - $user = $panel->site()->user(); - $response = array( - 'user' => $user ? $user->username() : false, - 'direction' => $panel->direction(), - 'title' => $data['title'], - 'content' => $data['topbar'] . $data['content'] - ); - return response::json($response); - } else { - return new Layout($type, $data); - } - - } - - public function view($file, $data = array()) { - return new View($file, $data); - } - - public function snippet($file, $data = array()) { - return new Snippet($file, $data); - } - - public function topbar($view, $input) { - return new Topbar($view, $input); - } - - public function screen($view, $topbar = null, $data = array()) { - return $this->layout('app', array( - 'topbar' => is_a($topbar, 'Kirby\\Panel\\Topbar') ? $topbar : $this->topbar($view, $topbar), - 'content' => is_a($data, 'Kirby\\Panel\\View') ? $data : $this->view($view, $data) - )); - } - - public function modal($view, $data = array()) { - if($view === 'error') $view = 'error/modal'; - return $this->layout('app', array('content' => $this->view($view, $data))); - } - - public function json($data = array()) { - return response::json($data); - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/controllers/field.php b/panel/app/src/panel/controllers/field.php deleted file mode 100644 index 53073fb..0000000 --- a/panel/app/src/panel/controllers/field.php +++ /dev/null @@ -1,47 +0,0 @@ -model = $model; - $this->field = $field; - $this->fieldname = $field->name(); - } - - public function form($id, $data = array(), $submit = null) { - $file = $this->field->root() . DS . 'forms' . DS . $id . '.php'; - return panel()->form($file, $data, $submit); - } - - public function view($file, $data = array()) { - - $view = new View($file, $data); - $root = $this->field->root() . DS . 'views'; - - if(file_exists($root . DS . $file . '.php')) { - $view->_root = $root; - } - - return $view; - - } - - public function snippet($file, $data = array()) { - - $snippet = new Snippet($file, $data); - $root = $this->field->root() . DS . 'snippets'; - - if(file_exists($root . DS . $file . '.php')) { - $snippet->_root = $root; - } - - return $snippet; - - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/form.php b/panel/app/src/panel/form.php deleted file mode 100644 index e489deb..0000000 --- a/panel/app/src/panel/form.php +++ /dev/null @@ -1,340 +0,0 @@ -fields = new Collection; - - // if Form is part of a structureField, set structureField name - $this->parentField = $parent; - - // initialize all field plugins - $this->plugins = new Plugins(); - - $this->values($values); - $this->fields($fields); - $this->buttons(); - $this->attr('method', 'post'); - $this->attr('action', panel()->urls()->current()); - $this->addClass('form'); - - } - - public function method($method = null) { - return $this->attr('method', $method); - } - - public function action($action = null) { - return $this->attr('action', $action); - } - - public function fields($fields = null) { - - if(is_null($fields)) return $this->fields; - - // get the site object - $site = panel()->site(); - - // check if untranslatable fields should be deactivated - $translated = $site->multilang() && !$site->language()->default(); - - foreach($fields as $name => $field) { - - $name = str_replace('-','_', str::lower($name)); - - $field['name'] = $name; - $field['default'] = a::get($field, 'default', null); - $field['value'] = a::get($this->values(), $name, $field['default']); - - // Pass through parent field name (structureField) - $field['parentField'] = $this->parentField; - - // Check for untranslatable fields - if($translated and isset($field['translate']) and $field['translate'] === false) { - $field['readonly'] = true; - $field['disabled'] = true; - } - - $this->fields->append($name, static::field($field['type'], $field)); - - } - - return $this; - - } - - public function values($values = null) { - if(is_null($values)) return array_merge($this->values, r::data()); - $this->values = array_merge($this->values, $values); - return $this; - } - - public function value($name) { - return a::get($this->values(), $name, null); - } - - public function validate() { - - $site = panel()->site(); - $translated = $site->multilang() && !$site->language()->default(); - $errors = array(); - - foreach($this->fields() as $field) { - - // don't validate fields, which are not translatable - if($translated and $field->translate() === false) continue; - - $name = $field->name(); - $value = $this->value($name); - - if($field->required() and $value == '') { - $field->error = true; - } else if($value !== '' and $field->validate() == false) { - $field->error = true; - } - - } - - } - - public function isValid() { - return $this->fields()->filterBy('error', true)->count() == 0; - } - - public function message($type, $text) { - - $this->message = new Brick('div'); - $this->message->addClass('message'); - - if($type == 'error') { - $this->message->addClass('message-is-alert'); - } else { - $this->message->addClass('message-is-notice'); - } - - $this->message->append(function() use($text) { - - $content = new Brick('span'); - $content->addClass('message-content'); - $content->text($text); - - return $content; - - }); - - return $this->message; - - } - - public function alert($text) { - $this->message('error', $text); - } - - public function notify($text) { - $this->message('success', $text); - } - - public function serialize() { - - $data = array(); - $site = panel()->site(); - $fields = $this->fields(); - - foreach($fields as $field) { - $result = $field->result(); - if(!is_null($result)) $data[$field->name()] = $result; - } - - // unset untranslatable fields in all languages but the default lang - if($site->multilang() and $site->language() != $site->defaultLanguage()) { - foreach($fields as $field) { - if($field->translate() === false) { - $data[$field->name()] = null; - } - } - } - - return $data; - - } - - public function toArray() { - return $this->serialize(); - } - - public function plugins() { - return $this->plugins; - } - - public function style($style) { - - switch($style) { - case 'centered': - $this->centered = true; - $this->buttons->cancel = ''; - break; - case 'upload': - $this->centered = true; - $this->buttons->submit = ''; - $this->attr('enctype', 'multipart/form-data'); - break; - case 'delete': - $this->buttons->submit->addClass('btn-negative'); - $this->buttons->submit->attr('autofocus', true); - $this->buttons->submit->val(l('delete')); - break; - case 'editor': - - $kirbytext = kirby()->option('panel.kirbytext', true); - - $this->data('textarea', get('textarea')); - $this->data('autosubmit', 'false'); - $this->data('kirbytext', r($kirbytext, 'true', 'false')); - $this->buttons->submit->val(l('insert')); - break; - } - - } - - public function redirect() { - return get('_redirect'); - } - - public function cancel() { - if($redirect = $this->redirect()) { - $this->buttons->cancel->href = purl($redirect); - } else { - $this->buttons->cancel->href = call('purl', func_get_args()); - } - } - - static public function field($type, $options = array()) { - - $class = $type . 'field'; - - if(!class_exists($class)) { - throw new Exception('The ' . $type . ' field is missing. Please add it to your installed fields or remove it from your blueprint'); - } - - $field = new $class; - - foreach($options as $key => $value) { - $field->$key = $value; - } - - return $field; - - } - - public function buttons() { - - if(!is_null($this->buttons)) return $this->buttons; - - $this->buttons = new Collection(); - - $button = new Brick('input', null); - $button->addClass('btn btn-rounded'); - - $cancel = clone $button; - $cancel->tag('a'); - $cancel->addClass('btn-cancel'); - $cancel->attr('href', '#cancel'); - $cancel->text(l('cancel')); - - $this->buttons->append('cancel', $cancel); - - $submit = clone $button; - $submit->attr('type', 'submit'); - $submit->addClass('btn-submit'); - $submit->data('saved', l('saved')); - $submit->val(l('save')); - - $this->buttons->append('submit', $submit); - - return $this->buttons; - - } - - public function on($action, $callback) { - - // auto-trigger the submit event when the form is being echoed - if(r::is('post')) { - $callback($this); - } - - $this->fields->append('csrf', static::field('hidden', array( - 'name' => 'csrf', - 'value' => panel()->csrf() - ))); - - } - - public function toHTML() { - - if($this->message) { - $this->append($this->message); - } - - $fieldset = new Brick('fieldset'); - $fieldset->addClass('fieldset field-grid cf'); - - foreach($this->fields() as $field) $fieldset->append($field); - - // pass the redirect url - $redirectField = new Brick('input'); - $redirectField->type = 'hidden'; - $redirectField->name = '_redirect'; - $redirectField->value = $this->redirect(); - $fieldset->append($redirectField); - - $this->append($fieldset); - - $buttons = new Brick('fieldset'); - $buttons->addClass('fieldset buttons'); - - if($this->centered) { - $buttons->addClass('buttons-centered'); - } - - foreach($this->buttons() as $button) $buttons->append($button); - - $this->append($buttons); - - return $this; - - } - - public function __toString() { - - $this->toHTML(); - return parent::__toString(); - - } - -} diff --git a/panel/app/src/panel/form/fieldoptions.php b/panel/app/src/panel/form/fieldoptions.php deleted file mode 100644 index fb17ace..0000000 --- a/panel/app/src/panel/form/fieldoptions.php +++ /dev/null @@ -1,256 +0,0 @@ -toArray(); - } - - public function __construct($field) { - - $this->field = $field; - - if(is_array($this->field->options)) { - $this->options = $this->field->options; - } else if($this->isUrl($this->field->options)) { - $this->options = $this->optionsFromApi($this->field->options); - } else if($this->field->options == 'query') { - $this->options = $this->optionsFromQuery($this->field->query); - } else if($this->field->options == 'field') { - $this->options = $this->optionsFromField($this->field->field); - } else { - $this->options = $this->optionsFromPageMethod($this->field->page, $this->field->options); - } - - // sorting - $this->options = $this->sort($this->options, !empty($this->field->sort) ? $this->field->sort : null); - - } - - public function optionsFromPageMethod($page, $method) { - - if($page && $items = $this->items($page, $method)) { - $options = array(); - foreach($items as $item) { - if(is_a($item, 'Page')) { - $options[$item->uid()] = (string)$item->title(); - } else if(is_a($item, 'File')) { - $options[$item->filename()] = (string)$item->filename(); - } - } - return $options; - } else { - return array(); - } - - } - - public function optionsFromApi($url) { - $response = remote::get($url); - $options = @json_decode($response->content(), true); - return is_array($options) ? $options : array(); - } - - public function optionsFromField($field) { - - // default field parameters - $defaults = array( - 'page' => $this->field->page ? ($this->field->page->isSite() ? '/' : $this->field->page->id()) : '', - 'name' => 'tags', - 'separator' => ',', - ); - - // sanitize the query - if(!is_array($field)) { - $field = array(); - } - - // merge the default parameters with the actual query - $field = array_merge($defaults, $field); - - // dynamic page option - // ../ - // ../../ etc. - $page = $this->page($field['page']); - $items = $page->{$field['name']}()->split($field['separator']); - $options = array(); - - foreach($items as $item) { - $options[$item] = $item; - } - - return $options; - - } - - public function optionsFromQuery($query) { - - // default query parameters - $defaults = array( - 'page' => $this->field->page ? ($this->field->page->isSite() ? '/' : $this->field->page->id()) : '', - 'fetch' => 'children', - 'value' => '{{uid}}', - 'text' => '{{title}}', - 'flip' => false, - 'template' => false - ); - - // sanitize the query - if(!is_array($query)) { - $query = array(); - } - - // merge the default parameters with the actual query - $query = array_merge($defaults, $query); - - // dynamic page option - // ../ - // ../../ etc. - $page = $this->page($query['page']); - $items = $this->items($page, $query['fetch']); - $options = array(); - - if($query['template']) { - $items = $items->filter(function($item) use($query) { - return in_array(str::lower($item->intendedTemplate()), array_map('str::lower', (array)$query['template'])); - }); - } - - if($query['flip']) { - $items = $items->flip(); - } - - foreach($items as $item) { - $value = $this->tpl($query['value'], $item); - $text = $this->tpl($query['text'], $item); - - $options[$value] = $text; - } - - return $options; - - } - - public function page($uri) { - - if(str::startsWith($uri, '../')) { - if($currentPage = $this->field->page) { - $path = $uri; - while(str::startsWith($path, '../')) { - if($parent = $currentPage->parent()) { - $currentPage = $parent; - } else { - $currentPage = site(); - } - $path = str::substr($path, 3); - } - if(!empty($path)) { - $currentPage = $currentPage->find($path); - } - $page = $currentPage; - } else { - $page = null; - } - } else if($uri == '/') { - $page = site(); - } else { - $page = page($uri); - } - - return $page; - - } - - public function sort($options, $sort) { - - if(empty($sort)) return $options; - - switch(strtolower($sort)) { - case 'asc': - asort($options); - break; - case 'desc': - arsort($options); - break; - } - - return $options; - - } - - public function tpl($string, $obj) { - return preg_replace_callback('!\{\{(.*?)\}\}!', function($item) use($obj) { - return (string)$obj->{$item[1]}(); - }, $string); - } - - public function isUrl($url) { - return - v::url($url) or - str::contains($url, '://localhost') or - str::contains($url, '://127.0.0.1'); - } - - public function items($page, $method) { - - if(!$page) return new Collection(); - - switch($method) { - case 'visibleChildren': - $items = $page->children()->visible(); - break; - case 'invisibleChildren': - $items = $page->children()->invisible(); - break; - case 'siblings': - $items = $page->siblings()->not($page); - break; - case 'visibleSiblings': - $items = $page->siblings()->not($page)->visible(); - break; - case 'invisibleSiblings': - $items = $page->siblings()->not($page)->invisible(); - break; - case 'pages': - $items = site()->index(); - $items = $items->sortBy('title', 'asc'); - break; - case 'index': - $items = $page->index(); - $items = $items->sortBy('title', 'asc'); - break; - case 'children': - case 'grandchildren': - case 'files': - case 'images': - case 'documents': - case 'videos': - case 'audio': - case 'code': - case 'archives': - $items = $page->{$method}(); - break; - default: - $items = new Collection(); - } - - return $items; - - } - - public function toArray() { - return $this->options; - } - -} diff --git a/panel/app/src/panel/form/plugins.php b/panel/app/src/panel/form/plugins.php deleted file mode 100644 index 4ff4e42..0000000 --- a/panel/app/src/panel/form/plugins.php +++ /dev/null @@ -1,113 +0,0 @@ -find(); - $this->load(); - } - - public function find() { - - $kirby = kirby(); - - // store all fields coming from plugins and load - // them between the default fields and the custom fields - $pluginfields = $kirby->get('field'); - - // load the default panel fields first, because they can be overwritten - foreach(dir::read(form::$root['default']) as $name) { - $kirby->set('field', $name, form::$root['default'] . DS . $name); - } - - // load the plugin fields again. A bit hacky, but works - foreach($pluginfields as $name => $field) { - $kirby->set('field', $name, $field->root()); - } - - // load all custom fields, which can overwrite all the others - foreach(dir::read(form::$root['custom']) as $name) { - $kirby->set('field', $name, form::$root['custom'] . DS . $name); - } - - } - - public function load() { - - $fields = kirby()->get('field'); - $classes = []; - - foreach($fields as $name => $field) { - $classes[$field->class()] = $field->file(); - } - - // start the autoloader - load($classes); - - foreach($fields as $name => $field) { - - $classname = $field->class(); - - if(!class_exists($classname)) { - throw new Exception('The field class is missing for: ' . $classname); - } - - if(method_exists($classname, 'setup')) { - call(array($classname, 'setup')); - } - - } - - } - - public function assets($type) { - - $output = []; - $defaultRoot = panel()->roots()->fields(); - - foreach(kirby()->get('field') as $name => $field) { - - $root = $field->root(); - $base = dirname($root); - - // only fetch assets for custom fields - if($base == $defaultRoot) { - continue; - } - - $classname = $field->class(); - - if(!class_exists($classname)) { - throw new Exception('The field class is missing for: ' . $classname); - } - - if(!isset($classname::$assets) || !isset($classname::$assets[$type])) { - continue; - } - - foreach($classname::$assets[$type] as $filename) { - $output[] = f::read($field->root() . DS . 'assets' . DS . $type . DS . $filename); - } - - } - - return implode(PHP_EOL . PHP_EOL, $output); - - } - - public function css() { - return $this->assets('css'); - } - - public function js() { - return $this->assets('js'); - } - -} diff --git a/panel/app/src/panel/installer.php b/panel/app/src/panel/installer.php deleted file mode 100644 index e0ca048..0000000 --- a/panel/app/src/panel/installer.php +++ /dev/null @@ -1,78 +0,0 @@ -users()->count() > 0 && is_writable(kirby()->roots()->accounts())); - } - - public function problems() { - - $checks = array('allowed', 'accounts', 'thumbs', 'blueprints', 'content', 'avatars'); - $problems = array(); - - foreach($checks as $c) { - $method = 'check' . $c; - - if(!$this->$method()) { - $problems[] = l('installation.check.error.' . $c); - } - - } - - return empty($problems) ? false : $problems; - - } - - protected function checkAllowed() { - return (panel()->isLocal() || kirby()->option('panel.install') === true); - } - - protected function checkAccounts() { - - $root = kirby()->roots()->accounts(); - - // try to create the accounts folder - dir::make($root); - - return is_writable($root); - - } - - protected function checkThumbs() { - - $root = kirby()->roots()->thumbs(); - - // try to create the thumbs folder - dir::make($root); - - return is_writable($root); - - } - - protected function checkBlueprints() { - return is_dir(kirby()->roots()->blueprints()); - } - - protected function checkContent() { - $folder = new Folder(kirby()->roots()->content()); - return $folder->isWritable(true); - } - - protected function checkAvatars() { - - $root = kirby()->roots()->avatars(); - - // try to create the avatars folder - dir::make($root); - - return is_writable($root); - - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/layout.php b/panel/app/src/panel/layout.php deleted file mode 100644 index 1aea276..0000000 --- a/panel/app/src/panel/layout.php +++ /dev/null @@ -1,14 +0,0 @@ -_root = panel::instance()->roots()->layouts(); - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/login.php b/panel/app/src/panel/login.php deleted file mode 100644 index 5f816e3..0000000 --- a/panel/app/src/panel/login.php +++ /dev/null @@ -1,246 +0,0 @@ -kirby = kirby(); - $this->logfile = $this->kirby->roots()->accounts() . DS . '.logins'; - - $this->setup(); - - } - - /** - * Setup and check the logfile - */ - protected function setup() { - - // make sure the logroot exists - if(!is_writable(dirname($this->logfile))) { - throw new Exception(l('users.form.error.permissions.title')); - } - - // create the logfile if not there yet - touch($this->logfile); - - // make sure the logroot exists - if(!is_writable($this->logfile)) { - throw new Exception(l('login.log.error.permissions')); - } - - } - - /** - * Run an attempt to login - * - * @param string $username - * @param string $password - */ - public function attempt($username, $password) { - - $this->username = str::lower($username); - $this->password = $password; - - try { - - if($this->isInvalidUsername() || $this->isInvalidPassword()) { - throw new Exception(l('login.error')); - } - - $user = $this->user(); - - if(!$user->login($this->password)) { - throw new Exception(l('login.error')); - } - - $this->clearLog($this->visitorId()); - return true; - - } catch(Exception $e) { - - $this->log(); - $this->pause(); - - throw $e; - - } - - } - - /** - * Checks if the login form can be - * bypassed, because the user is already - * authenticated - * - * @return boolean - */ - public function isAuthenticated() { - try { - panel()->user(); - return true; - } catch(Exception $e) { - return false; - } - } - - /** - * Checks if a brute force attack has - * probably been executed - * - * @return boolean - */ - public function isBlocked() { - return $this->attempts() > $this->maxUntrustedAttempts; - } - - /** - * Fetch the user for the entered username - * - * @return User - */ - protected function user() { - return panel()->user($this->username); - } - - /** - * Returns all logdata in an array - * - * @return array - */ - protected function logdata() { - if(!is_null($this->logdata)) { - return $this->logdata; - } else { - - $data = (array)data::read($this->logfile, 'json'); - $login = $this; - - // remove old entries - $data = array_filter($data, function($entry) use($login) { - return ($entry['time'] > (time() - $login->logexpiry)); - }); - - return $this->logdata = $data; - } - } - - /** - * Stores a new login attempt to - * make it trackable later - * - * The store contains a sha1 hash of the ip - * - * @return boolean - */ - protected function log() { - - // get the latest logdata - $data = $this->logdata(); - - // store a new attempt - $data[] = array( - 'time' => time(), - 'id' => $this->visitorId(), - ); - - // write it to the logfile - return data::write($this->logfile, $data, 'json'); - - } - - /** - * Return a hashed version of the visitor ip - * - * @return string - */ - protected function visitorId() { - return sha1(visitor::ip()); - } - - /** - * Returns the number of attempts for - * the current visitor - * - * @return int - */ - protected function attempts() { - - $data = $this->logdata(); - $login = $this; - $data = array_filter($data, function($entry) use($login) { - return $login->visitorId() === $entry['id']; - }); - - return count($data); - - } - - /** - * Checks if an invalid username has been entered - * - * @return boolean - */ - protected function isInvalidUsername() { - return !preg_match('!^[a-z0-9._-]{1,}$!', $this->username); - } - - /** - * Checks if an invalid password has been entered - * - * @return boolean - */ - protected function isInvalidPassword() { - return empty($this->password); - } - - /** - * Create a random pause between 0 and 3 - * seconds to make it harder for attackers - * to execute many sequent attacks - */ - protected function pause() { - sleep(rand(1, 3)); - } - - /** - * Delete log entries by visitor id - */ - protected function clearLog($id) { - - $data = array_filter($this->logdata(), function($entry) use($id) { - return $entry['id'] !== $id; - }); - - data::write($this->logfile, $data, 'json'); - - // reset the logdata cache - $this->logdata = null; - - return $this->logdata(); - - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/file.php b/panel/app/src/panel/models/file.php deleted file mode 100644 index 0974be6..0000000 --- a/panel/app/src/panel/models/file.php +++ /dev/null @@ -1,250 +0,0 @@ -page()->uri('file') . '/' . $this->encodedFilename() . '/' . $action; - } - } - - public function encodedFilename() { - if(php_sapi_name() == 'cli-server') { - $filename = str_replace('.', '․', $this->filename()); - } else { - $filename = $this->filename(); - } - return rawurlencode($filename); - } - - public static function decodeFilename($filename) { - $filename = rawurldecode($filename); - if(php_sapi_name() == 'cli-server') { - $filename = str_replace('․', '.', $filename); - } - return $filename; - } - - public function url($action = null) { - if(empty($action)) { - return parent::url(); - } else if($action == 'preview') { - return parent::url() . '?' . $this->modified(); - } else { - return panel()->urls()->index() . '/' . $this->uri($action); - } - } - - public function menu() { - return new Menu($this); - } - - public function form($action, $callback) { - return panel()->form('files/' . $action, $this, $callback); - } - - public function filterInput($input) { - return $input; - } - - public function getBlueprintFields() { - return $this->blueprint()->files()->fields($this); - } - - public function getFormFields() { - return $this->getBlueprintFields()->toArray(); - } - - public function getFormData() { - return $this->meta()->toArray(); - } - - public function canHavePreview() { - return $this->isWebImage() or $this->extension() == 'svg'; - } - - public function isWebImage() { - $images = array('image/jpeg', 'image/gif', 'image/png'); - return in_array($this->mime(), $images); - } - - public function canHaveThumb() { - if(!$this->isWebImage()) { - return false; - } else if(kirby()->option('thumbs.driver') == 'gd') { - if($this->width() > 2048 or $this->height() > 2048) { - return false; - } else { - return true; - } - } else { - return true; - } - } - - public function rename($name, $safeName = true) { - - // keep the old state of the file object - $old = clone $this; - - if($name == $this->name()) return true; - - // check if the name should be sanitized - $safeName = $this->page()->blueprint()->files()->sanitize(); - - // rename and get the new filename - $filename = parent::rename($name, $safeName); - - // clean the thumbs folder - $this->page()->removeThumbs(); - - // trigger the rename hook - kirby()->trigger('panel.file.rename', array($this, $old)); - - } - - public function update($data = array(), $sort = null, $trigger = true) { - - if($data == 'sort') { - parent::update(array('sort' => $sort)); - kirby()->trigger('panel.file.sort', $this); - return true; - } - - // rename the file if necessary - if(!empty($data['_name'])) { - $filename = $this->rename($data['_name']); - } - - // remove the name url and info - unset($data['_name']); - unset($data['_info']); - unset($data['_link']); - - if(!empty($data)) { - parent::update($data); - } - - if($trigger) { - kirby()->trigger('panel.file.update', $this); - } - - } - - public function replace() { - new Uploader($this->page, $this); - } - - public function delete() { - - parent::delete(); - - // clean the thumbs folder - $this->page()->removeThumbs(); - - kirby()->trigger('panel.file.delete', $this); - - } - - public function icon($position = 'left') { - - switch($this->type()) { - case 'image': - return icon('file-image-o', $position); - break; - case 'document': - switch($this->extension()) { - case 'pdf': - return icon('file-pdf-o', $position); - break; - case 'doc': - case 'docx': - return icon('file-word-o', $position); - break; - case 'xls': - return icon('file-excel-o', $position); - break; - default: - return icon('file-text-o', $position); - break; - } - break; - case 'code': - return icon('file-code-o', $position); - break; - case 'audio': - return icon('file-audio-o', $position); - break; - case 'video': - return icon('file-video-o', $position); - break; - default: - return icon('file-archive-o', $position); - break; - } - - } - - public function dragText() { - if(kirby()->option('panel.kirbytext') === false) { - switch($this->type()) { - case 'image': - return '![' . $this->name() . '](' . parent::url() . ')'; - break; - default: - return '[' . $this->filename() . '](' . parent::url() . ')'; - break; - } - } else { - switch($this->type()) { - case 'image': - return '(image: ' . $this->filename() . ')'; - break; - default: - return '(file: ' . $this->filename() . ')'; - break; - } - } - } - - public function topbar($topbar) { - - $this->files()->topbar($topbar); - - $topbar->append($this->url('edit'), $this->filename()); - - } - - public function createMeta($triggerUpdateHook = true) { - - // save default meta - $meta = array(); - - foreach($this->page()->blueprint()->files()->fields($this) as $field) { - $meta[$field->name()] = $field->default(); - } - - $this->update($meta, null, $triggerUpdateHook); - - return $this; - - } - - public function blueprint() { - return $this->page->blueprint(); - } - - public function structure() { - return new Structure($this, 'file_' . $this->page()->id() . '_' . $this->filename() . '_' . $this->site()->lang()); - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/file/menu.php b/panel/app/src/panel/models/file/menu.php deleted file mode 100644 index b6a6bf1..0000000 --- a/panel/app/src/panel/models/file/menu.php +++ /dev/null @@ -1,69 +0,0 @@ -page = $file->page(); - $this->file = $file; - } - - public function item($icon, $label, $attr = array()) { - - $a = new Brick('a', '', $attr); - $a->append(icon($icon, 'left')); - $a->append(l($label)); - - $li = new Brick('li'); - $li->append($a); - - return $li; - - } - - public function previewOption() { - return $this->item('play-circle-o', 'files.show.open', array( - 'href' => $this->file->url('preview'), - 'target' => '_blank' - )); - } - - public function editOption() { - return $this->item('pencil', 'files.index.edit', array( - 'href' => $this->file->url('edit'), - )); - } - - public function deleteOption() { - return $this->item('trash-o', 'files.show.delete', array( - 'href' => $this->file->url('delete'), - 'data-modal' => true, - )); - } - - public function html() { - - $list = new Brick('ul'); - $list->addClass('nav nav-list'); - $list->addClass('dropdown-list'); - - $list->append($this->previewOption()); - $list->append($this->editOption()); - $list->append($this->deleteOption()); - - return ''; - - } - - public function __toString() { - return (string)$this->html(); - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/page.php b/panel/app/src/panel/models/page.php deleted file mode 100644 index 1be4764..0000000 --- a/panel/app/src/panel/models/page.php +++ /dev/null @@ -1,644 +0,0 @@ -cache['blueprint'])) return $this->cache['blueprint']; - - $blueprint = $this->intendedTemplate(); - - if(!Blueprint::exists($blueprint)) { - $blueprint = $this->template(); - } - - return $this->cache['blueprint'] = new Blueprint($blueprint); - - } - - public function createNum($to = null) { - - $parent = $this->parent(); - $params = $parent->blueprint()->pages()->num(); - - switch($params->mode()) { - case 'zero': - return 0; - break; - case 'date': - if($to = $this->date($params->format(), $params->field())) { - return $to; - } else { - return date($params->format()); - } - break; - default: - - $visibleSiblings = $parent->children()->visible(); - - if($to == 'last') { - $to = $visibleSiblings->count() + 1; - } else if($to == 'first') { - $to = 1; - } else if(is_null($to)) { - $to = $this->num(); - } - - if(!v::num($to)) return false; - - if($to <= 0) return 1; - - if($this->isInvisible()) { - $limit = $visibleSiblings->count() + 1; - } else { - $limit = $visibleSiblings->count(); - } - - if($limit < $to) { - $to = $limit; - } - - return intval($to); - break; - } - - } - - public function uri($action = null) { - if(empty($action)) { - return parent::uri(); - } else { - return 'pages/' . $this->id() . '/' . $action; - } - } - - public function url($action = null) { - if(empty($action)) { - return parent::url(); - } else if($action == 'preview') { - if($previewSetting = $this->blueprint()->preview()) { - switch($previewSetting) { - case 'parent': - return $this->parent() ? $this->parent()->url() : $this->url(); - break; - case 'first-child': - return $this->children()->first() ? $this->children()->first()->url() : false; - break; - case 'last-child': - return $this->children()->last() ? $this->children()->last()->url() : false; - break; - default: - return $this->url(); - break; - } - } else { - return false; - } - } else if($this->site->multilang() and $lang = $this->site->language($action)) { - return parent::url($lang->code()); - } else { - return panel()->urls()->index() . '/' . $this->uri($action); - } - } - - public function form($action, $callback) { - return panel()->form('pages/' . $action, $this, $callback); - } - - public function structure() { - return new Structure($this, 'page_' . $this->id() . '_' . $this->site->lang()); - } - - public function getFormData() { - - // get the latest content from the text file - $data = $this->content()->toArray(); - - // make sure the title is always there - $data['title'] = $this->title(); - - // add the changes to the content array - $data = array_merge($data, $this->changes()->get()); - - return $data; - - } - - public function getBlueprintFields() { - return $this->blueprint()->fields($this); - } - - public function getFormFields() { - - $fields = $this->getBlueprintFields()->toArray(); - - // add the title as hidden field - if(!isset($fields['title'])) { - $fields['title'] = array( - 'type' => 'hidden', - 'name' => 'title' - ); - } else { - // make sure the title field always has the type title - $fields['title']['type'] = 'title'; - } - - return $fields; - - } - - public function children() { - return new Children($this); - } - - public function canSortFiles() { - return $this->blueprint()->files()->sortable(); - } - - public function files() { - return new Files($this); - } - - public function addButton() { - try { - return new AddButton($this); - } catch(Exception $e) { - return false; - } - } - - public function menu($position = 'sidebar') { - return new Menu($this, $position); - } - - public function filterInput($input) { - return $input; - } - - public function changes() { - return new Changes($this); - } - - public function maxSubpages() { - $max = $this->blueprint()->pages()->max(); - // if max subpages is null, use the biggest 32bit integer - // will never be reached anyway. Kirby is not made for that scale :) - return is_null($max) ? 2147483647 : $max; - } - - public function maxFiles() { - $max = $this->blueprint()->files()->max(); - // see: maxSubpages - return is_null($max) ? 2147483647 : $max; - } - - public function canHaveSubpages() { - return $this->maxSubpages() !== 0; - } - - public function canShowSubpages() { - return ($this->blueprint()->pages()->hide() !== true and $this->canHaveSubpages()); - } - - public function canHaveFiles() { - return $this->maxFiles() !== 0; - } - - public function canShowFiles() { - return ($this->blueprint()->files()->hide() !== true and $this->canHaveFiles()); - } - - public function canHaveMoreSubpages() { - if(!$this->canHaveSubpages()) { - return false; - } else if($this->children()->count() >= $this->maxSubpages()) { - return false; - } else { - return true; - } - } - - public function canHaveMoreFiles() { - if(!$this->canHaveFiles()) { - return false; - } else if($this->files()->count() >= $this->maxFiles()) { - return false; - } else { - return true; - } - } - - public function canShowPreview() { - return $this->blueprint()->options()->preview(); - } - - public function canChangeStatus() { - return (!$this->isErrorPage() and $this->blueprint()->options()->status()) ? true : false; - } - - public function canChangeUrl() { - if($this->isHomePage() or $this->isErrorPage() or $this->blueprint()->options()->url() === false) { - return false; - } else { - return true; - } - } - - public function canChangeTemplate() { - if($this->isHomePage() or $this->isErrorPage() or $this->blueprint()->options()->template() === false) { - return false; - } else { - return $this->parent()->blueprint()->pages()->template()->count() > 1; - } - } - - public function move($uid) { - - $old = clone($this); - - if(!$this->canChangeUrl()) { - throw new Exception(l('pages.url.error.rights')); - } - - $site = panel()->site(); - $changes = $this->changes()->get(); - - $this->changes()->discard(); - - if($site->multilang() and $site->language()->code() != $site->defaultLanguage()->code()) { - parent::update(array( - 'URL-Key' => $uid - )); - } else { - parent::move($uid); - } - - $this->changes()->update($changes); - - // remove all thumbs for the old id - $old->removeThumbs(); - - // hit the hook - kirby()->trigger('panel.page.move', array($this, $old)); - - } - - public function _sort($to) { - if(is_dir($this->root())) { - return parent::sort($to); - } else { - return false; - } - } - - public function sort($to = null) { - - if($this->isErrorPage()) { - return $this->num(); - } - - // don't sort pages without permission to change the status - if($this->isInvisible() && !$this->canChangeStatus()) { - return false; - } - - // store the old number - $oldNum = $this->num(); - - // run the sorter - $this->sorter()->to($to); - - // run the hook if the number changed - if($oldNum != $this->num()) { - // hit the hook - kirby()->trigger('panel.page.sort', $this); - } - - return $this->num(); - - } - - public function sorter() { - return new Sorter($this); - } - - public function hide() { - - // don't hide pages, which are not allowed to change their status - if(!$this->canChangeStatus()) { - return false; - } - - parent::hide(); - $this->sorter()->hide(); - kirby()->trigger('panel.page.hide', $this); - - } - - public function toggle($position) { - - $mode = $this->parent()->blueprint()->pages()->num()->mode(); - $position = intval($position); - - if(($mode == 'default' && $position > 0) || !$this->isVisible()) { - $this->sort($position); - } else { - $this->hide(); - } - - } - - public function hasNoTitleField() { - $fields = $this->getFormFields(); - return empty($fields['title']); - } - - public function isHidden() { - return $this->blueprint()->hide() === true; - } - - public function isDeletable($exception = false) { - - if($this->isHomePage()) { - $error = 'pages.delete.error.home'; - } else if($this->isErrorPage()) { - $error = 'pages.delete.error.error'; - } else if($this->hasChildren()) { - $error = 'pages.delete.error.children'; - } else if(!$this->blueprint()->deletable() or !$this->blueprint()->options()->delete()) { - $error = 'pages.delete.error.blocked'; - } else { - return true; - } - - if($exception) { - throw new Exception($error); - } else { - return false; - } - - } - - public function sidebar() { - return new Sidebar($this); - } - - public function addToHistory() { - panel()->user()->history()->add($this); - } - - public function updateNum() { - - // make sure that the sorting number is correct - if($this->isVisible()) { - $this->sort($this->num()); - } - - return $this->num(); - - } - - public function updateUid() { - - // auto-update the uid if the sorting mode is set to zero - if($this->parent()->blueprint()->pages()->num()->mode() == 'zero') { - $uid = str::slug($this->title()); - $this->move($uid); - } - return $this->uid(); - - } - - public function update($data = array(), $lang = null) { - - $this->changes()->discard(); - - parent::update($data, $lang); - - // update the number if the date field - // changed for example - $this->updateNum(); - - kirby()->trigger('panel.page.update', $this); - - // add the page to the history - $this->addToHistory(); - - } - - public function upload() { - new Uploader($this); - } - - public function delete($force = false) { - - // delete the page - parent::delete(); - - // resort the siblings - $this->sorter()->delete(); - - // remove unsaved changes - $this->changes()->discard(); - - // delete all associated thumbs - $this->removeThumbs(); - - // hit the hook - kirby()->trigger('panel.page.delete', $this); - - } - - public function icon($position = 'left') { - return icon($this->blueprint()->icon(), $position); - } - - public function dragText() { - if(c::get('panel.kirbytext') === false) { - return '[' . $this->title() . '](' . $this->url() . ')'; - } else { - return '(link: ' . $this->uri() . ' text: ' . $this->title() . ')'; - } - } - - public function displayNum() { - - if($this->isInvisible()) { - return '—'; - } else { - - $numberSettings = $this->parent()->blueprint()->pages()->num(); - - switch($numberSettings->mode()) { - case 'zero': - if($numberSettings->display()) { - // customer number display - return $this->{$numberSettings->display()}(); - } else { - // alphabetic display numbers - return str::substr($this->title(), 0, 1); - } - break; - case 'date': - return $this->date($numberSettings->display(), $numberSettings->field()); - break; - default: - if($numberSettings->display()) { - // customer number display - return $this->{$numberSettings->display()}(); - } else { - // regular number display - return intval($this->num()); - } - break; - } - - } - - } - - public function topbar(Topbar $topbar) { - - foreach($this->parents()->flip() as $item) { - $topbar->append($item->url('edit'), $item->title()); - } - - $topbar->append($this->url('edit'), $this->title()); - - if($topbar->view == 'subpages/index') { - $topbar->append($this->url('subpages'), l('subpages')); - } - - $topbar->html .= new Snippet('languages', array( - 'languages' => $this->site()->languages(), - 'language' => $this->site()->language(), - )); - - } - - public function changeTemplate($newTemplate) { - - $oldTemplate = $this->intendedTemplate(); - - if($newTemplate == $oldTemplate) return true; - - if($this->site()->multilang()) { - - foreach($this->site()->languages() as $lang) { - $old = $this->textfile(null, $lang->code()); - $new = $this->textfile($newTemplate, $lang->code()); - f::move($old, $new); - $this->reset(); - $this->updateForNewTemplate($oldTemplate, $newTemplate, $lang->code()); - } - - } else { - $old = $this->textfile(); - $new = $this->textfile($newTemplate); - f::move($old, $new); - $this->reset(); - $this->updateForNewTemplate($oldTemplate, $newTemplate); - } - - return true; - - } - - public function prepareForNewTemplate($oldTemplate, $newTemplate, $language = null) { - - $data = array(); - $incompatible = array(); - $content = $this->content($language); - $oldBlueprint = new Blueprint($oldTemplate); - $oldFields = $oldBlueprint->fields($this); - $newBlueprint = new Blueprint($newTemplate); - $newFields = $newBlueprint->fields($this); - - // log - $removed = array(); - $replaced = array(); - $added = array(); - - // first overwrite everything - foreach($oldFields as $oldField) { - $data[$oldField->name()] = null; - } - - // now go through all new fileds and compare them to the old field types - foreach($newFields as $newField) { - - $oldField = $oldFields->{$newField->name()}; - - // only take data from fields with matching names and types - if($oldField and $oldField->type() == $newField->type()) { - $data[$newField->name()] = $content->get($newField->name())->value(); - } else { - $data[$newField->name()] = $newField->default(); - - if($oldField) { - $replaced[$newField->name()] = $newField->label(); - } else { - $added[$newField->name()] = $newField->label(); - } - - } - - } - - foreach($data as $name => $content) { - if(is_null($content)) $removed[$name] = $oldFields->{$name}->label(); - } - - return array( - 'data' => $data, - 'removed' => $removed, - 'replaced' => $replaced, - 'added' => $added - ); - - } - - public function updateForNewTemplate($oldTemplate, $newTemplate, $language = null) { - $prep = $this->prepareForNewTemplate($oldTemplate, $newTemplate, $language); - $this->update($prep['data'], $language); - } - - /** - * Clean the thumbs folder for the page - * - */ - public function removeThumbs() { - return dir::remove($this->kirby()->roots()->thumbs() . DS . $this->id()); - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/page/addbutton.php b/panel/app/src/panel/models/page/addbutton.php deleted file mode 100644 index e66b1e8..0000000 --- a/panel/app/src/panel/models/page/addbutton.php +++ /dev/null @@ -1,21 +0,0 @@ -page = $page; - $this->modal = true; - $this->url = $this->page->url('add'); - - if(!$this->page->canHaveMoreSubpages()) { - throw new Exception(l('subpages.add.error.more')); - } - - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/page/blueprint.php b/panel/app/src/panel/models/page/blueprint.php deleted file mode 100644 index e988d37..0000000 --- a/panel/app/src/panel/models/page/blueprint.php +++ /dev/null @@ -1,126 +0,0 @@ -load($name); - - $this->title = a::get($this->yaml, 'title', 'Page'); - $this->preview = a::get($this->yaml, 'preview', 'page'); - $this->deletable = a::get($this->yaml, 'deletable', true); - $this->icon = a::get($this->yaml, 'icon', 'file-o'); - $this->hide = a::get($this->yaml, 'hide', false); - $this->type = a::get($this->yaml, 'type', 'page'); - $this->pages = new Pages(a::get($this->yaml, 'pages', true)); - $this->files = new Files(a::get($this->yaml, 'files', true)); - $this->options = new Options(a::get($this->yaml, 'options', array())); - - } - - public function load($name) { - - // make sure there's no path included in the name - $name = basename(strtolower($name)); - - if(isset(static::$cache[$name])) { - $this->file = static::$cache[$name]['file']; - $this->name = static::$cache[$name]['name']; - $this->yaml = static::$cache[$name]['yaml']; - return true; - } - - // find the matching blueprint file - $file = kirby()->get('blueprint', $name); - - if($file) { - - $this->file = $file; - $this->name = $name; - $this->yaml = data::read($this->file, 'yaml'); - - // remove the broken first line - unset($this->yaml[0]); - - static::$cache[$name] = array( - 'file' => $this->file, - 'name' => $this->name, - 'yaml' => $this->yaml - ); - - return true; - - } else if($name == 'default') { - throw new Exception(l('blueprints.error.default.missing')); - } else { - return $this->load('default'); - } - - } - - public function fields($model) { - $fields = a::get($this->yaml, 'fields', array()); - return new Fields($fields, $model); - } - - static public function exists($name) { - return kirby()->get('blueprint', $name) ? true : false; - } - - static public function all() { - - $files = dir::read(static::$root); - $result = array_keys(kirby()->get('blueprint')); - $home = kirby()->option('home', 'home'); - $error = kirby()->option('error', 'error'); - - foreach($files as $file) { - - $name = f::name($file); - - if($name != 'site' and $name != $home and $name != $error) { - $result[] = $name; - } - - } - - return $result; - - } - - public function __toString() { - return $this->name; - } - -} diff --git a/panel/app/src/panel/models/page/blueprint/field.php b/panel/app/src/panel/models/page/blueprint/field.php deleted file mode 100644 index 6bbd828..0000000 --- a/panel/app/src/panel/models/page/blueprint/field.php +++ /dev/null @@ -1,115 +0,0 @@ -_extend($params); - } - - if(a::get($params, 'name') == 'title') { - $params['type'] = 'title'; - - if(!isset($params['required'])) { - $params['required'] = true; - } - } - - if(empty($params['type'])) { - $params['type'] = 'text'; - } - - // lowercase the type - $params['type'] = strtolower($params['type']); - - // register the parent model - $params['model'] = $model; - - // try to fetch the parent page from the model - if(is_a($model, 'Page')) { - $params['page'] = $model; - } else if(is_a($model, 'File')) { - $params['page'] = $model->page(); - } - - // create the default value - $params['default'] = $this->_default(a::get($params, 'default')); - - parent::__construct($params); - - } - - - public function _extend($params) { - - $extends = $params['extends']; - $snippet = f::resolve(kirby()->roots()->blueprints() . DS . 'fields' . DS . $extends, array('yml', 'php', 'yaml')); - - if(empty($snippet)) { - throw new Exception(l('fields.error.extended')); - } - - $yaml = data::read($snippet, 'yaml'); - $params = a::merge($yaml, $params); - - return $params; - - } - - public function _default($default) { - - if($default === true) { - return 'true'; - } else if($default === false) { - return 'false'; - } else if(empty($default) and strlen($default) == 0) { - return ''; - } else if(is_string($default)) { - return $default; - } else { - $type = a::get($default, 'type'); - - switch($type) { - case 'date': - $format = a::get($default, 'format', 'Y-m-d'); - return date($format); - break; - case 'datetime': - $format = a::get($default, 'format', 'Y-m-d H:i:s'); - return date($format); - break; - case 'user': - $user = isset($default['user']) ? site()->users()->find($default['user']) : site()->user(); - if(!$user) return ''; - return (isset($default['field']) and $default['field'] != 'password') ? $user->{$default['field']}() : $user->username(); - break; - case 'structure': - return "\n" . \data::encode(array($default), 'yaml') . "\n"; - break; - default: - return $default; - break; - } - - } - - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/page/blueprint/fields.php b/panel/app/src/panel/models/page/blueprint/fields.php deleted file mode 100644 index e334a0a..0000000 --- a/panel/app/src/panel/models/page/blueprint/fields.php +++ /dev/null @@ -1,48 +0,0 @@ - $field) { - - // sanitize the name - $name = str_replace('-','_', str::lower($name)); - - // import a field by name - if(is_string($field)) { - $field = array( - 'name' => $name, - 'extends' => $field - ); - } - - // add the name to the field - $field['name'] = $name; - - // create the field object - $field = new Field($field, $model); - - // append it to the collection - $this->append($name, $field); - - } - - } - - public function toArray($callback = null) { - $result = array(); - foreach($this->data as $field) { - $result[$field->name()] = $field->toArray(); - } - return $result; - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/page/blueprint/files.php b/panel/app/src/panel/models/page/blueprint/files.php deleted file mode 100644 index 02385a9..0000000 --- a/panel/app/src/panel/models/page/blueprint/files.php +++ /dev/null @@ -1,57 +0,0 @@ -params = $params; - - if($params === false) { - $this->fields = array(); - $this->type = array(); - $this->size = false; - $this->width = false; - $this->height = false; - $this->max = 0; - $this->hide = true; - $this->sortable = false; - - } else if(is_array($params)) { - $this->fields = a::get($params, 'fields', $this->fields); - $this->type = a::get($params, 'type', $this->type); - if (!is_array($this->type)) - $this->type = array($this->type); - $this->size = a::get($params, 'size', $this->size); - $this->width = a::get($params, 'width', $this->width); - $this->height = a::get($params, 'height', $this->height); - $this->max = a::get($params, 'max', $this->max); - $this->hide = a::get($params, 'hide', $this->hide); - $this->sort = a::get($params, 'sort', $this->sort); - $this->sortable = a::get($params, 'sortable', $this->sortable); - $this->sanitize = a::get($params, 'sanitize', true); - } - - } - - public function fields($file) { - return new Fields($this->fields, $file); - } - -} diff --git a/panel/app/src/panel/models/page/blueprint/options.php b/panel/app/src/panel/models/page/blueprint/options.php deleted file mode 100644 index 305c96e..0000000 --- a/panel/app/src/panel/models/page/blueprint/options.php +++ /dev/null @@ -1,46 +0,0 @@ -preview = a::get($options, 'preview', true); - $this->status = a::get($options, 'status', true); - $this->template = a::get($options, 'template', true); - $this->url = a::get($options, 'url', true); - $this->delete = a::get($options, 'delete', true); - } - - public function preview() { - return $this->preview; - } - - public function status() { - return $this->status; - } - - public function template() { - return $this->template; - } - - public function url() { - return $this->url; - } - - public function delete() { - return $this->delete; - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/page/blueprint/pages.php b/panel/app/src/panel/models/page/blueprint/pages.php deleted file mode 100644 index 9540c0e..0000000 --- a/panel/app/src/panel/models/page/blueprint/pages.php +++ /dev/null @@ -1,96 +0,0 @@ -template = blueprint::all(); - } else if($params === false) { - $this->limit = 0; - $this->max = 0; - $this->sortable = false; - $this->hide = true; - } else if(is_array($params)) { - $template = a::get($params, 'template'); - if($template == false) { - $this->template = blueprint::all(); - } else if(is_array($template)) { - $this->template = $template; - } else { - $this->template = array($template); - } - $this->sort = a::get($params, 'sort', $this->sort); - $this->sortable = a::get($params, 'sortable', $this->sortable); - $this->limit = a::get($params, 'limit', $this->limit); - $this->num = a::get($params, 'num', $this->num); - $this->max = a::get($params, 'max', $this->max); - $this->hide = a::get($params, 'hide', $this->hide); - $this->build = a::get($params, 'build', $this->build); - } else if(is_string($params)) { - $this->template = array($params); - } - - } - - public function template() { - $result = array(); - foreach($this->template as $t) { - $result[$t] = new Blueprint($t); - } - return new Collection($result); - } - - public function num() { - - $obj = new Obj(); - - $obj->mode = 'default'; - $obj->field = null; - $obj->format = null; - $obj->display = null; - - if(is_array($this->num)) { - foreach($this->num as $k => $v) $obj->$k = $v; - } else if(!empty($this->num)) { - $obj->mode = $this->num; - } - - switch($obj->mode) { - case 'field': - isset($obj->field) or $obj->field = 'num'; - break; - case 'date': - // switch the default date format by configured handler - $defaultDateFormat = kirby()->option('date.handler') == 'strftime' ? '%Y%m%d' : 'Ymd'; - $defaultDisplayFormat = kirby()->option('date.handler') == 'strftime' ? '%Y/%m/%d' : 'Y/m/d'; - - // set the defaults - isset($obj->field) or $obj->field = 'date'; - isset($obj->format) or $obj->format = $defaultDateFormat; - isset($obj->display) or $obj->display = $defaultDisplayFormat; - break; - } - - return $obj; - - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/page/changes.php b/panel/app/src/panel/models/page/changes.php deleted file mode 100644 index bae4bd2..0000000 --- a/panel/app/src/panel/models/page/changes.php +++ /dev/null @@ -1,121 +0,0 @@ -model = $model; - } - - public function data() { - return s::get('changes', array()); - } - - public function id() { - $site = panel()->site(); - if($site->multilang()) { - return $site->language()->code() . '-' . sha1($this->model->id()); - } else { - return sha1($this->model->id()); - } - } - - public function keep() { - - $blueprint = $this->model->blueprint(); - $fields = $blueprint->fields($this->model); - $form = new Form($fields->toArray()); - $data = $this->model->filterInput($form->serialize()); - $old = $this->model->content()->toArray(); - - if($data != $old) { - $this->update($data); - } - - } - - public function discard($field = null) { - - $store = $this->data(); - - if(is_null($field)) { - unset($store[$this->id()]); - } else { - unset($store[$this->id()][$field]); - } - - s::set('changes', $store); - - // remove all structures from the session as well - $this->model->structure()->reset(); - - return $store; - - } - - public function differ() { - - $data = $this->get(); - $changes = false; - - foreach($data as $field => $value) { - - $object = $this->model->{$field}(); - - if(!method_exists($object, '__toString')) { - continue; - } - - if((string)$object !== $value) { - $changes = true; - } - - } - - return $changes; - - } - - public function get($field = null) { - - $data = (array)a::get($this->data(), $this->id()); - - if(!is_null($field)) { - return a::get($data, $field); - } else { - return $data; - } - - } - - public function update($field, $data = null) { - - if(is_null($data) and is_array($field)) { - $store = $this->data(); - $store[$this->id()] = $field; - } else if(is_string($field)) { - $store = $this->data(); - if(!isset($store[$this->id()]) or !is_array($store[$this->id()])) { - $store[$this->id()] = array(); - } - $store[$this->id()][$field] = $data; - } - - s::set('changes', $store); - return $store; - - } - - public function flush() { - s::set('changes', array()); - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/page/menu.php b/panel/app/src/panel/models/page/menu.php deleted file mode 100644 index 692d523..0000000 --- a/panel/app/src/panel/models/page/menu.php +++ /dev/null @@ -1,166 +0,0 @@ -page = $page; - $this->parent = $page->parent(); - $this->blueprint = $page->blueprint(); - $this->position = $position; - } - - public function item($icon, $label, $attr = array()) { - - $a = new Brick('a', '', $attr); - $a->append(icon($icon, 'left')); - $a->append(l($label) ?: $label); - - $li = new Brick('li'); - $li->append($a); - - return $li; - - } - - public function modalUrl($action) { - - if($this->position == 'context') { - if($this->parent->isSite()) { - $redirect = '/'; - } else { - $redirect = $this->parent->uri('edit'); - } - return $this->page->url($action) . '?_redirect=' . $redirect; - } else { - return $this->page->url($action); - } - - } - - public function previewOption() { - if($preview = $this->page->url('preview') and $this->page->canShowPreview()) { - return $this->item('play-circle-o', 'pages.show.preview', array( - 'href' => $preview, - 'target' => '_blank', - 'title' => 'p', - 'data-shortcut' => 'p', - )); - } else { - return false; - } - } - - public function editOption() { - if($this->position == 'context') { - return $this->item('pencil', 'pages.show.subpages.edit', array( - 'href' => $this->page->url('edit'), - )); - } - } - - public function statusOption() { - - if($this->page->canChangeStatus()) { - - if($this->page->isInvisible()) { - $icon = 'toggle-off'; - $label = 'pages.show.invisible'; - } else { - $icon = 'toggle-on'; - $label = 'pages.show.visible'; - } - - return $this->item($icon, $label, array( - 'href' => $this->modalUrl('toggle'), - 'data-modal' => true, - )); - - } else { - return false; - } - - } - - public function templateOption() { - if($this->page->canChangeTemplate()) { - return $this->item('file-code-o', l('pages.show.template') . ': ' . i18n($this->page->blueprint()->title()), array( - 'href' => $this->modalUrl('template'), - 'data-modal' => true, - 'data-shortcut' => 't', - )); - } else { - return false; - } - } - - public function urlOption() { - if($this->page->canChangeUrl()) { - return $this->item('chain', 'pages.show.changeurl', array( - 'href' => $this->modalUrl('url'), - 'title' => 'u', - 'data-shortcut' => 'u', - 'data-modal' => true, - )); - } else { - return false; - } - } - - public function deleteOption() { - if($this->page->isDeletable()) { - return $this->item('trash-o', 'pages.show.delete', array( - 'href' => $this->modalUrl('delete'), - 'title' => '#', - 'data-shortcut' => '#', - 'data-modal' => true, - )); - } else { - return false; - } - } - - public function html() { - - $list = new Brick('ul'); - $list->addClass('nav nav-list'); - - if($this->position == 'sidebar') { - $list->addClass('sidebar-list'); - } else { - $list->addClass('dropdown-list'); - } - - $list->append($this->previewOption()); - $list->append($this->editOption()); - $list->append($this->statusOption()); - $list->append($this->templateOption()); - $list->append($this->urlOption()); - $list->append($this->deleteOption()); - - if($this->position == 'context') { - return ''; - } else { - return $list; - } - - } - - public function __toString() { - try { - return (string)$this->html(); - } catch(Exception $e) { - return (string)$e->getMessage(); - } - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/page/sidebar.php b/panel/app/src/panel/models/page/sidebar.php deleted file mode 100644 index 4e6dee2..0000000 --- a/panel/app/src/panel/models/page/sidebar.php +++ /dev/null @@ -1,78 +0,0 @@ -page = $page; - $this->blueprint = $page->blueprint(); - } - - public function subpages() { - - if(!$this->page->canShowSubpages()) { - return null; - } - - // fetch all subpages in the right order - $children = $this->page->children()->paginated('sidebar'); - - // create the pagination snippet - $pagination = new Snippet('pagination', array( - 'pagination' => $children->pagination(), - 'nextUrl' => $children->pagination()->nextPageUrl(), - 'prevUrl' => $children->pagination()->prevPageUrl(), - )); - - // create the snippet and fill it with all data - return new Snippet('pages/sidebar/subpages', array( - 'title' => l('pages.show.subpages.title'), - 'page' => $this->page, - 'subpages' => $children, - 'addbutton' => $this->page->addButton(), - 'pagination' => $pagination, - )); - - } - - public function files() { - - if(!$this->page->canShowFiles()) { - return null; - } - - return new Snippet('pages/sidebar/files', array( - 'page' => $this->page, - 'files' => $this->page->files(), - )); - - } - - public function render() { - - // create the monster sidebar - return new Snippet('pages/sidebar', array( - 'page' => $this->page, - 'menu' => $this->page->menu('sidebar'), - 'subpages' => $this->subpages(), - 'files' => $this->files(), - )); - - } - - public function __toString() { - try { - return (string)$this->render(); - } catch(Exception $e) { - return $e->getMessage(); - } - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/page/sorter.php b/panel/app/src/panel/models/page/sorter.php deleted file mode 100644 index a2aa0f0..0000000 --- a/panel/app/src/panel/models/page/sorter.php +++ /dev/null @@ -1,123 +0,0 @@ -page = $page; - $this->parent = $page->parent(); - $this->params = $this->parent->blueprint()->pages()->num(); - $this->siblings = $this->parent->children()->visible(); - - } - - protected function execute() { - - switch($this->params->mode()) { - case 'date': - $this->date(); - break; - case 'zero': - $this->zero(); - break; - default: - $this->num(); - break; - } - - } - - protected function zero() { - foreach($this->siblings as $sibling) { - $sibling->_sort(0); - } - } - - protected function date() { - - foreach($this->siblings as $sibling) { - - // get the date - $date = $sibling->date($this->params->format(), $this->params->field()); - - // take the current date if the date is missing - if(!$date) { - $handler = kirby()->option('date.handler'); - $date = $handler($this->params->format()); - } - - $sibling->_sort($date); - - } - - } - - protected function num() { - - // make sure the siblings are sorted correctly - $this->siblings = $this->siblings->not($this->page)->sortBy('num', 'asc'); - - // special keywords and sanitization - if($this->to == 'last') { - $this->to = $this->siblings->count() + 1; - } else if($this->to == 'first') { - $this->to = 1; - } else if($this->to === false) { - $this->to = false; - } else if($this->to < 1) { - $this->to = 1; - } - - // start the index - $n = 0; - - if($this->to === false) { - foreach($this->siblings as $sibling) { - $n++; $sibling->_sort($n); - } - } else { - - // go through all items before the selected page - foreach($this->siblings->slice(0, $this->to - 1) as $sibling) { - $n++; $sibling->_sort($n); - } - - // add the selected page - $n++; $this->page->_sort($n); - - // go through all the items after the selected page - foreach($this->siblings->slice($this->to - 1) as $sibling) { - $n++; $sibling->_sort($n); - } - - } - - } - - public function to($to) { - $this->siblings->data[$this->page->id()] = $this->page; - $this->to = $to; - $this->execute(); - } - - public function delete() { - $this->siblings = $this->siblings->not($this->page); - $this->to = false; - $this->execute(); - } - - public function hide() { - $this->siblings = $this->siblings->not($this->page); - $this->to = false; - $this->execute(); - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/page/uploader.php b/panel/app/src/panel/models/page/uploader.php deleted file mode 100644 index 09da27d..0000000 --- a/panel/app/src/panel/models/page/uploader.php +++ /dev/null @@ -1,188 +0,0 @@ -page = $page; - $this->file = $file; - $this->blueprint = $page->blueprint(); - $this->filename = $this->blueprint->files()->sanitize() ? '{safeFilename}' : '{filename}'; - - if($this->file) { - $this->replace(); - } else { - $this->upload(); - } - - } - - public function upload() { - - // check if more files can be uploaded for the page - if(!$this->page->canHaveMoreFiles()) { - throw new Exception(l('files.add.error.max')); - } - - $upload = new Upload($this->page->root() . DS . $this->filename, array( - 'overwrite' => true, - 'accept' => function($file) { - - $callback = kirby()->option('panel.upload.accept'); - - if(is_callable($callback)) { - return call($callback, $file); - } else { - return true; - } - - } - )); - - $file = $this->move($upload); - - // create the initial meta file - // without triggering the update hook - $file->createMeta(false); - - // make sure that the file is being marked as updated - touch($file->root()); - - // clean the thumbs folder - $this->page->removeThumbs(); - - kirby()->trigger('panel.file.upload', $file); - - } - - public function replace() { - - $file = $this->file; - $upload = new Upload($file->root(), array( - 'overwrite' => true, - 'accept' => function($upload) use($file) { - if($upload->mime() != $file->mime()) { - throw new Error(l('files.replace.error.type')); - } - } - )); - - $file = $this->move($upload); - - // make sure that the file is being marked as updated - touch($file->root()); - - // clean the thumbs folder - $this->page->removeThumbs(); - - kirby()->trigger('panel.file.replace', $file); - - } - - public function move($upload) { - - // flush all cached files - $this->page->reset(); - - // get the file object from the upload - $uploaded = $upload->file(); - - // check if the upload worked - if(!$uploaded) { - throw new Exception($upload->error()->getMessage()); - } - - // check if the page has such a file - $file = $this->page->file($uploaded->filename()); - - // delete the upload if something went wrong - if(!$file) { - $uploaded->delete(); - throw new Exception(l('files.error.missing.file')); - } - - try { - // security checks - $this->checkUpload($file); - return $file; - } catch(Exception $e) { - $file->delete(); - throw $e; - } - - } - - public function checkUpload($file) { - - $filesettings = $this->blueprint->files(); - $forbiddenExtensions = array('php', 'html', 'htm', 'exe', kirby()->option('content.file.extension', 'txt')); - $forbiddenMimes = array_merge(f::$mimes['php'], array('text/html', 'application/x-msdownload')); - $extension = strtolower($file->extension()); - - // files without extension are not allowed - if(empty($extension)) { - throw new Exception(l('files.add.error.extension.missing')); - } - - // block forbidden extensions - if(in_array($extension, $forbiddenExtensions)) { - throw new Exception(l('files.add.error.extension.forbidden')); - } - - // especially block any connection that contains php - if(str::contains($extension, 'php')) { - throw new Exception(l('files.add.error.extension.forbidden')); - } - - // block forbidden mimes - if(in_array(strtolower($file->mime()), $forbiddenMimes)) { - throw new Exception(l('files.add.error.mime.forbidden')); - } - - // Block htaccess files - if(strtolower($file->filename()) == '.htaccess') { - throw new Exception(l('files.add.error.htaccess')); - } - - // Block invisible files - if(str::startsWith($file->filename(), '.')) { - throw new Exception(l('files.add.error.invisible')); - } - - // Files blueprint option 'type' - if(count($filesettings->type()) > 0 and !in_array($file->type(), $filesettings->type())) { - throw new Exception(l('files.add.blueprint.type.error') . implode(', ', $filesettings->type())); - } - - // Files blueprint option 'size' - if($filesettings->size() and f::size($file->root()) > $filesettings->size()) { - throw new Exception(l('files.add.blueprint.size.error') . f::niceSize($filesettings->size())); - } - - // Files blueprint option 'width' - if($file->type() == 'image' and $filesettings->width() and $file->width() > $filesettings->width()) { - throw new Exception('Page only allows image width of ' . $filesettings->width().'px'); - } - - // Files blueprint option 'height' - if($file->type() == 'image' and $filesettings->height() and $file->height() > $filesettings->height()) { - throw new Exception('Page only allows image height of ' . $filesettings->height().'px'); - } - - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/site.php b/panel/app/src/panel/models/site.php deleted file mode 100644 index e6de5b2..0000000 --- a/panel/app/src/panel/models/site.php +++ /dev/null @@ -1,222 +0,0 @@ -cache['blueprint'])) return $this->cache['blueprint']; - return $this->cache['blueprint'] = new Blueprint('site'); - } - - public function changes() { - return new Changes($this); - } - - public function uri($action = null) { - if(empty($action)) { - return parent::uri(); - } else { - return 'site/' . $action; - } - } - - public function url($action = null) { - - if(empty($action)) { - return parent::url(); - } else if($action == 'edit') { - return panel()->urls()->index() . '/options'; - } else if($action == 'preview') { - return parent::url(); - } else if($this->multilang() and in_array($action, $this->languages()->codes())) { - return parent::url($action); - } else { - return panel()->urls()->index() . '/' . $this->uri($action); - } - - } - - public function form($action, $callback) { - return panel()->form('pages/' . $action, $this, $callback); - } - - public function getFormData() { - - // get the latest content from the text file - $data = $this->content()->toArray(); - - // make sure the title is always there - $data['title'] = $this->title(); - - return $data; - - } - - public function getBlueprintFields() { - return $this->blueprint()->fields($this); - } - - public function getFormFields() { - return $this->getBlueprintFields()->toArray(); - } - - public function canSortFiles() { - return $this->blueprint()->files()->sortable(); - } - - public function files() { - return new Files($this); - } - - public function children() { - return new Children($this); - } - - public function filterInput($input) { - $data = array(); - foreach($this->content()->toArray() as $key => $value) { - $data[$key] = null; - } - return array_merge($data, $input); - } - - public function update($input = array(), $lang = null) { - - $data = $this->filterInput($input); - - $this->changes()->discard(); - - parent::update($data, $lang); - - kirby()->trigger('panel.site.update', $this); - - } - - public function sidebar() { - return new Sidebar($this); - } - - public function upload() { - return new Uploader($this); - } - - public function addButton() { - try { - return new AddButton($this); - } catch(Exception $e) { - return false; - } - } - - public function topbar(Topbar $topbar) { - - if($topbar->view == 'options/index') { - $topbar->append(purl('options'), l('metatags')); - } - - if($topbar->view == 'subpages/index') { - $topbar->append($this->url('subpages'), l('subpages')); - } - - $topbar->html .= new Snippet('languages', array( - 'languages' => $this->languages(), - 'language' => $this->language(), - )); - - } - - public function users() { - return new Users(); - } - - public function user($username = null) { - if(is_null($username)) return User::current(); - try { - return new User($username); - } catch(Exception $e) { - return null; - } - } - - public function delete($force = false) { - throw new Exception(l('site.delete.error')); - } - - public function maxSubpages() { - $max = $this->blueprint()->pages()->max(); - // if max subpages is null, use the biggest 32bit integer - // will never be reached anyway. Kirby is not made for that scale :) - return is_null($max) ? 2147483647 : $max; - } - - public function maxFiles() { - $max = $this->blueprint()->files()->max(); - // see: maxSubpages - return is_null($max) ? 2147483647 : $max; - } - - public function canHaveSubpages() { - return $this->maxSubpages() !== 0; - } - - public function canShowSubpages() { - return ($this->blueprint()->pages()->hide() !== true and $this->canHaveSubpages()); - } - - public function canHaveFiles() { - return $this->maxFiles() !== 0; - } - - public function canShowFiles() { - return ($this->blueprint()->files()->hide() !== true and $this->canHaveFiles()); - } - - public function canHaveMoreSubpages() { - if(!$this->canHaveSubpages()) { - return false; - } else if($this->children()->count() >= $this->maxSubpages()) { - return false; - } else { - return true; - } - } - - public function canHaveMoreFiles() { - if(!$this->canHaveFiles()) { - return false; - } else if($this->files()->count() >= $this->maxFiles()) { - return false; - } else { - return true; - } - } - - - public function structure() { - return new Structure($this, 'site_' . $this->lang()); - } - - public function lang() { - return $this->multilang() ? $this->language()->code() : false; - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/user.php b/panel/app/src/panel/models/user.php deleted file mode 100644 index b897c15..0000000 --- a/panel/app/src/panel/models/user.php +++ /dev/null @@ -1,151 +0,0 @@ -username() . '/' . $action; - } - - public function url($action = 'edit') { - if(empty($action)) $action = 'edit'; - return panel()->urls()->index() . '/' . $this->uri($action); - } - - public function form($action, $callback) { - return panel()->form('users/' . $action, $this, $callback); - } - - public function update($data = array()) { - - if(!panel()->user()->isAdmin() and !$this->isCurrent()) { - throw new Exception(l('users.form.error.update.rights')); - } - - // users which are not an admin cannot change their role - if(!panel()->user()->isAdmin()) { - unset($data['role']); - } - - if(str::length(a::get($data, 'password')) > 0) { - if(a::get($data, 'password') !== a::get($data, 'passwordconfirmation')) { - throw new Exception(l('users.form.error.password.confirm')); - } - } else { - unset($data['password']); - } - - unset($data['passwordconfirmation']); - - if($this->isLastAdmin() and a::get($data, 'role') !== 'admin') { - // check the number of left admins to not convert the last one - throw new Exception(l('user.error.lastadmin')); - } - - parent::update($data); - - // flush the cache in case if the user data is - // used somewhere on the site (i.e. for profiles) - kirby()->cache()->flush(); - - kirby()->trigger('panel.user.update', $this); - - return $this; - - } - - public function isLastAdmin() { - if($this->isAdmin()) { - if(panel()->users()->filterBy('role', 'admin')->count() == 1) { - return true; - } - } else { - return false; - } - } - - public function delete() { - - if(!panel()->user()->isAdmin() and !$this->isCurrent()) { - throw new Exception(l('users.delete.error.permission')); - } - - if($this->isLastAdmin()) { - // check the number of left admins to not delete the last one - throw new Exception(l('users.delete.error.lastadmin')); - } - - parent::delete(); - - // flush the cache in case if the user data is - // used somewhere on the site (i.e. for profiles) - kirby()->cache()->flush(); - - kirby()->trigger('panel.user.delete', $this); - - } - - public function avatar($crop = null) { - if($crop === null) { - return new Avatar($this); - } else { - $avatar = $this->avatar(); - if($avatar->exists()) { - return $avatar->crop($crop); - } else { - return $avatar; - } - } - } - - public function isCurrent() { - return $this->is(panel()->user()); - } - - public function history() { - return new History($this); - } - - public function topbar($topbar) { - - $topbar->append(purl('users'), l('users')); - $topbar->append($this->url(), $this->username()); - - } - - public function getBlueprintFields() { - return $this->blueprint()->fields($this); - } - - public function blueprint() { - return new Blueprint($this); - } - - public function structure() { - return new Structure($this, 'user_' . $this->username()); - } - - static public function current() { - if($user = parent::current()) { - if($user->hasPanelAccess()) { - return $user; - } else { - $user->logout(); - return null; - } - } else { - return null; - } - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/user/avatar.php b/panel/app/src/panel/models/user/avatar.php deleted file mode 100644 index 1a6e26d..0000000 --- a/panel/app/src/panel/models/user/avatar.php +++ /dev/null @@ -1,78 +0,0 @@ -exists()) { - $this->root = $this->user->avatarRoot('{safeExtension}'); - $this->url = purl('assets/images/avatar.png'); - } - - } - - public function form($action, $callback) { - return panel()->form('avatars/' . $action, $this, $callback); - } - - public function upload() { - - if(!panel()->user()->isAdmin() and !$this->user->isCurrent()) { - throw new Exception(l('users.avatar.error.permission')); - } - - $root = $this->exists() ? $this->root() : $this->user->avatarRoot('{safeExtension}'); - - $upload = new Upload($root, array( - 'accept' => function($upload) { - if($upload->type() != 'image') { - throw new Error(l('users.avatar.error.type')); - } - } - )); - - if(!$upload->file()) { - throw $upload->error(); - } - - // flush the cache in case if the user data is - // used somewhere on the site (i.e. for profiles) - kirby()->cache()->flush(); - - kirby()->trigger('panel.avatar.upload', $this); - - } - - public function delete() { - - if(!panel()->user()->isAdmin() and !$this->user->isCurrent()) { - throw new Exception(l('users.avatar.delete.error.permission')); - } else if(!$this->exists()) { - return true; - } - - if(!parent::delete()) { - throw new Exception(l('users.avatar.delete.error')); - } - - // flush the cache in case if the user data is - // used somewhere on the site (i.e. for profiles) - kirby()->cache()->flush(); - - kirby()->trigger('panel.avatar.delete', $this); - - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/models/user/blueprint.php b/panel/app/src/panel/models/user/blueprint.php deleted file mode 100644 index ad09ca8..0000000 --- a/panel/app/src/panel/models/user/blueprint.php +++ /dev/null @@ -1,59 +0,0 @@ -user = $user; - - // load from yaml file - $this->load(); - - } - - public function load() { - - // get the user role and load the - // correspondant blueprint if available - $this->name = basename(strtolower($this->user->role())); - - // try to find a user blueprint - $file = kirby()->get('blueprint', 'users/' . $this->name); - - if($file) { - $this->file = $file; - $this->yaml = data::read($this->file, 'yaml'); - - // remove the broken first line - unset($this->yaml[0]); - } - - } - - public function fields() { - $fields = (array)a::get($this->yaml, 'fields', array()); - return new Fields($fields, $this->user); - } - - public function __toString() { - return $this->name; - } - -} diff --git a/panel/app/src/panel/models/user/history.php b/panel/app/src/panel/models/user/history.php deleted file mode 100644 index 9d9ea3d..0000000 --- a/panel/app/src/panel/models/user/history.php +++ /dev/null @@ -1,94 +0,0 @@ -site()->user($user->username())) { - $this->user = $user; - } else { - throw new Exception('The user could not be found'); - } - } - - public function add($id) { - - if(is_a('Kirby\\Panel\\Models\\Page', $id)) { - $page = $id; - } else { - if(empty($id)) return false; - - try { - $page = panel()->page($id); - } catch(Exception $e) { - return false; - } - } - - $history = $this->get(); - - // remove existing entries - foreach($history as $key => $val) { - if($val->id() == $page->id()) unset($history[$key]); - } - - array_unshift($history, $page->id()); - $history = array_slice($history, 0, 5); - - try { - $this->user->update(array( - 'history' => $history - )); - } catch(Exception $e) { - - } - - } - - public function get() { - - $history = $this->user->__get('history'); - - if(empty($history) or !is_array($history)) { - return array(); - } - - $update = false; - $result = array(); - - foreach($history as $item) { - - try { - $result[] = panel()->page($item); - } catch(Exception $e) { - $update = true; - } - - } - - if($update) { - - $history = array_map(function($item) { - return $item->id(); - }, $result); - - try { - $this->user->update(array( - 'history' => $history - )); - } catch(Exception $e) { - - } - - } - - return $result; - - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/roots.php b/panel/app/src/panel/roots.php deleted file mode 100644 index 60d8a7a..0000000 --- a/panel/app/src/panel/roots.php +++ /dev/null @@ -1,34 +0,0 @@ -panel = $panel; - $this->index = $root; - $this->app = $root . DS . 'app'; - $this->assets = $root . DS . 'assets'; - - $this->config = $this->app . DS . 'config'; - $this->controllers = $this->app . DS . 'controllers'; - $this->collections = $this->app . DS . 'collections'; - $this->models = $this->app . DS . 'models'; - $this->fields = $this->app . DS . 'fields'; - $this->forms = $this->app . DS . 'forms'; - $this->translations = $this->app . DS . 'translations'; - $this->widgets = $this->app . DS . 'widgets'; - $this->layouts = $this->app . DS . 'layouts'; - $this->lib = $this->app . DS . 'lib'; - $this->topbars = $this->app . DS . 'topbars'; - $this->snippets = $this->app . DS . 'snippets'; - $this->views = $this->app . DS . 'views'; - - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/search.php b/panel/app/src/panel/search.php deleted file mode 100644 index f3f6f95..0000000 --- a/panel/app/src/panel/search.php +++ /dev/null @@ -1,109 +0,0 @@ -query = trim($query); - $this->pages = new Collection; - $this->users = new Collection; - - // temporary disable the search cache - $this->cache = cache::setup('mock'); - - // try { - // $root = kirby()->roots()->cache() . DS . 'search'; - // dir::make($root); - // $this->cache = cache::setup('file', array('root' => $root)); - // } catch(Exception $e) { - // $this->cache = cache::setup('session'); - // } - - $this->run(); - - } - - public function data() { - - $pages = $this->cache->get('pages'); - $users = $this->cache->get('users'); - - if(empty($pages)) { - $pages = array(); - foreach(panel()->site()->index() as $page) { - $pages[] = array( - 'title' => (string)$page->title(), - 'uri' => (string)$page->id(), - ); - } - $this->cache->set('pages', $pages); - } - - if(empty($users)) { - foreach(panel()->users() as $user) { - $users[] = array( - 'username' => $user->username(), - 'email' => $user->email() - ); - } - $this->cache->set('users', $users); - } - - return compact('pages', 'users'); - - } - - public function run() { - - if(empty($this->query) or str::length($this->query) <= 1) { - return false; - } - - $data = $this->data(); - - - foreach($data['pages'] as $page) { - if( - str::contains($page['title'], $this->query) or - str::contains($page['uri'], $this->query) - ) { - $this->pages->append($page['uri'], $page); - } - } - - foreach($data['users'] as $user) { - if( - str::contains($user['username'], $this->query) or - str::contains($user['email'], $this->query) - ) { - $this->users->append($user['username'], $user); - } - } - - $this->pages = $this->pages->limit(5); - $this->users = $this->users->limit(5); - - } - - public function pages() { - return $this->pages; - } - - public function users() { - return $this->users; - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/snippet.php b/panel/app/src/panel/snippet.php deleted file mode 100644 index 7ece8fe..0000000 --- a/panel/app/src/panel/snippet.php +++ /dev/null @@ -1,14 +0,0 @@ -_root = panel::instance()->roots()->snippets(); - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/structure.php b/panel/app/src/panel/structure.php deleted file mode 100644 index b57d3b2..0000000 --- a/panel/app/src/panel/structure.php +++ /dev/null @@ -1,181 +0,0 @@ -model = $model; - $this->id = 'structure_' . sha1($id); - $this->blueprint = $this->model->blueprint(); - - } - - public function forField($field) { - - if(method_exists($this->model, $field)) { - throw new Exception('The field name: ' . $field . ' cannot be used as it is reserved'); - } - - - $this->field = $field; - $this->config = $this->model->getBlueprintFields()->get($this->field); - - - if(is_a($this->model, 'Page')) { - $source = $this->model->content()->get($this->field); - $decode = true; - } else if(is_a($this->model, 'File')) { - $source = $this->model->meta()->get($this->field); - $decode = true; - } else if(is_a($this->model, 'User')) { - $source = $this->model->{$this->field}(); - $decode = false; - } else { - throw new Exception('Invalid model for structure field: ' . $this->field); - } - - $this->source = $decode ? (array)yaml::decode($source) : (array)$source; - $this->store = new Store($this, $this->source); - - return $this; - - } - - public function config() { - return $this->config; - } - - public function source() { - return $this->source; - } - - public function store() { - return $this->store; - } - - public function model() { - return $this->model; - } - - public function field() { - return $this->field; - } - - public function id() { - return $this->id; - } - - public function fields() { - - $fields = $this->config->fields(); - $fields = new Fields($fields, $this->model); - $fields = $fields->toArray(); - - // make sure that no unwanted options or fields - // are being included here - foreach($fields as $name => $field) { - - // remove all structure fields within structures - if($field['type'] == 'structure') { - unset($fields[$name]); - // convert title fields to normal text fields - } else if($field['type'] == 'title') { - $fields[$name]['type'] = 'text'; - // remove invalid buttons from textareas - } else if($field['type'] == 'textarea') { - $buttons = a::get($fields[$name], 'buttons'); - if(is_array($buttons)) { - foreach($buttons as $index => $value) { - if(in_array($value, array('link','email'))) { - unset($fields[$name]['buttons'][$index]); - } - } - } else if($buttons !== false) { - $fields[$name]['buttons'] = array('bold', 'italic'); - } - } - - } - - return $fields; - - } - - public function data() { - - $collection = new Collection($this->store()->data()); - $collection = $collection->map(function($item) { - return new Obj($item); - }); - - return $collection; - - } - - public function toObject($array) { - return is_array($array) ? new Obj($array) : false; - } - - public function find($id) { - return $this->toObject($this->store()->find($id)); - } - - public function reset() { - - if($this->field) { - return $this->store()->reset(); - } else { - foreach(s::get() as $key => $value) { - if(str::startsWith($key, $this->id)) { - s::remove($key); - } - } - } - - } - - public function delete($id = null) { - return $this->store()->delete($id); - } - - public function add($data = array()) { - return $this->store()->add($data); - } - - public function update($id, $data = array()) { - return $this->toObject($this->store()->update($id, $data)); - } - - public function sort($ids) { - return $this->store()->sort($ids); - } - - public function toArray() { - return $this->store()->toArray(); - } - - public function toYaml() { - return $this->store()->toYaml(); - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/structure/store.php b/panel/app/src/panel/structure/store.php deleted file mode 100644 index 5cb599e..0000000 --- a/panel/app/src/panel/structure/store.php +++ /dev/null @@ -1,185 +0,0 @@ -structure = $structure; - $this->source = $source; - $this->id = $structure->id() . '_' . $structure->field(); - $this->age = time(); - - $this->sync(); - $this->init(); - } - - public function init() { - - $data = s::get($this->id()); - - if(!is_array($data)) { - $raw = (array)$this->source; - } else { - $raw = (array)s::get($this->id(), array()); - } - - $data = array(); - - foreach($raw as $row) { - - if(is_string($row)) { - continue; - } - - if(!isset($row['id'])) { - $row['id'] = str::random(32); - } - - $data[$row['id']] = $row; - - } - - $this->data = $data; - s::set($this->id, $this->data); - s::set($this->id . '_age', $this->age); - - } - - /** - * Resets store if necessary to stay in sync with content file - */ - public function sync() { - - $file = $this->structure->model()->textfile(); - $ageModel = f::exists($file) ? f::modified($file) : 0; - $ageStore = s::get($this->id() . '_age'); - - if($ageStore < $ageModel) { - $this->reset(); - $this->age = $ageModel; - } else { - $this->age = $ageStore; - } - - } - - public function id() { - return $this->id; - } - - public function data() { - return $this->data; - } - - public function find($id) { - return a::get($this->data, $id); - } - - public function add($data) { - - $data['id'] = str::random(32); - - $this->data[ $data['id'] ] = $data; - $this->save(); - - return $data['id']; - - } - - public function update($id, $data) { - - if($entry = a::get($this->data, $id)) { - - foreach($data as $key => $value) { - $entry[$key] = $value; - } - - $this->data[$id] = $entry; - $this->save(); - - return $entry; - - } else { - return false; - } - - } - - public function delete($id) { - - if(is_null($id)) { - $this->data = array(); - } else { - unset($this->data[$id]); - } - - $this->save(); - - return $this->data; - - } - - public function sort($ids) { - - $data = array(); - - foreach($ids as $id) { - if($item = $this->find($id)) { - $data[$id] = $item; - } - } - - $this->data = $data; - $this->save(); - - return $this->data; - - } - - public function toArray() { - $array = array_values($this->data); - $array = array_map(function($item) { - unset($item['id']); - return $item; - }, $array); - return $array; - } - - public function toYaml() { - return trim(yaml::encode($this->toArray())); - } - - public function save() { - - s::set($this->id, $this->data); - - // keep the changes for the page - if(is_a($this->structure->model(), 'page')) { - $this->structure->model()->changes()->update( - $this->structure->field(), - $this->toYaml() - ); - } - - } - - public function reset() { - return s::remove($this->id); - } - - -} \ No newline at end of file diff --git a/panel/app/src/panel/topbar.php b/panel/app/src/panel/topbar.php deleted file mode 100644 index 4f2169f..0000000 --- a/panel/app/src/panel/topbar.php +++ /dev/null @@ -1,117 +0,0 @@ -view = $view; - - if(is_object($input) and method_exists($input, 'topbar')) { - $input->topbar($this); - } else { - - $class = is_object($input) ? str_replace('model', '', strtolower(get_class($input))) : (string)$input; - $file = panel()->roots()->topbars() . DS . str::lower($class) . '.php'; - - if(file_exists($file)) { - - $callback = require($file); - $callback($this, $input); - - } else { - throw new Exception(l('topbar.error.class.definition') . $class); - } - - } - - } - - public function append($url, $title) { - - $this->breadcrumb[] = array( - 'title' => $title, - 'url' => $url - ); - - } - - public function menu() { - return new Snippet('menu'); - } - - public function breadcrumb() { - return new Snippet('breadcrumb', array( - 'items' => $this->breadcrumb - )); - } - - public function message() { - - if($message = s::get('message') and is_array($message)) { - - $text = a::get($message, 'text'); - $type = a::get($message, 'type', 'notification'); - - $element = new Brick('div'); - $element->addClass('message'); - - if($type == 'error') { - $element->addClass('message-is-alert'); - } else { - $element->addClass('message-is-notice'); - } - - $element->append(function() use($text) { - $content = new Brick('span'); - $content->addClass('message-content'); - $content->text($text); - return $content; - }); - - $element->append(function() { - $toggle = new Brick('a'); - $toggle->attr('href', url::current()); - $toggle->addClass('message-toggle'); - $toggle->html('×'); - return $toggle; - }); - - s::remove('message'); - - return $element; - - } - - } - - public function render() { - - $element = new Brick('header', '', array('class' => 'topbar')); - $element->append($this->menu()); - $element->append($this->breadcrumb()); - $element->append($this->html); - $element->append(new Snippet('search')); - $element->append($this->message()); - - return $element; - - } - - public function __toString() { - return (string)$this->render(); - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/translation.php b/panel/app/src/panel/translation.php deleted file mode 100644 index 04f0477..0000000 --- a/panel/app/src/panel/translation.php +++ /dev/null @@ -1,80 +0,0 @@ - 'es_419', - 'no_nb' => 'nb', - 'cz' => 'cs' - ); - - public function __construct($panel, $code) { - - $this->panel = $panel; - $this->code = basename($code); - - // convert old codes - if(isset($this->map[$this->code])) { - $this->code = $this->map[$this->code]; - } - - // set the root for the translation directory - $this->root = $this->panel->roots()->translations() . DS . $this->code; - - if(!is_dir($this->root)) { - throw new Exception('The translation does not exist: ' . $this->code); - } - - if(!is_file($this->root . DS . 'package.json')) { - throw new Exception('The package.json is missing for the translation with code: ' . $this->code); - } - - if(!is_file($this->root . DS . 'core.json')) { - throw new Exception('The core.json is missing for the translation with code: ' . $this->code); - } - - } - - public function code() { - return $this->code; - } - - public function root() { - return $this->root; - } - - public function load() { - return l::$data = data::read($this->root . DS . 'core.json'); - } - - public function info() { - if(!is_null($this->info)) return $this->info; - return $this->info = new Obj(data::read($this->root . DS . 'package.json')); - } - - public function direction() { - $direction = $this->info()->direction(); - return $direction ? $direction : 'ltr'; - } - - public function __call($method, $args) { - return $this->info()->{$method}(); - } - - public function __toString() { - return $this->code; - } - -} diff --git a/panel/app/src/panel/upload.php b/panel/app/src/panel/upload.php deleted file mode 100644 index 1ec93bb..0000000 --- a/panel/app/src/panel/upload.php +++ /dev/null @@ -1,22 +0,0 @@ - 'The file is missing', - static::ERROR_MISSING_TMP_DIR => 'The /tmp directory is missing on your server', - static::ERROR_FAILED_UPLOAD => 'The upload failed', - static::ERROR_PARTIAL_UPLOAD => 'The file has been only been partially uploaded', - static::ERROR_UNALLOWED_OVERWRITE => 'The file exists and cannot be overwritten', - static::ERROR_MAX_SIZE => 'The file is too big. The maximum size is ' . f::niceSize($this->maxSize()), - static::ERROR_MOVE_FAILED => 'The file could not be moved', - static::ERROR_UNACCEPTED => 'The file is not accepted by the server' - ); - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/urls.php b/panel/app/src/panel/urls.php deleted file mode 100644 index 5341164..0000000 --- a/panel/app/src/panel/urls.php +++ /dev/null @@ -1,35 +0,0 @@ -panel = $panel; - - // base url - $this->index = rtrim($this->panel->kirby()->urls()->index(), '/') . '/' . basename($root); - - // assets - $this->assets = $this->index . '/assets'; - $this->css = $this->assets . '/css'; - $this->js = $this->assets . '/js'; - $this->images = $this->assets . '/images'; - - // enable urls without rewriting - if(kirby()->option('rewrite') === false) { - $this->index .= '/index.php'; - } - - // shortcuts - $this->api = $this->index . '/api'; - $this->login = $this->index . '/login'; - $this->logout = $this->index . '/logout'; - $this->error = $this->index . '/error'; - - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/view.php b/panel/app/src/panel/view.php deleted file mode 100644 index d30f5bf..0000000 --- a/panel/app/src/panel/view.php +++ /dev/null @@ -1,40 +0,0 @@ -_root = panel::instance()->roots()->views(); - $this->_file = $file; - $this->_data = $data; - } - - public function __set($key, $value) { - $this->_data[$key] = $value; - } - - public function render() { - $file = $this->_root . DS . str_replace('.', DS, $this->_file) . '.php'; - if(!file_exists($file)) throw new Exception(l('view.error.invalid') . $file); - return tpl::load($file, $this->_data); - } - - public function __toString() { - try { - return (string)$this->render(); - } catch(Exception $e) { - return $e->getMessage(); - } - } - -} \ No newline at end of file diff --git a/panel/app/src/panel/widgets.php b/panel/app/src/panel/widgets.php deleted file mode 100644 index c73d825..0000000 --- a/panel/app/src/panel/widgets.php +++ /dev/null @@ -1,92 +0,0 @@ -order = kirby()->option('panel.widgets'); - - $this->defaults(); - $this->custom(); - $this->sort(); - - } - - public function load($name) { - - if(!isset($this->available[$name])) { - return false; - } - - $dir = $this->available[$name]; - $file = $dir . DS . $name . '.php'; - - if(!file_exists($file)) { - return false; - } - - $widget = require($file); - - if(is_array($widget)) { - $this->append($name, $widget); - return $widget; - } else { - return false; - } - - } - - public function defaults() { - - $kirby = kirby(); - $root = panel()->roots()->widgets(); - - foreach(dir::read($root) as $dir) { - $kirby->registry->set('widget', $dir, $root . DS . $dir); - } - - } - - public function custom() { - - $kirby = kirby(); - $root = $kirby->roots()->widgets(); - - foreach(dir::read($root) as $dir) { - $kirby->registry->set('widget', $dir, $root . DS . $dir); - } - - } - - public function sort() { - - // load all widgets from the registry - $this->available = kirby()->registry()->get('widget'); - - // the license warning must always be included - $this->order['license'] = true; - - // append ordered widgets - foreach($this->order as $name => $add) { - if($add) { - $this->load($name); - } - unset($this->available[$name]); - } - - // append the unsorted widgets - foreach($this->available as $name => $dir) { - $this->load($name); - } - - } - -} \ No newline at end of file diff --git a/panel/app/topbars/error.php b/panel/app/topbars/error.php deleted file mode 100644 index 123b6eb..0000000 --- a/panel/app/topbars/error.php +++ /dev/null @@ -1,5 +0,0 @@ -append('', l('error.headline')); -}; \ No newline at end of file diff --git a/panel/app/topbars/user.php b/panel/app/topbars/user.php deleted file mode 100644 index b6d2a48..0000000 --- a/panel/app/topbars/user.php +++ /dev/null @@ -1,13 +0,0 @@ -append(purl('users'), l('users')); - - if($user === 'user') { - $topbar->append(purl('users/add'), l('users.index.add')); - } else { - $topbar->append($user->url(), $user->username()); - } - -}; \ No newline at end of file diff --git a/panel/app/translations/ar/core.json b/panel/app/translations/ar/core.json deleted file mode 100644 index 1f09f80..0000000 --- a/panel/app/translations/ar/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "إلغاء", - "add": "إضافة", - "addit": "إضافة وتعديل", - "save": "حفظ", - "saved": "تم الحفظ!", - "change": "تغيير", - "delete": "حذف", - "insert": "إدراج", - "ok": "موافق", - "routes.error.invalid": "رابط غير صالح للوحة التحكم", - "controller.error.invalid": "مراقب غير صالح", - "controller.error.action": "Invalid action", - "view.error.invalid": "Invalid view:", - "options.show": "عرض الخيارات", - "options.hide": "إخفاء الخيارات", - "installation": "التنصيب", - "installation.check.headline": "تنصيب لوحة كيربي", - "installation.check.text": "المشاكل التالية واجهت كيربي أثناء التنصيب…", - "installation.check.retry": "إعادة المحاولة", - "installation.check.error": "هناك بعض المشاكل!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "المجلد /site/accounts غير قابل للكتابة", - "installation.check.error.avatars": "المجلد /assets/avatars غير قابل للكتابة", - "installation.check.error.blueprints": "فضلا قم بإضافة المجلد /site/blueprints", - "installation.check.error.content": "مجلد المحتوى وجميع الملفات التي بداخله يجب أن تكون قابلة للكتابة.", - "installation.check.error.thumbs": "مجلد الصور المصغرة يجب أن يكون قابل للكتابة.", - "installation.signup.username.label": "أنشئ حسابك الأول", - "installation.signup.username.placeholder": "اسم المستخدم", - "installation.signup.email.label": "البريد الإلكتروني", - "installation.signup.email.placeholder": "mail@example.com", - "installation.signup.password.label": "كلمة المرور", - "installation.signup.language.label": "اللغة", - "installation.signup.button": "إنشاء الحساب", - "login": "تسجيل الدخول", - "login.welcome": "فضلاً سجل الدخول باستخدام حسابك", - "login.username.label": "اسم المستخدم", - "login.password.label": "كلمة المرور", - "login.error": "خطأ في اسم المستخدم أو كلمة المرور", - "login.button": "تسجيل الدخول", - "login.log.error.permissions": "Login log file is not writable.", - "logout": "Log out", - "topbar.error.class.definition": "Missing topbar definition for class:", - "dashboard": "لوحة التحكم", - "dashboard.index.pages.title": "الصفحات", - "dashboard.index.pages.edit": "تعديل", - "dashboard.index.pages.add": "إضافة", - "dashboard.index.site.title": "وصلة موقعك", - "dashboard.index.account.title": "حسابك", - "dashboard.index.account.edit": "تعديل", - "dashboard.index.metatags.title": "متغيرات الموقع", - "dashboard.index.metatags.edit": "تعديل", - "dashboard.index.history.title": "آخر تحديثاتك", - "dashboard.index.history.text": "سيتم عرض آخر صفحاتك المعدلة هنا لتسهيل وصولك إليها مجدداً.", - "dashboard.index.license.title": "Kirby license", - "dashboard.index.license.text": "It seems you are running Kirby on a public server without a valid license!\n\nPlease, support Kirby and (link: {buy} text: buy a license now)\n\nIf you already have a license key, just add it to your config file: (link: {docs} text: site/config/config.php)", - "metatags": "متغيرات الموقع", - "metatags.info": "معلومات عن Kirby ", - "metatags.license": "Kirby license", - "metatags.version.toolkit": "Toolkit version", - "metatags.version.kirby": "Kirby version", - "metatags.version.panel": "Panel version", - "metatags.back": "العودة إلى لوحة التحكم", - "metatags.files": "Site files", - "site.delete.error": "The site cannot be deleted", - "pages.show.settings": "إعدادات الصفحة", - "pages.show.preview": "عرض المعاينة", - "pages.show.template": "القالب", - "pages.show.changeurl": "تغيير الوصلة", - "pages.show.invisible": "Status: invisible", - "pages.show.visible": "Status: visible", - "pages.show.changes.text": "You have unsaved changes!", - "pages.show.changes.button": "Discard", - "pages.show.delete": "حذف هذه الصفحة", - "pages.show.subpages.title": "الصفحات", - "pages.show.subpages.edit": "تعديل", - "pages.show.subpages.add": "إضافة", - "pages.show.subpages.empty": "هذه الصفحة لا تحتوي على صفحات فرعية", - "pages.show.files.title": "الملفات", - "pages.show.files.edit": "تعديل", - "pages.show.files.add": "إضافة", - "pages.show.files.empty": "هذه الصفحة لا تحتوي على ملفات", - "pages.show.error.permissions.title": "هذه الصفحة غير قابلة للكتابة", - "pages.show.error.permissions.text": "فضلاً قم بفحص جميع التصاريح على مجلد المحتوى وجميع الملفات التي بداخله.", - "pages.show.error.permissions.retry": "إعادة المحاولة", - "pages.show.error.notitle.title": "هذا المخطط لا يحتوي على حقل العنوان،", - "pages.show.error.notitle.text": "فضلاً قم بإضافة حقل العنوان والمحاولة مرة أخرى", - "pages.show.error.notitle.retry": "إعادة المحاولة", - "pages.show.error.form": "فضلاً قم بإكمال جميع الحقول بشكل صحيح", - "pages.add.title.label": "إضافة صفحة جديدة", - "pages.add.title.placeholder": "العنوان", - "pages.add.url.label": "الوصلة", - "pages.add.url.enter": "(اكتب عنوانك)", - "pages.add.url.close": "إغلاق", - "pages.add.url.help": "الصيغة: حروف صغيرة a-z، أرقام 0-9 وعلامة الشرطة -.", - "pages.add.template.label": "القالب", - "pages.add.error.create": "The page could not be created", - "pages.add.error.title": "العنوان مفقود", - "pages.add.error.template": "القالب مفقود", - "pages.add.error.max.headline": "لا يُسمح بإضافة صفحات جديدة", - "pages.add.error.max.text": "تم استهلاك الحد الأقصى من الصفحات الفرعية لهذه الصفحة", - "pages.url.uid.label": "الوصلة", - "pages.url.uid.label.option": "إنشاء من العنوان", - "pages.url.error.exists": "توجد صفحة أخرى لها نفس الوصلة", - "pages.url.error.move": "لم يكن بالإمكان تغيير الوصلة", - "pages.url.error.rights": "You cannot change the URL of this page", - "pages.template.select.label": "القالب", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Position", - "pages.toggle.invisible": "invisible", - "pages.toggle.publish": "Do you really want to change the status of this page to **visible?**", - "pages.toggle.hide": "Do you really want to change the status of this page to **invisible?**", - "pages.toggle.error.error": "The status of the error page cannot be changed", - "pages.delete.headline": "هل أنت متأكد من رغبتك في حذف هذه الصفحة؟", - "pages.delete.error.home.headline": "لا يمكن حذف الصفحة الرئيسة", - "pages.delete.error.home.text": "قمت بمحاولة حذف الصفحة الرئيسة. لا يمكن إتمام ذلك بسبب ما سيعقبه من آثار غير مرغوبة.", - "pages.delete.error.error.headline": "لا يمكن حذف صفحة الأخطاء", - "pages.delete.error.error.text": "قمت بمحاولة حذف صفحة الأخطاء. لا يمكن إتمام ذلك بسبب ما سيعقبه من آثار غير مرغوبة.", - "pages.delete.error.children.headline": "لا يمكن حذف هذه الصفحة", - "pages.delete.error.children.text": "لا يمكن حذف هذه الصفحة لإحتوائها على صفحات فرعية. لإتمام ذلك، عليك أن تحذف صفحاتها الفرعية أولاً..", - "pages.delete.error.blocked.headline": "لا يمكن حذف هذه الصفحة", - "pages.delete.error.blocked.text": "هذه الصفحة مقفلة ولا يمكن حذفها.", - "pages.search.help": "ابحث عن الصفحات باستخدام الوصلة. تنقل بين نتائج البحث باستخدام مفاتيح الأسهم لأعلى وأسفل، واضغط مفتاح الإدخال للإنتقال للصفحة المحددة.", - "pages.search.noresults": "لا توجد نتائج لما بحثت عنه. فضلاً حاول البحث مرة أخرى بوصلة مختلفة.", - "pages.error.missing": "لم يتم العثور على الصفحة.", - "subpages": "الصفحات", - "subpages.index.headline": "الصفحات في", - "subpages.index.back": "عودة", - "subpages.index.add": "إضافة صفحة جديدة", - "subpages.index.add.first.text": "هذه الصفحة لا تملك صفحات فرعية حالياً", - "subpages.index.add.first.button": "أضف الصفحة الأولى", - "subpages.index.visible": "الصفحات المرئية", - "subpages.index.visible.help": "اسحب الصفحات المخفية إلى هنا لترتيبها أو جعلها مرئية.", - "subpages.index.invisible": "الصفحات المخفية", - "subpages.index.invisible.help": "اسحب الصفحات المرئية إلى هنا لبعثرتها أو جعلها مخفية.", - "subpages.add.error": "This page is not allowed to have subpages", - "subpages.add.error.more": "This page cannot have any more subpages", - "subpages.error.missing": "لم يتم العثور على الصفحة", - "files": "Files", - "files.index.headline": "الملفات لـ", - "files.index.back": "عودة", - "files.index.upload": "رفع ملف جديد", - "files.index.upload.first.text": "هذه الصفحة لا تملك ملفات حالياً", - "files.index.upload.first.button": "ارفع الملف الأول", - "files.index.edit": "تعديل", - "files.index.delete": "حذف", - "files.index.error.disabled": "The page is not allowed to have any files", - "files.add.error.max": "The maximum number of files for the current page has been reached.", - "files.add.error.extension.missing": "You cannot upload files without extension", - "files.add.error.extension.forbidden": "Forbidden file extension", - "files.add.error.mime.forbidden": "Forbidden mime type", - "files.add.error.htaccess": "htaccess files cannot be uploaded", - "files.add.error.invisible": "Invisible files cannot be uploaded", - "files.add.blueprint.type.error": "Page only allows:", - "files.add.blueprint.size.error": "Page only allows file size of", - "files.show.name.label": "اسم الملف", - "files.show.info.label": "النوع / الحجم / الأبعاد", - "files.show.link.label": "الوصلة العلنية", - "files.show.open": "عرض/تنزيل الملف", - "files.show.back": "عودة", - "files.show.replace": "استبدال", - "files.show.delete": "حذف", - "files.show.error.rename": "لم يكن بالإمكان تغيير اسم الملف", - "files.show.error.form": "فضلاً قم بتعبئة جميع الحقول بشكل صحيح", - "files.upload.drop": "اسقط الملفات هنا…", - "files.upload.click": "…او اضغط للرفع", - "files.replace.drop": "اسقط ملفاً هنا…", - "files.replace.click": "…او اضغط للاستبدال", - "files.replace.error.type": "الملف المرفوع يجب أن يكون من نفس النوع", - "files.delete.headline": "هل أنت متأكد من رغبتك في حذف هذا الملف؟", - "files.error.missing.page": "لم يتم العثور على الصفحة", - "files.error.missing.file": "لم يتم العثور على الملف", - "users": "المستخدمون", - "users.index.headline": "جميع المستخدمين", - "users.index.add": "إضافة مستخدم جديد", - "users.index.edit": "تعديل", - "users.index.delete": "حذف", - "users.form.username.label": "اسم المستخدم", - "users.form.username.placeholder": "اسم المستخدم الخاص بك", - "users.form.username.help": "الصيغة: حروف صغيرة a-z، أرقام 0-9 وعلامة الشرطة -.", - "users.form.username.readonly": "لا يمكن تغيير اسم المستخدم", - "users.form.firstname.label": "الاسم", - "users.form.lastname.label": "العائلة", - "users.form.email.label": "البريد الإلكتروني", - "users.form.email.placeholder": "mail@example.com", - "users.form.password.label": "كلمة المرور", - "users.form.password.confirm.label": "تأكيد كلمة المرور", - "users.form.password.new.label": "كلمة المرور الجديدة", - "users.form.password.new.confirm.label": "تأكيد كلمة المرور الجديدة", - "users.form.password.new.help": "اترك الحقل فارغاً لإبقاء كلمة المرور الحالية", - "users.form.language.label": "اللغة", - "users.form.role.label": "الوظيفة", - "users.form.options.headline": "خيارات الحساب", - "users.form.options.message": "إرسال بريد إلكتروني", - "users.form.options.delete": "حذف الحساب", - "users.form.avatar.headline": "الصورة الشخصية", - "users.form.avatar.upload": "رفع الصورة الشخصية", - "users.form.avatar.replace": "استبدال الصورة الشخصية", - "users.form.avatar.delete": "حذف الصورة الشخصية", - "users.form.back": "العودة إلى المستخدمين", - "users.form.error.password.confirm": "فضلاً قم بتأكيد كلمة المرور", - "users.form.error.update": "لم يكن بالإمكان تحديث المستخدم", - "users.form.error.update.rights": "You are not allowed to update this user", - "users.form.error.create": "لم يكن بالإمكان إنشاء المستخدم", - "users.form.error.permissions.title": "مجلد الحسابات غير قابل للكتابة", - "users.form.error.permissions.text": "تأكد أن المجلد /site/accounts موجود وقابل للكتابة.", - "users.delete.headline": "هل أنت متأكد من رغبتك في حذف هذا المستخدم؟", - "users.delete.error": "لم يكن بالإمكان حذف المستخدم", - "users.delete.error.permission": "You are not allowed to delete users", - "users.delete.error.permission.single": "You are not allowed to delete this user", - "users.delete.error.lastadmin": "You cannot delete the last admin", - "users.avatar.drop": "اسقط الصورة الشخصية هنا…", - "users.avatar.click": "…او اضغط للرفع", - "users.avatar.error.type": "بإمكانك رفع الصورة فقط بالصيغ JPG، أو PNG، أو GIF.", - "users.avatar.error.folder.headline": "مجلد الصور الشخصية غير قابل للكتابة", - "users.avatar.error.folder.text": "تأكد أن من إنشاء المجلد /assets/avatars وكونه قابل للكتابة لترفع الصور الشخصية.", - "users.avatar.error.permission": "You are not allowed to change the avatar", - "users.avatar.delete.error": "لم يكن بالإمكان حذف الصورة الشخصية", - "users.avatar.delete.error.permission": "You are not allowed to delete the avatar of this user", - "users.avatar.delete.success": "تم حذف الصورة الشخصية", - "users.avatar.missing": "This user has no avatar", - "users.error.missing": "لم يتم العثور على المستخدم", - "user.error.lastadmin": "You are the only admin. This cannot be changed.", - "form.error.missing": "The form cannot be found", - "form.construct.error.invalid": "Invalid form construction method", - "fields.required": "إلزامي", - "fields.date.label": "التاريخ", - "fields.date.months": [ - "يناير", - "فبراير", - "مارس", - "أبريل", - "مايو", - "يونيو", - "يوليو", - "أغسطس", - "سبتمبر", - "أكتوبر", - "نوڤمبر", - "ديسمبر" - ], - "fields.date.weekdays": [ - "الأحد", - "الإثنين", - "الثلاثاء", - "الأربعاء", - "الخميس", - "الجمعة", - "السبت" - ], - "fields.date.weekdays.short": [ - "أحد", - "أثنين", - "ثلاثاء", - "أربعاء", - "خميس", - "جمعة", - "سبت" - ], - "fields.email.label": "بريد إلكتروني", - "fields.email.placeholder": "mail@example.com", - "fields.number.label": "رقم", - "fields.number.placeholder": "#", - "fields.page.label": "صفحة", - "fields.page.placeholder": "محل/الصفحة/المرادة", - "fields.password.label": "كلمة مرور", - "fields.structure.add": "إضافة", - "fields.structure.add.first": "إضافة السجل الأول", - "fields.structure.empty": "لا توجد سجلات حالياً.", - "fields.structure.entry.error": "The item could not be found", - "fields.structure.cancel": "إلغاء", - "fields.structure.save": "حفظ", - "fields.structure.edit": "تعديل", - "fields.structure.delete": "حذف", - "fields.structure.delete.label": "Do you really want to delete this entry?", - "fields.tags.label": "وسوم", - "fields.tel.label": "هاتف", - "fields.textarea.buttons.bold.label": "نص عريض", - "fields.textarea.buttons.bold.text": "نص عريض", - "fields.textarea.buttons.italic.label": "نص مائل", - "fields.textarea.buttons.italic.text": "نص مائل", - "fields.textarea.buttons.link.label": "وصلة", - "fields.textarea.buttons.email.label": "بريد إلكتروني", - "fields.textarea.buttons.image.label": "صورة", - "fields.textarea.buttons.file.label": "ملف", - "fields.toggle.yes": "نعم", - "fields.toggle.no": "لا", - "fields.toggle.on": "تشغيل", - "fields.toggle.off": "تعطيل", - "fields.error.missing.controller": "The field controller file is missing", - "fields.error.missing.class": "The field controller class is missing", - "fields.error.route.invalid": "Invalid field route", - "fields.error.extended": "The field cannot be extended", - "editor.link.url.label": "إضافة وصلة", - "editor.link.text.label": "نص الوصلة", - "editor.link.text.help": "نص الوصلة اختياري", - "editor.email.address.label": "أدخل بريد إلكتروني", - "editor.email.address.placeholder": "mail@example.com", - "editor.email.text.label": "نص الوصلة", - "editor.email.text.help": "نص الوصلة اختياري", - "editor.file.empty": "هذه الصفحة لا تملك ملفات", - "editor.image.empty": "هذه الصفحة لا تملك صوراً", - "autocomplete.method.error": "Invalid autocomplete method", - "blueprints.error.default.missing": "Missing default blueprint", - "error": "خطأ", - "error.headline": "خطأ" -} \ No newline at end of file diff --git a/panel/app/translations/ar/package.json b/panel/app/translations/ar/package.json deleted file mode 100644 index 3765a0a..0000000 --- a/panel/app/translations/ar/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "title": "العربية", - "direction": "rtl", - "author": "أحمد الحداد ", - "version": "1.0.0" -} \ No newline at end of file diff --git a/panel/app/translations/bg/core.json b/panel/app/translations/bg/core.json deleted file mode 100644 index 606f188..0000000 --- a/panel/app/translations/bg/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Откажи", - "add": "Добави", - "addit": "Добави & Редактирай", - "save": "Запиши", - "saved": "Записано", - "change": "Промени", - "delete": "Изтрий", - "insert": "Вмъкни", - "ok": "Ок", - "routes.error.invalid": "Невалиден URL на Панел", - "controller.error.invalid": "Невалиден контролер", - "controller.error.action": "Невалидно действие", - "view.error.invalid": "Невалиден изглед:", - "options.show": "Покажи Опции", - "options.hide": "Скрий Опции", - "installation": "Инсталация", - "installation.check.headline": "Инсталиране на Kirby Панел", - "installation.check.text": "Kirby откри следните проблеми по време на инсталацията...", - "installation.check.retry": "Опитай пак", - "installation.check.error": "Има няколко проблема!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "папката /site/accounts не е записваема", - "installation.check.error.avatars": "Папката assets/avatars не е записваема", - "installation.check.error.blueprints": "моля добавете папка /site/blueprints", - "installation.check.error.content": "Папката \"content\" и всички файлове в нея трябва да бъдат записваеми", - "installation.check.error.thumbs": "Папката \"thumbs\" трябва да бъде записваема.", - "installation.signup.username.label": "Създайте Вашия първи акаунт", - "installation.signup.username.placeholder": "Потребителско име", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@example.com", - "installation.signup.password.label": "Парола", - "installation.signup.language.label": "Език", - "installation.signup.button": "Създайте своя акаунт", - "login": "Подписване", - "login.welcome": "Please log in with your new account", - "login.username.label": "Потребителско име", - "login.password.label": "Парола", - "login.error": "Невалидно потребитебско име или парола", - "login.button": "Log in", - "login.log.error.permissions": "Лог файла за влизанията не е записваем", - "logout": "Log out", - "topbar.error.class.definition": "липсва topbar definition за клас:", - "dashboard": "Табло", - "dashboard.index.pages.title": "Страници", - "dashboard.index.pages.edit": "Редактирай", - "dashboard.index.pages.add": "Добави", - "dashboard.index.site.title": "URL на Вашия сайт", - "dashboard.index.account.title": "Вашия акаунт", - "dashboard.index.account.edit": "Редактирай", - "dashboard.index.metatags.title": "Опции за сайта", - "dashboard.index.metatags.edit": "Редактирай", - "dashboard.index.history.title": "Вашите последни промени", - "dashboard.index.history.text": "Вашите последно променяни страници ще се покажат тук, за да е по-лесно да ги намерите отново по-късно.", - "dashboard.index.license.title": "Лиценз за Kirby", - "dashboard.index.license.text": "Изглежда използвате Kirby на публичен сървър без да притежавате валиден лиценз\n\nМоля, подкрепете Kirby и (link: {buy} text: купете своя лиценз сега)\n\nАко вече имате лицензен ключ, просто го добавете във Вашия config файл (link: {docs} text: site/config/config.php)", - "metatags": "Опции за сайта", - "metatags.info": "Информация за Kirby", - "metatags.license": "Лиценз за Kirby", - "metatags.version.toolkit": "Toolkit версия", - "metatags.version.kirby": "Версия на Kirby", - "metatags.version.panel": "Версия на Панел", - "metatags.back": "Назад към Таблото", - "metatags.files": "Файлове на сайта", - "site.delete.error": "Сайтът не може да се изтрие", - "pages.show.settings": "Настройки за страницата", - "pages.show.preview": "Отвори предварителен преглед", - "pages.show.template": "Модел", - "pages.show.changeurl": "Промени URL", - "pages.show.invisible": "Статус: Невидимо", - "pages.show.visible": "Статус: Видимо", - "pages.show.changes.text": "Имате незаписани промени", - "pages.show.changes.button": "Отмени", - "pages.show.delete": "Изтрий тази страница", - "pages.show.subpages.title": "Страници", - "pages.show.subpages.edit": "Редактирай", - "pages.show.subpages.add": "Добави", - "pages.show.subpages.empty": "Тази страница няма под-страници", - "pages.show.files.title": "Файлове", - "pages.show.files.edit": "Редактирай", - "pages.show.files.add": "Добави", - "pages.show.files.empty": "Тази страница не съдържа файлове", - "pages.show.error.permissions.title": "Страницата не е записваема", - "pages.show.error.permissions.text": "Моля, проверете правата за content папката и всички файлове в нея", - "pages.show.error.permissions.retry": "Опитай пак", - "pages.show.error.notitle.title": "blueprint няма поле title", - "pages.show.error.notitle.text": "Моля добавете заглавно поле и опитайте отново", - "pages.show.error.notitle.retry": "Опитай пак", - "pages.show.error.form": "Моля, попълнете всички полета правилно", - "pages.add.title.label": "Добавете нова страница", - "pages.add.title.placeholder": "Заглавие", - "pages.add.url.label": "URL-добавка", - "pages.add.url.enter": "(въведете вашето заглавие)", - "pages.add.url.close": "Затвори", - "pages.add.url.help": "Формат: малки букви a-z, 0-9 и нормални тирета", - "pages.add.template.label": "Модел", - "pages.add.error.create": "Страницата не може да бъде създадена", - "pages.add.error.title": "Заглавието липсва", - "pages.add.error.template": "Моделът липсва", - "pages.add.error.max.headline": "Не са позволени нови страници", - "pages.add.error.max.text": "Максималният брой под-страници за тази страница е достигнат.", - "pages.url.uid.label": "URL-добавка", - "pages.url.uid.label.option": "Създайте от заглавието", - "pages.url.error.exists": "Страница със същата URL-добавка вече съществува", - "pages.url.error.move": "Добавката не може да се променя", - "pages.url.error.rights": "Не можете да смените URL за тази страница", - "pages.template.select.label": "Модел", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Позиция", - "pages.toggle.invisible": "Невидим", - "pages.toggle.publish": "Наистина ли искате да смените статуса на тази страница на **Видим?**", - "pages.toggle.hide": "Наистина ли искате да смените статуса на тази страница на **Невидим?**", - "pages.toggle.error.error": "Статуса на ERROR страницата не може да се променя", - "pages.delete.headline": "Наистина ли искате да изтриете тази страница?", - "pages.delete.error.home.headline": "HOME страницата не може да се изтрива", - "pages.delete.error.home.text": "Вие се опитвате да изтриете HOME страницата. Това не е възможно, защото би довело до нежелани резултати.", - "pages.delete.error.error.headline": "ERROR страницата не може да се изтрива", - "pages.delete.error.error.text": "Вие се опитвате да изтриете ERROR страницата. Това не е възможно, защото би довело до нежелани резултати.", - "pages.delete.error.children.headline": "Страницата не може да се изтрива", - "pages.delete.error.children.text": "Тази страница има под-страници и не може да се изтрие. Моля, изтрийте всички под-страници.", - "pages.delete.error.blocked.headline": "Страницата не може да се изтрие", - "pages.delete.error.blocked.text": "Тази страница е заключена и не може да се изтрие.", - "pages.search.help": "Търсете страници по URL. Използвайте клавишите Нагоре и Надолу за да обходите резултатите от търсенето. Използвайте Enter за да отидете в избраната страница.", - "pages.search.noresults": "Няма резултати от вашето търсене. Моля опитайте отново с различен URL.", - "pages.error.missing": "Страницата не може да бъде намерена", - "subpages": "Страници", - "subpages.index.headline": "Страници в", - "subpages.index.back": "Назад", - "subpages.index.add": "Добавете нова страница", - "subpages.index.add.first.text": "Тази страница все още няма под-страници", - "subpages.index.add.first.button": "Добавете първата страница", - "subpages.index.visible": "Видими страници", - "subpages.index.visible.help": "Влачете невидимите страници тук за да ги сортирате / направите видими.", - "subpages.index.invisible": "Невидими страници", - "subpages.index.invisible.help": "Влачете видимите страници тук за да не ги сортирате / да ги направите невидими.", - "subpages.add.error": "Тази страница не може да има под-страници", - "subpages.add.error.more": "Тази страница не може да има повече под-страници", - "subpages.error.missing": "Страницата не може да бъде намерена", - "files": "Файлове", - "files.index.headline": "Файлове за", - "files.index.back": "Назад", - "files.index.upload": "Качете нов файл", - "files.index.upload.first.text": "Тази страница все още няма файлове", - "files.index.upload.first.button": "Качете първия файл", - "files.index.edit": "Редактирай", - "files.index.delete": "Изтрий", - "files.index.error.disabled": "Тази страница не може да има файлове", - "files.add.error.max": "Максималният брой файлове за тази страница бе достигнат.", - "files.add.error.extension.missing": "Не можете да качвате файлове без разширение", - "files.add.error.extension.forbidden": "Забранено файлово разширение", - "files.add.error.mime.forbidden": "Забранен mime type", - "files.add.error.htaccess": "htaccess файл не може да се качи", - "files.add.error.invisible": "Невидимите файлове не могат да бъдат качени", - "files.add.blueprint.type.error": "Страницата позволява:", - "files.add.blueprint.size.error": "Страницата позволява големина на файла ", - "files.show.name.label": "Име на файла", - "files.show.info.label": "Тип / Големина / Размери", - "files.show.link.label": "Публична връзка", - "files.show.open": "Покажи / Свали файла", - "files.show.back": "Назад", - "files.show.replace": "Замести", - "files.show.delete": "Изтрий", - "files.show.error.rename": "Файлът не може да се преименува", - "files.show.error.form": "Моля, попълнете всички полета правилно", - "files.upload.drop": "Пуснете файловете тук...", - "files.upload.click": "... или кликнете за да качите", - "files.replace.drop": "Пуснете файл тук...", - "files.replace.click": "...или кликнете за да замените", - "files.replace.error.type": "Каченият файл трябва да има същия файлов тип", - "files.delete.headline": "Наистина ли искате да изтриете този файл?", - "files.error.missing.page": "Страницата не може да бъде намерена", - "files.error.missing.file": "Файлът не може да бъде намерен", - "users": "Потребители", - "users.index.headline": "Всички потребители", - "users.index.add": "Добавете нов потребител", - "users.index.edit": "Редактирай", - "users.index.delete": "Изтрий", - "users.form.username.label": "Потребителско име", - "users.form.username.placeholder": "Вашето потребителско име", - "users.form.username.help": "Позволени символи: малки букви a-zq 0-9 и тирета", - "users.form.username.readonly": "Потребителското име не може да се променя", - "users.form.firstname.label": "Първо име", - "users.form.lastname.label": "Фамилия", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@example.com", - "users.form.password.label": "Парола", - "users.form.password.confirm.label": "Потвърдете паролата", - "users.form.password.new.label": "Нова парола", - "users.form.password.new.confirm.label": "Потвърдете новата парола", - "users.form.password.new.help": "Оставете празна за да запазите текущата парола", - "users.form.language.label": "Език", - "users.form.role.label": "Роля", - "users.form.options.headline": "Опции на акаунта", - "users.form.options.message": "Изпратете email", - "users.form.options.delete": "Изтрийте акаунт", - "users.form.avatar.headline": "Профилна картинка", - "users.form.avatar.upload": "Качете профилна картинка", - "users.form.avatar.replace": "Заменете профилната картинка", - "users.form.avatar.delete": "Изтрийте профилната картинка", - "users.form.back": "Назад към потребители", - "users.form.error.password.confirm": "Моля, потвърдете паролата", - "users.form.error.update": "Потребителят не може да бъде актуализиран", - "users.form.error.update.rights": "Не ви е позволено да се актуализира този потребител", - "users.form.error.create": "Потребителят не може да бъде създаден", - "users.form.error.permissions.title": "Папката accounts не е записваема", - "users.form.error.permissions.text": "Моля, уверете се, че /site/accounts съществува и е записваема", - "users.delete.headline": "Наистина ли искате да изтриете този потребител?", - "users.delete.error": "Потребителят не може да бъде изтрит", - "users.delete.error.permission": "Не ви е позволено да изтривате потребители", - "users.delete.error.permission.single": "Не е позволено да изтривате този потребител", - "users.delete.error.lastadmin": "Не можете да изтриете последния администратор", - "users.avatar.drop": "Пуснете профилната снимка тук...", - "users.avatar.click": "... или кликнете за да качите", - "users.avatar.error.type": "Можете да качвате само JPG, PNG и GIF файлове.", - "users.avatar.error.folder.headline": "Папката за аватари трябва да е записваема", - "users.avatar.error.folder.text": "Моля създайте папка assets/avatar и я направете записваема за да качвате профилни снимки.", - "users.avatar.error.permission": "Не можете да сменяте профилната снимка", - "users.avatar.delete.error": "Профилната снимка не може да се изтрие", - "users.avatar.delete.error.permission": "Не можете да изтриете профилната снимка на този потребител.", - "users.avatar.delete.success": "Профилната снимка беше изтрита", - "users.avatar.missing": "Този потребител няма профилна снимка", - "users.error.missing": "Потребителят не може да бъде намерен.", - "user.error.lastadmin": "Вие сте само администратор. Това не може да се промени.", - "form.error.missing": "Формата не може да се намери", - "form.construct.error.invalid": "Невалиден form construction method", - "fields.required": "Задължително", - "fields.date.label": "Дата", - "fields.date.months": [ - "Януари", - "Февруари", - "Март", - "Април", - "Май", - "Юни", - "Юли", - "Август", - "Септември", - "Октомври", - "Ноември", - "Декември" - ], - "fields.date.weekdays": [ - "Неделя", - "Понеделник", - "Вторник", - "Сряда", - "Четвъртък", - "Петък", - "Събота" - ], - "fields.date.weekdays.short": [ - "Нд", - "Пн", - "Вт", - "Ср", - "Чт", - "Пт", - "Сб" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@example.com", - "fields.number.label": "Число", - "fields.number.placeholder": "№", - "fields.page.label": "Страница", - "fields.page.placeholder": "път/към/страницата", - "fields.password.label": "Парола", - "fields.structure.add": "Добави", - "fields.structure.add.first": "Добавете първото въвеждане", - "fields.structure.empty": "Няма все още въвеждания", - "fields.structure.entry.error": "Това не може да бъде намерено", - "fields.structure.cancel": "Откажи", - "fields.structure.save": "Ок", - "fields.structure.edit": "Редактирай", - "fields.structure.delete": "Изтрий", - "fields.structure.delete.label": "Наистина ли искате да изтриете това вписване?", - "fields.tags.label": "Етикети", - "fields.tel.label": "Телефон", - "fields.textarea.buttons.bold.label": "Получер шрифт", - "fields.textarea.buttons.bold.text": "Получер шрифт", - "fields.textarea.buttons.italic.label": "Наклонен шрифт", - "fields.textarea.buttons.italic.text": "Наклонен шрифт", - "fields.textarea.buttons.link.label": "Връзка", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Изображение", - "fields.textarea.buttons.file.label": "Файл", - "fields.toggle.yes": "Да", - "fields.toggle.no": "Не", - "fields.toggle.on": "Вкл.", - "fields.toggle.off": "Изкл.", - "fields.error.missing.controller": "field controller файлът липсва", - "fields.error.missing.class": "field controller класът липсва", - "fields.error.route.invalid": "Невалиден field route", - "fields.error.extended": "Полето не може да бъде extended", - "editor.link.url.label": "Вмъкни URL", - "editor.link.text.label": "Текст връзка", - "editor.link.text.help": "Текстовия линк е по избор", - "editor.email.address.label": "Вмъкни email адрес", - "editor.email.address.placeholder": "mail@example.com", - "editor.email.text.label": "Текст връзка", - "editor.email.text.help": "Текстовия линк е по избор", - "editor.file.empty": "Тази страница не съдържа файлове", - "editor.image.empty": "Тази страница няма изображения", - "autocomplete.method.error": "Невалиден метод за автоматично довършване", - "blueprints.error.default.missing": "Липсва blueprint по подразбиране", - "error": "Грешка", - "error.headline": "Грешка" -} \ No newline at end of file diff --git a/panel/app/translations/bg/package.json b/panel/app/translations/bg/package.json deleted file mode 100644 index dc59f74..0000000 --- a/panel/app/translations/bg/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Bulgarian", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/ca/core.json b/panel/app/translations/ca/core.json deleted file mode 100644 index 5b0c208..0000000 --- a/panel/app/translations/ca/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Cancel·lar", - "add": "Afegir", - "addit": "Afegir i Editar", - "save": "Desar", - "saved": "Desat!", - "change": "Canviar", - "delete": "Eliminar", - "insert": "Insertar", - "ok": "Ok", - "routes.error.invalid": "URL del \"Panel\" incorrecte", - "controller.error.invalid": "\"Controller\" incorrecte", - "controller.error.action": "Acció incorrecte", - "view.error.invalid": "Vista incorrecte:", - "options.show": "Mostrar opcions", - "options.hide": "Ocultar opcions", - "installation": "Isntal·lació", - "installation.check.headline": "Instal·lació de Kirby Panel", - "installation.check.text": "Kirby ha trobat els següents problemes durant l'instal·lació…", - "installation.check.retry": "Reintentar", - "installation.check.error": "Hi ha alguns problemes!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts no té permís d'escriptura", - "installation.check.error.avatars": "/assets/avatars no té permís d'escriptura", - "installation.check.error.blueprints": "Afegeix el directori /site/blueprints", - "installation.check.error.content": "El directori de contingut i tots els seus arxius i subdirectoris han de tenir permís d'escriptura.", - "installation.check.error.thumbs": "El directori de \"thumbs\" ha de tenir permís d'escriptura.", - "installation.signup.username.label": "Crea la teva primera compta", - "installation.signup.username.placeholder": "Nom d'usuari", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@exemple.com", - "installation.signup.password.label": "Contrasenya", - "installation.signup.language.label": "Idioma", - "installation.signup.button": "Crea la teva compta", - "login": "Entrar", - "login.welcome": "Entra amb la teva nova compta", - "login.username.label": "Nom d'usuari", - "login.password.label": "Contrasenya", - "login.error": "Nom d'usuari o contrasenya incorrectes", - "login.button": "Entrar", - "login.log.error.permissions": "L'arxiu de log de Login no té permís d'escriptura", - "logout": "Tancar sessió", - "topbar.error.class.definition": "La definició del topbar no s'ha trobat per a la classe:", - "dashboard": "Escriptori", - "dashboard.index.pages.title": "Pàgines", - "dashboard.index.pages.edit": "Editar", - "dashboard.index.pages.add": "Afegir", - "dashboard.index.site.title": "URL de la web", - "dashboard.index.account.title": "La teva compta", - "dashboard.index.account.edit": "Editar", - "dashboard.index.metatags.title": "Opcions de la web", - "dashboard.index.metatags.edit": "Editar", - "dashboard.index.history.title": "Últimes modificacions", - "dashboard.index.history.text": "Aquí es mostraran les últimes modificacions realitzades per facilitar el seu posterior accés.", - "dashboard.index.license.title": "Llicència Kirby", - "dashboard.index.license.text": "Sembla que estàs fent servir Kirby en un servidor públic sense una llicència vàlida!\n\nDona suport a Kirby i (link: {buy} text: compra una llicència ara)\n\nSi ja tens una llicència comprada, afegeix-la al arxiu de configuració: (link: {docs} text: site/config/config.php)", - "metatags": "Opcions de la web", - "metatags.info": "Informació Kirby", - "metatags.license": "Llicència Kirby", - "metatags.version.toolkit": "Versió del Toolkit", - "metatags.version.kirby": "Versió de Kirby", - "metatags.version.panel": "Versió del Panel", - "metatags.back": "Tornar a l'escriptori", - "metatags.files": "Arxius de la web", - "site.delete.error": "La web no es pot eliminar", - "pages.show.settings": "Configuració de la pàgina", - "pages.show.preview": "Obrir vista prèvia", - "pages.show.template": "Plantilla", - "pages.show.changeurl": "Canviar URL", - "pages.show.invisible": "Estat: invisible", - "pages.show.visible": "Estat: visible", - "pages.show.changes.text": "Hi ha canvis pendents de desar!", - "pages.show.changes.button": "Descartar", - "pages.show.delete": "Eliminar aquesta pàgina", - "pages.show.subpages.title": "Pàgines", - "pages.show.subpages.edit": "Editar", - "pages.show.subpages.add": "Afegir", - "pages.show.subpages.empty": "Aquesta pàgina no té cap subpàgina", - "pages.show.files.title": "Arxius", - "pages.show.files.edit": "Editar", - "pages.show.files.add": "Afegir", - "pages.show.files.empty": "Aquesta pàgina no té cap arxiu", - "pages.show.error.permissions.title": "Aquesta pàgina no té permís d'escriptura", - "pages.show.error.permissions.text": "Revisa els permisos del directori de contingut i de tots els seus arxius.", - "pages.show.error.permissions.retry": "Reintentar", - "pages.show.error.notitle.title": "El \"blueprint\" de la pàgina no té cap camp definit per al títol", - "pages.show.error.notitle.text": "Afegeix un camp de títol i torna a intentar-ho", - "pages.show.error.notitle.retry": "Reintentar", - "pages.show.error.form": "Completa tots els camps correctament.", - "pages.add.title.label": "Afegir una nova pàgina", - "pages.add.title.placeholder": "Títol", - "pages.add.url.label": "URL-apèndix", - "pages.add.url.enter": "(introdueix el teu títol)", - "pages.add.url.close": "Tancar", - "pages.add.url.help": "Format: minúscules a-z, 0-9 i guions regulars", - "pages.add.template.label": "Plantilla", - "pages.add.error.create": "La pàgina no pot crear", - "pages.add.error.title": "Falta el títol", - "pages.add.error.template": "La plantilla no s'ha trobat", - "pages.add.error.max.headline": "No es permés afegir noves pàgines", - "pages.add.error.max.text": "S'ha arribat al número màxim de subpàgines per aquesta pàgina.", - "pages.url.uid.label": "URL-apèndix", - "pages.url.uid.label.option": "Crear a partir del títol", - "pages.url.error.exists": "Ja existeix una altra pàgina amb el mateix apèndix", - "pages.url.error.move": "L'apèndix no es pot modificar", - "pages.url.error.rights": "No pots canviar la URL d'aquest pàgina", - "pages.template.select.label": "Plantilla", - "pages.template.warning.text": "Els següents camps canviaran quan canviïs de plantilla", - "pages.template.warning.removed": "Eliminar camps", - "pages.template.warning.replaced": "Reemplaçar camps", - "pages.template.warning.added": "Camps afegits", - "pages.template.error": "La plantilla d'aquesta pàgina no es pot canviar", - "pages.toggle.position": "Posició", - "pages.toggle.invisible": "invisible", - "pages.toggle.publish": "Estàs segur de canviar l'estat de la pàgina a **visible**?", - "pages.toggle.hide": "Estàs segur de canviar l'estat de la pàgina a **invisible**?", - "pages.toggle.error.error": "L'estat de la pàgina d'error no es pot modificar", - "pages.delete.headline": "Estàs segur d'eliminar aquesta pàgina?", - "pages.delete.error.home.headline": "La pàgina d'inici no es pot eliminar", - "pages.delete.error.home.text": "Estàs intentant eliminar la pàgina d'inici. Això no és possible, i donaria lloc a efectes no desitjats.", - "pages.delete.error.error.headline": "La pàgina d'error no es pot eliminar", - "pages.delete.error.error.text": "Estàs intentant eliminar la pàgina d'error. Això no és possible, i donaria lloc a efectes no desitjats.", - "pages.delete.error.children.headline": "La pàgina no es pot eliminar", - "pages.delete.error.children.text": "Aquesta pàgina té subpàgines i no es pot eliminar. Per eliminar-la, cal eliminar primer totes les seves subpàgines.", - "pages.delete.error.blocked.headline": "La pàgina no es pot eliminar", - "pages.delete.error.blocked.text": "Aquesta pàgina esta bloquejada i no es pot eliminar.", - "pages.search.help": "Cercar pàgines per URL. Navega a través dels resultats de la cerca amb les tecles de fletxa cap amunt i cap avall i prem enter per saltar a la pàgina seleccionada.", - "pages.search.noresults": "No hi ha resultats de la cerca realitzada. Intenta-ho de nou amb una altra URL.", - "pages.error.missing": "La pàgina no s'ha trobat", - "subpages": "Pàgines", - "subpages.index.headline": "Pàgines a", - "subpages.index.back": "Tornar", - "subpages.index.add": "Afegir una nova pàgina", - "subpages.index.add.first.text": "Aquesta pàgina encara no té subpàgines", - "subpages.index.add.first.button": "Afegeix la primera pàgina", - "subpages.index.visible": "Pàgines visibles", - "subpages.index.visible.help": "Arrossega les pàgines invisibles aquí per ordenar-les i fer-les visibles.", - "subpages.index.invisible": "Pàgines invisibles", - "subpages.index.invisible.help": "Arrossega les pàgines visibles aquí per fer-les invisibles.", - "subpages.add.error": "Aquesta pàgina no pot tenir subpàgines", - "subpages.add.error.more": "Aquesta pàgina no pot tenir més subpàgines", - "subpages.error.missing": "La pàgina no s'ha trobat", - "files": "Arxius", - "files.index.headline": "Arxius per a", - "files.index.back": "Tornar", - "files.index.upload": "Carregar un nou arxiu", - "files.index.upload.first.text": "Aquesta pàgina encara no té cap arxiu", - "files.index.upload.first.button": "Carregar el primer arxiu", - "files.index.edit": "Editar", - "files.index.delete": "Eliminar", - "files.index.error.disabled": "Aquesta pàgina no pot tenir cap arxiu", - "files.add.error.max": "S'ha arribat al número màxim d'arxius per aquesta pàgina.", - "files.add.error.extension.missing": "No pots carregar arxius sense extensió", - "files.add.error.extension.forbidden": "Extensión de l'arxiu prohibida", - "files.add.error.mime.forbidden": "Mime type de l'arxiu prohibit", - "files.add.error.htaccess": "L'arxiu htaccess no es pot carregar", - "files.add.error.invisible": "Els arxius invisibles no es pode carregar", - "files.add.blueprint.type.error": "La pàgina només accepta:", - "files.add.blueprint.size.error": "La pàgina només accepta arxius amb un volum de", - "files.show.name.label": "Nom de l'arxiu", - "files.show.info.label": "Tipus / Volum / Dimensions", - "files.show.link.label": "Enllaç públic", - "files.show.open": "Mostrar / Descarregar arxiu", - "files.show.back": "Tornar", - "files.show.replace": "Reemplaçar", - "files.show.delete": "Eliminar", - "files.show.error.rename": "L'arxiu no pot ser renombrat", - "files.show.error.form": "Completa tots els camps correctament.", - "files.upload.drop": "Arrossega els arxius aquí…", - "files.upload.click": "… o clica per carregar-los", - "files.replace.drop": "Arrossega l'arxiu aquí…", - "files.replace.click": "… o clica per reeplaçar-lo", - "files.replace.error.type": "L'arxiu carregat ha de ser del mateix tipus", - "files.delete.headline": "Estàs segur d'eliminar aquest arxiu?", - "files.error.missing.page": "La pàgina no s'ha trobat", - "files.error.missing.file": "L'arxiu no s'ha trobat", - "users": "Usuaris", - "users.index.headline": "Tots els usuaris", - "users.index.add": "Afegir un nou usuari", - "users.index.edit": "Editar", - "users.index.delete": "Eliminar", - "users.form.username.label": "Nom d'usuari", - "users.form.username.placeholder": "Nom d'usuari", - "users.form.username.help": "Caràcters permesos: minúscules a-z, 0-9 i guions regulars", - "users.form.username.readonly": "El nom d'usuari no es pot canviar", - "users.form.firstname.label": "Nom", - "users.form.lastname.label": "Cognom", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@exemple.com", - "users.form.password.label": "Contrasenya", - "users.form.password.confirm.label": "Confirmar contrasenya", - "users.form.password.new.label": "Nova contrasenya", - "users.form.password.new.confirm.label": "Confirmar la nova contrasenya", - "users.form.password.new.help": "Deixa en blanc per mantenir la contrasenya actual", - "users.form.language.label": "Idioma", - "users.form.role.label": "Rol", - "users.form.options.headline": "Opcions de la compta", - "users.form.options.message": "Enviar correu electrònic", - "users.form.options.delete": "Eliminar compte", - "users.form.avatar.headline": "Imatge del perfil", - "users.form.avatar.upload": "Carregar imatge del perfil", - "users.form.avatar.replace": "Reemplaçar imatge del perfil", - "users.form.avatar.delete": "Eliminar imatge del perfil", - "users.form.back": "Tornar als usuaris", - "users.form.error.password.confirm": "Confirma la contrasenya", - "users.form.error.update": "L'usuari no s'ha pogut actualitzar", - "users.form.error.update.rights": "No pots actualitzar aquest usuari", - "users.form.error.create": "L'usuari no es pot crear", - "users.form.error.permissions.title": "El directori de comptes no té permís d'escriptura", - "users.form.error.permissions.text": "Assegure't de que el directori /site/accounts existeix i té permís d'escriptura", - "users.delete.headline": "Estàs segur d'eliminar aquest usuari?", - "users.delete.error": "L'usuari no es pot eliminar", - "users.delete.error.permission": "No pots eliminar usuaris", - "users.delete.error.permission.single": "No pots eliminar aquest usuari", - "users.delete.error.lastadmin": "No es pot eliminar l'últim administrador", - "users.avatar.drop": "Arrossega la imatge del perfil aquí…", - "users.avatar.click": "… o clica per carregar-la", - "users.avatar.error.type": "Només pot carregar arxius JPG, PNG i GIF", - "users.avatar.error.folder.headline": "La carpeta avatar no té permís d'escriptura", - "users.avatar.error.folder.text": "Si us plau, creï la carpeta /assets/avatars i doneu-li permisos d'escriptura per a pujar fotos del perfil.", - "users.avatar.error.permission": "No pots modificar l'avatar", - "users.avatar.delete.error": "La imatge del perfil no s'ha pogut eliminar", - "users.avatar.delete.error.permission": "No pots eliminar l'avatar d'aquest usuari", - "users.avatar.delete.success": "La imatge del perfil ha estat eliminada", - "users.avatar.missing": "Aquest usuari no té avatar", - "users.error.missing": "L'usuari no s'ha trobat", - "user.error.lastadmin": "Ets l'únic usuari administrador. No es pot modificar.", - "form.error.missing": "El formulari no s'ha trobat", - "form.construct.error.invalid": "Métode de construcció del formulari incorrecte", - "fields.required": "Obligatori", - "fields.date.label": "Data", - "fields.date.months": [ - "Gener", - "Febrer", - "Març", - "Abril", - "Maig", - "Juny", - "Juliol", - "Agost", - "Setembre", - "Octubre", - "Novembre", - "Desembre" - ], - "fields.date.weekdays": [ - "Diumenge", - "Dilluns", - "Dimarts", - "Dimecres", - "Dijous", - "Divendres", - "Dissabte" - ], - "fields.date.weekdays.short": [ - "dg.", - "dl.", - "dt.", - "dc.", - "dj.", - "dv.", - "ds." - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@exemple.com", - "fields.number.label": "Número", - "fields.number.placeholder": "#", - "fields.page.label": "Pàgina", - "fields.page.placeholder": "ruta/a/pàgina", - "fields.password.label": "Contrasenya", - "fields.structure.add": "Afegir", - "fields.structure.add.first": "Afegir la primera entrada", - "fields.structure.empty": "Encara no hi ha entrades.", - "fields.structure.entry.error": "No s'ha trobat", - "fields.structure.cancel": "Cancel·lar", - "fields.structure.save": "Ok", - "fields.structure.edit": "Editar", - "fields.structure.delete": "Eliminar", - "fields.structure.delete.label": "Estàs segur d'eliminar aquesta entrada?", - "fields.tags.label": "Etiquetes", - "fields.tel.label": "Telèfon", - "fields.textarea.buttons.bold.label": "Texte negreta", - "fields.textarea.buttons.bold.text": "Texte negreta", - "fields.textarea.buttons.italic.label": "Texte cursiva", - "fields.textarea.buttons.italic.text": "Texte cursiva", - "fields.textarea.buttons.link.label": "Enllaç", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Imatge", - "fields.textarea.buttons.file.label": "Arxiu", - "fields.toggle.yes": "Sí", - "fields.toggle.no": "No", - "fields.toggle.on": "Encès", - "fields.toggle.off": "Apagat", - "fields.error.missing.controller": "El \"Controller\" del camp no s'ha trobat", - "fields.error.missing.class": "La classe del \"Controller\" del camp no s'ha trobat", - "fields.error.route.invalid": "Ruta del camp incorrecte", - "fields.error.extended": "El camp no es pot extendre", - "editor.link.url.label": "Inserta URL", - "editor.link.text.label": "Texte enllaçat", - "editor.link.text.help": "L'enllaç és opcional", - "editor.email.address.label": "Inserta adressa d'email", - "editor.email.address.placeholder": "mail@exemple.com", - "editor.email.text.label": "Texte enllaçat", - "editor.email.text.help": "L'enllaç és opcional", - "editor.file.empty": "Aquesta pàgina no té fitxers", - "editor.image.empty": "Aquesta pàgina no té imatges", - "autocomplete.method.error": "Mètode d'autocompletar incorrecte", - "blueprints.error.default.missing": "El \"blueprint\" per defecte no s'ha trobat", - "error": "Error", - "error.headline": "Error" -} \ No newline at end of file diff --git a/panel/app/translations/ca/package.json b/panel/app/translations/ca/package.json deleted file mode 100644 index c1b8934..0000000 --- a/panel/app/translations/ca/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Catalan", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/cs/core.json b/panel/app/translations/cs/core.json deleted file mode 100644 index 437f35d..0000000 --- a/panel/app/translations/cs/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Zrušit", - "add": "Přidat", - "addit": "Přidat a upravit", - "save": "Uložit", - "saved": "Uloženo!", - "change": "Změnit", - "delete": "Smazat", - "insert": "Vložit", - "ok": "Ok", - "routes.error.invalid": "Neplatná URL panelu", - "controller.error.invalid": "Neplatný controller", - "controller.error.action": "Neplatná akce", - "view.error.invalid": "Neplatný view:", - "options.show": "Zobrazit možnosti", - "options.hide": "Skrýt možnosti", - "installation": "Instalace", - "installation.check.headline": "Instalace Kirby Panelu", - "installation.check.text": "Kirby během instalace narazilo na následující problémy…", - "installation.check.retry": "Zkusit znovu", - "installation.check.error": "Nastaly nějaké problémy!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts není zapisovatelné", - "installation.check.error.avatars": "/assets/avatars není zapisovatelné", - "installation.check.error.blueprints": "Prosím přidejte složku /site/blueprints", - "installation.check.error.content": "Složka content a všechny soubory a složky v ní musí být zapisovatelné.", - "installation.check.error.thumbs": "Složka thumbs musí být zapisovatelná.", - "installation.signup.username.label": "Vytvořte svůj první účet", - "installation.signup.username.placeholder": "Uživatelské jméno", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@example.com", - "installation.signup.password.label": "Heslo", - "installation.signup.language.label": "Jazky", - "installation.signup.button": "Vytvořit účet", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Uživatelské jméno", - "login.password.label": "Heslo", - "login.error": "Chybné jméno nebo heslo", - "login.button": "Log in", - "login.log.error.permissions": "Log soubor pro přihlášení není zapisovatelný.", - "logout": "Log out", - "topbar.error.class.definition": "Chybějící topbar definice pro třídu:", - "dashboard": "Přehled", - "dashboard.index.pages.title": "Stránky", - "dashboard.index.pages.edit": "Upravit", - "dashboard.index.pages.add": "Přidat", - "dashboard.index.site.title": "URL vašeho webu", - "dashboard.index.account.title": "Váš účet", - "dashboard.index.account.edit": "Upravit", - "dashboard.index.metatags.title": "Parametry webu", - "dashboard.index.metatags.edit": "Upravit", - "dashboard.index.history.title": "Vaše poslední změny", - "dashboard.index.history.text": "Zde budou zobrazeny stránky, které jste naposledy měnili, abyste k nim měli snadný přístup.", - "dashboard.index.license.title": "Kirby licence", - "dashboard.index.license.text": "It seems you are running Kirby on a public server without a valid license!\n\nPlease, support Kirby and (link: {buy} text: buy a license now)\n\nIf you already have a license key, just add it to your config file: (link: {docs} text: site/config/config.php)", - "metatags": "Parametry webu", - "metatags.info": "Kirby informace", - "metatags.license": "Kirby licence", - "metatags.version.toolkit": "Verze Toolkitu", - "metatags.version.kirby": "Verze Kirby", - "metatags.version.panel": "Verze panelu", - "metatags.back": "Zpět na přehled", - "metatags.files": "Soubory webu", - "site.delete.error": "Tento web nemůže být smazán", - "pages.show.settings": "Nastavení stránky", - "pages.show.preview": "Otevřít náhled", - "pages.show.template": "Šablona", - "pages.show.changeurl": "Změnit URL", - "pages.show.invisible": "Status: neviditelný", - "pages.show.visible": "Status: viditelný", - "pages.show.changes.text": "Máte neuložené změny!", - "pages.show.changes.button": "Zahodit", - "pages.show.delete": "Smazat tuto stránku", - "pages.show.subpages.title": "Stránky", - "pages.show.subpages.edit": "Upravit", - "pages.show.subpages.add": "Přidat", - "pages.show.subpages.empty": "Tato strana nemá podstrany", - "pages.show.files.title": "Soubory", - "pages.show.files.edit": "Upravit", - "pages.show.files.add": "Přidat", - "pages.show.files.empty": "Tato strana nemá soubory", - "pages.show.error.permissions.title": "Tato strana není zapisovatelná", - "pages.show.error.permissions.text": "Prosím zkontrolujte nastavení složky content a všech jejích podsložek a souborů", - "pages.show.error.permissions.retry": "Zkusit znovu", - "pages.show.error.notitle.title": "Blueprint nemá položku title", - "pages.show.error.notitle.text": "Prosím přidejte title a zkuste to znovu", - "pages.show.error.notitle.retry": "Zkusit znovu", - "pages.show.error.form": "Prosím vyplňte správně všechny položky", - "pages.add.title.label": "Přidat novou stránku", - "pages.add.title.placeholder": "Název", - "pages.add.url.label": "Přípona URL", - "pages.add.url.enter": "(vložte svůj název)", - "pages.add.url.close": "Zavřit", - "pages.add.url.help": "Formát: malé a-z, 0-9 a pomlčky", - "pages.add.template.label": "Šablona", - "pages.add.error.create": "Stránka nemohla být vytvořena", - "pages.add.error.title": "Chybí název", - "pages.add.error.template": "Šablona chybí", - "pages.add.error.max.headline": "Nové stránky nejsou povoleny", - "pages.add.error.max.text": "Bylo dosaženo maximálního počtu podstran pro tuto stránku", - "pages.url.uid.label": "Přípona URL", - "pages.url.uid.label.option": "Vytvořit z názvu", - "pages.url.error.exists": "Stránka se stejnou příponou již existuje", - "pages.url.error.move": "Nepodařilo se změnit příponu", - "pages.url.error.rights": "Nemůžete změnit URL této stránky", - "pages.template.select.label": "Šablona", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Pozice", - "pages.toggle.invisible": "neviditelný", - "pages.toggle.publish": "Opravdu chcete změnit status této stránky na **viditelný?**", - "pages.toggle.hide": "Opravdu chcete změnit status této stránky na **neviditelný?**", - "pages.toggle.error.error": "Status této error stránky nemůže být změněn", - "pages.delete.headline": "Opravdu chcete smazat tuto stránku?", - "pages.delete.error.home.headline": "Úvodní stránka nemůže být smazána", - "pages.delete.error.home.text": "Snažíte se smazat úvodní stránka webu. To není možné a způsobilo by to nechtěné problémy.", - "pages.delete.error.error.headline": "Chybová stránka nemůže být smazána", - "pages.delete.error.error.text": "Snažíte se smazat chybovou stránku. To není možné a způsobilo by to nechtěné problémy.", - "pages.delete.error.children.headline": "Stránka nemůže být smazána", - "pages.delete.error.children.text": "Tato stránka má podstránky a proto nemůže být smazána. Nejdříve prosím smažte všechny podstránky.", - "pages.delete.error.blocked.headline": "TStránka nemůže být smazána", - "pages.delete.error.blocked.text": "Tato stránka je zamčená a proto nemůže být smazána.", - "pages.search.help": "Vyhledat stránku pomocí URL. Pro přechod mezi výsledky použijte šipky nahodu a dolů. Pomocí klávesy Enter pak stránku vyberte.", - "pages.search.noresults": "Pro váš dotaz nejsou žádné výsledky. Zkuste to znovu s jinou URL.", - "pages.error.missing": "Stránku se nepodařilo nalézt.", - "subpages": "Stránky", - "subpages.index.headline": "Stránky v", - "subpages.index.back": "Zpět", - "subpages.index.add": "Přidat novou stránku", - "subpages.index.add.first.text": "Tato stránka ještě nemá podstránky", - "subpages.index.add.first.button": "Přidat první stránku", - "subpages.index.visible": "Viditelné stránky", - "subpages.index.visible.help": "Přetáhněte sem neviditelné stránky, pokud je chcete řadit a udělat viditelné.", - "subpages.index.invisible": "Neviditelné stránky", - "subpages.index.invisible.help": "Přetáhněte sem viditelné stránky, pokud je chcete udělat neviditelné a přestat je řadit.", - "subpages.add.error": "Tato stránka nemůže mít podstrany", - "subpages.add.error.more": "Tato stránka nemůže mít žádné další podstrany", - "subpages.error.missing": "Stránku se nepodařilo nalézt", - "files": "Soubory", - "files.index.headline": "Soubory pro", - "files.index.back": "Zpět", - "files.index.upload": "Nahrát nový soubor", - "files.index.upload.first.text": "Tato stránka ješte nemá žádné soubory", - "files.index.upload.first.button": "Nahrajte první soubor", - "files.index.edit": "Upravit", - "files.index.delete": "Smazat", - "files.index.error.disabled": "Tato stránka nemůže mít soubory", - "files.add.error.max": "Bylo dosaženo maximálního počtu souborů pro tuto stránku", - "files.add.error.extension.missing": "Nemůžete nahrát soubor bez přípony", - "files.add.error.extension.forbidden": "Zakázaná přípona souboru", - "files.add.error.mime.forbidden": "Zakázaný mime typ", - "files.add.error.htaccess": "Soubory htaccess nemohou být nahrány", - "files.add.error.invisible": "Neviditelné soubory nemohou být nahrány", - "files.add.blueprint.type.error": "Stránka povoluje pouze:", - "files.add.blueprint.size.error": "Stránka povoluje pouze soubory velikosti", - "files.show.name.label": "Jméno souboru", - "files.show.info.label": "Typ / Velikost / Rozměry", - "files.show.link.label": "Veřejný odkaz", - "files.show.open": "Ukázat/stáhnout soubot", - "files.show.back": "Zpět", - "files.show.replace": "Nahradit", - "files.show.delete": "Smazat", - "files.show.error.rename": "Soubor se nepodařilo odstranit", - "files.show.error.form": "Prosím vyplňte správně všechny položky", - "files.upload.drop": "Sem přetáhněte soubory…", - "files.upload.click": "…nebo klikněte pro nahrání", - "files.replace.drop": "Sem přetáhněte soubor…", - "files.replace.click": "…nebo klikněte pro nahrazení", - "files.replace.error.type": "Nahraný soubor musí být stejného typu", - "files.delete.headline": "Opravdu chcete smazat tento soubor?", - "files.error.missing.page": "Stránku se nepodařilo nalézt", - "files.error.missing.file": "Soubor se nepodařilo nalézt", - "users": "Uživatelé", - "users.index.headline": "Všichni uživatelé", - "users.index.add": "Přidat nového uživatele", - "users.index.edit": "Upravit", - "users.index.delete": "Smazat", - "users.form.username.label": "Uživatelské jméno", - "users.form.username.placeholder": "Vaše uživatelské jméno", - "users.form.username.help": "Povolené znaky: malé a-z, 0-9 a pomlčky", - "users.form.username.readonly": "Uživatelské jméno nelze změnit", - "users.form.firstname.label": "Křestní jméno", - "users.form.lastname.label": "Příjmení", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@example.com", - "users.form.password.label": "Heslo", - "users.form.password.confirm.label": "Potvrdit heslo", - "users.form.password.new.label": "Nové heslo", - "users.form.password.new.confirm.label": "Potvrďte nové heslo", - "users.form.password.new.help": "Nechte prázdné pro zachování současného hesla", - "users.form.language.label": "Jazyk", - "users.form.role.label": "Role", - "users.form.options.headline": "Možnosti účtu", - "users.form.options.message": "Poslat email", - "users.form.options.delete": "Smazat účet", - "users.form.avatar.headline": "Profilový obrázek", - "users.form.avatar.upload": "Nahrát profilový obrázek", - "users.form.avatar.replace": "Nahradit profilový obrázek", - "users.form.avatar.delete": "Smazat profilový obrázek", - "users.form.back": "Zpět na uživatele", - "users.form.error.password.confirm": "Prosím potvrďte heslo", - "users.form.error.update": "Uživatel nemohl být aktualizován", - "users.form.error.update.rights": "Nemáte dovoleno měnit tohoto uživatele", - "users.form.error.create": "Uživatel nemohl být vytvořen", - "users.form.error.permissions.title": "Složka account není zapisovatelná", - "users.form.error.permissions.text": "Prosím ověřte že složka /site/accounts existuje a je zapisovatelná.", - "users.delete.headline": "Opravdu chcete smazat tohoto uživatele?", - "users.delete.error": "Uživatel nemohl být smazán", - "users.delete.error.permission": "Nemáte dovoleno mazat uživatele", - "users.delete.error.permission.single": "Nemáte dovoleno smazat tohoto uživatele", - "users.delete.error.lastadmin": "Nemůžete smazat posledního administrátora", - "users.avatar.drop": "Sem přetáhněte uživatelský obrázek…", - "users.avatar.click": "…nebo klikněte pro nahrání", - "users.avatar.error.type": "Můžete nahrát pouze soubory typu JPG, PNG a GIF", - "users.avatar.error.folder.headline": "Složka avatar není zapisovatelná", - "users.avatar.error.folder.text": "Prosím vytvořte složku /assets/avatars a udělejte jí zapisovatelnou, aby bylo možné nahrát obrázek.", - "users.avatar.error.permission": "Nemáte dovoleno měnit avatara", - "users.avatar.delete.error": "Nebylo možné smazat profilový obrázek", - "users.avatar.delete.error.permission": "Nemáte dovoleno smazat avatara tomuto uživateli", - "users.avatar.delete.success": "Profilový obrázek byl smazán", - "users.avatar.missing": "Tento uživatel žádného avatara nemá", - "users.error.missing": "Uživatele se nepodařilo nalézt", - "user.error.lastadmin": "Jste jediným administrátorem. Toto nelze změnit.", - "form.error.missing": "Formulář se nepovedlo nalézt", - "form.construct.error.invalid": "Neplatná konstrukční metoda formuláře", - "fields.required": "Vyžadované", - "fields.date.label": "Datum", - "fields.date.months": [ - "Leden", - "Únor", - "Březen", - "Duben", - "Květen", - "Červen", - "Červenec", - "Srpen", - "Září", - "Říjen", - "Listopad", - "Prosinec" - ], - "fields.date.weekdays": [ - "neděle", - "pondělí", - "úterý", - "středa", - "čtvrtek", - "pátek", - "sobota" - ], - "fields.date.weekdays.short": [ - "ne", - "po", - "út", - "st", - "čt", - "pá", - "so" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@example.com", - "fields.number.label": "Číslo", - "fields.number.placeholder": "#", - "fields.page.label": "Stránka", - "fields.page.placeholder": "cesta/ke/strance", - "fields.password.label": "Heslo", - "fields.structure.add": "Přidat", - "fields.structure.add.first": "Přidat první záznam", - "fields.structure.empty": "Zatím nejsou žádné záznamy.", - "fields.structure.entry.error": "Položku se nepodařilo najít", - "fields.structure.cancel": "Zrušit", - "fields.structure.save": "Uložit", - "fields.structure.edit": "Upravit", - "fields.structure.delete": "Smazat", - "fields.structure.delete.label": "Opravdu chcete smazat tento záznam?", - "fields.tags.label": "Štítky", - "fields.tel.label": "Telefon", - "fields.textarea.buttons.bold.label": "Tučný text", - "fields.textarea.buttons.bold.text": "Tučný text", - "fields.textarea.buttons.italic.label": "Kurzíva", - "fields.textarea.buttons.italic.text": "Kurzíva", - "fields.textarea.buttons.link.label": "Odkaz", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Obrázek", - "fields.textarea.buttons.file.label": "Soubor", - "fields.toggle.yes": "Ano", - "fields.toggle.no": "Ne", - "fields.toggle.on": "Zap", - "fields.toggle.off": "Vyp", - "fields.error.missing.controller": "Soubor controller pro toto políčko chybí", - "fields.error.missing.class": "Třída controller pro toto políčko chybí", - "fields.error.route.invalid": "Neplatná cesta políčka", - "fields.error.extended": "Toto políčko nemůže být rozšířeno", - "editor.link.url.label": "Cílové URL", - "editor.link.text.label": "Text odkazu", - "editor.link.text.help": "Text odkazu je nepovinný", - "editor.email.address.label": "Vložit emailovou adresu", - "editor.email.address.placeholder": "mail@example.com", - "editor.email.text.label": "Text odkazu", - "editor.email.text.help": "Text odkazu je nepovinný", - "editor.file.empty": "Tato stránka nemá žádné soubory", - "editor.image.empty": "Tato stránka nemá žádné obrázky", - "autocomplete.method.error": "Neplatná našeptávací metoda", - "blueprints.error.default.missing": "Chybí výchozí blueprint", - "error": "Chyba", - "error.headline": "Chyba" -} \ No newline at end of file diff --git a/panel/app/translations/cs/package.json b/panel/app/translations/cs/package.json deleted file mode 100644 index ce3af3d..0000000 --- a/panel/app/translations/cs/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Česky", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/da/core.json b/panel/app/translations/da/core.json deleted file mode 100644 index 0f78264..0000000 --- a/panel/app/translations/da/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Annuller", - "add": "Ny", - "addit": "Tilføj & Rediger", - "save": "Gem", - "saved": "Gemt!", - "change": "Ændre", - "delete": "Slet", - "insert": "Indsæt", - "ok": "Ok", - "routes.error.invalid": "Ugyldig Panel URL", - "controller.error.invalid": "Ugyldig controller", - "controller.error.action": "Ugyldig handling", - "view.error.invalid": "Ugyldig visning:", - "options.show": "Vis indstillinger", - "options.hide": "Skjul indstillinger", - "installation": "Installation", - "installation.check.headline": "Kirby Panel Installation", - "installation.check.text": "Kirby stødte på følgende problemer under installationen…", - "installation.check.retry": "Prøv igen", - "installation.check.error": "Der er nogle problemer!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts er ikke skrivbar", - "installation.check.error.avatars": "/assets/avatars er ikke skrivbar", - "installation.check.error.blueprints": "Tilføj venligst en /site/blueprints mappe", - "installation.check.error.content": "Content mappen samt alle underliggende filer og mapper skal være skrivbare.", - "installation.check.error.thumbs": "Thumbs mappen skal være skrivbar.", - "installation.signup.username.label": "Opret din første konto", - "installation.signup.username.placeholder": "Brugernavn", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@eksempel.dk", - "installation.signup.password.label": "Adgangskode", - "installation.signup.language.label": "Sprog", - "installation.signup.button": "Opret din konto", - "login": "Log ind", - "login.welcome": "Log ind med din nye konto", - "login.username.label": "Brugernavn", - "login.password.label": "Adgangskode", - "login.error": "Ugyldigt brugernavn eller adgangskode", - "login.button": "Log ind", - "login.log.error.permissions": "Login log fil er ikke skrivbar", - "logout": "Log ud", - "topbar.error.class.definition": "Mangler topbar definition for class:", - "dashboard": "Dashboard", - "dashboard.index.pages.title": "Sider", - "dashboard.index.pages.edit": "Rediger", - "dashboard.index.pages.add": "Tilføj", - "dashboard.index.site.title": "Dit websites URL", - "dashboard.index.account.title": "Din konto", - "dashboard.index.account.edit": "Rediger", - "dashboard.index.metatags.title": "Website indstillinger", - "dashboard.index.metatags.edit": "Rediger", - "dashboard.index.history.title": "Dine seneste opdateringer", - "dashboard.index.history.text": "Dine seneste opdaterede sider vil blive vist her, for at gøre det nemt at finde dem igen senere.", - "dashboard.index.license.title": "Kirby licens", - "dashboard.index.license.text": "Det ser ud til at du kører Kirby på en offentlig server uden en gyldig licens!\n\nStøt venligst Kirby og (link: {buy} text: køb en licens nu)\n\nHar du allerede en licens nøgle, kan du blot tilføje den i din config fil: (link: {docs} text: site/config/config.php)", - "metatags": "Website indstillinger", - "metatags.info": "Kirby info", - "metatags.license": "Kirby licens", - "metatags.version.toolkit": "Toolkit version", - "metatags.version.kirby": "Kirby version", - "metatags.version.panel": "Panel version", - "metatags.back": "Tilbage til dashboard", - "metatags.files": "Website filer", - "site.delete.error": "Sitet kan ikke slettes", - "pages.show.settings": "Side indstillinger", - "pages.show.preview": "Se eksempel", - "pages.show.template": "Skabelon", - "pages.show.changeurl": "Ændre URL", - "pages.show.invisible": "Status: usynlig", - "pages.show.visible": "Status: synlig", - "pages.show.changes.text": "Du har ugemte ændringer!", - "pages.show.changes.button": "Kassér", - "pages.show.delete": "Slet denne side", - "pages.show.subpages.title": "Sider", - "pages.show.subpages.edit": "Rediger", - "pages.show.subpages.add": "Tilføj", - "pages.show.subpages.empty": "Denne side har ingen undersider", - "pages.show.files.title": "Filer", - "pages.show.files.edit": "Rediger", - "pages.show.files.add": "Tilføj", - "pages.show.files.empty": "Denne side har ingen filer", - "pages.show.error.permissions.title": "Siden er ikke skrivbar", - "pages.show.error.permissions.text": "Kontroller venligst skriverettigheder for content mappen samt alle filer.", - "pages.show.error.permissions.retry": "Prøv igen", - "pages.show.error.notitle.title": "Dette blueprint har intet titel-felt", - "pages.show.error.notitle.text": "Tilføj venligst et titel-felt og prøv igen", - "pages.show.error.notitle.retry": "Prøv igen", - "pages.show.error.form": "Udfyld venligst alle felter korrekt", - "pages.add.title.label": "Tilføj en ny side", - "pages.add.title.placeholder": "Titel", - "pages.add.url.label": "URL-appendiks", - "pages.add.url.enter": "(indtast din titel)", - "pages.add.url.close": "Luk", - "pages.add.url.help": "Format: små bogstaver a-z, 0-9 samt almindelige bindestreger", - "pages.add.template.label": "Skabelon", - "pages.add.error.create": "Siden kunne ikke oprettes", - "pages.add.error.title": "Titlen mangler", - "pages.add.error.template": "Skabelonen manger", - "pages.add.error.max.headline": "Der tillades ikke nye sider", - "pages.add.error.max.text": "Det maksimale antal undersider for denne side er nået.", - "pages.url.uid.label": "URL-appendiks", - "pages.url.uid.label.option": "Generer udfra titel", - "pages.url.error.exists": "En side med samme appendiks eksisterer allerede", - "pages.url.error.move": "URL-appendikset kunne ikke ændres", - "pages.url.error.rights": "Du kan ikke ændre denne sides URL", - "pages.template.select.label": "Skabelon", - "pages.template.warning.text": "Følgende felter ændres, hvis du skifter skabelon", - "pages.template.warning.removed": "Fjernede felter", - "pages.template.warning.replaced": "Erstattede felter", - "pages.template.warning.added": "Tilføjede felter", - "pages.template.error": "Skabelonen for denne side kan ikke ændres", - "pages.toggle.position": "Position", - "pages.toggle.invisible": "usynlig", - "pages.toggle.publish": "Ønsker du virkelig at ændre denne sides status til **synlig?**", - "pages.toggle.hide": "Ønsker du virkelig at ændre denne sides status til **usynlig?**", - "pages.toggle.error.error": "Status for fejl-siden kan ikke ændres", - "pages.delete.headline": "Ønsker du virkelig at slette denne side?", - "pages.delete.error.home.headline": "Forsiden kunne ikke slettes", - "pages.delete.error.home.text": "Du forsøger at slette forsiden. Dette er ikke muligt da det ville lede til en uønsket oplevelse.", - "pages.delete.error.error.headline": "Fejlsiden kan ikke slettes", - "pages.delete.error.error.text": "Du forsøger at slette fejlsiden. Dette er ikke muligt da det ville lede til en uønsket oplevelse.", - "pages.delete.error.children.headline": "Siden kan ikke slettes", - "pages.delete.error.children.text": "Denne side har undersider og kan derfor ikke slettes. Slet venligst alle undersider først.", - "pages.delete.error.blocked.headline": "Siden kan ikke slettes", - "pages.delete.error.blocked.text": "Denne side er låst og kan derfor ikke slettes.", - "pages.search.help": "Søg efter sider udfra URL. Naviger igennem søgeresultater med dine op- og ned-piletaster og tryk enter for at hoppe til den valgte side.", - "pages.search.noresults": "Søgningen gav intet resultat. Prøv venligst igen med en anden URL.", - "pages.error.missing": "Siden kunne ikke findes", - "subpages": "Sider", - "subpages.index.headline": "Sider i", - "subpages.index.back": "Tilbage", - "subpages.index.add": "Tilføj en ny side", - "subpages.index.add.first.text": "Denne side har ingen undersider endnu", - "subpages.index.add.first.button": "Tilføj den første side", - "subpages.index.visible": "Synlige sider", - "subpages.index.visible.help": "Træk usynlige sider hertil for at sortere dem og gøre dem synlige.", - "subpages.index.invisible": "Usynlige sider", - "subpages.index.invisible.help": "Træk synlige sider hertil for at gøre dem usynlige.", - "subpages.add.error": "Denne side må ikke have undersider", - "subpages.add.error.more": "Denne side kan ikke have flere undersider", - "subpages.error.missing": "Siden kunne ikke findes", - "files": "Filer", - "files.index.headline": "Filer for", - "files.index.back": "Tilbage", - "files.index.upload": "Upload en ny fil", - "files.index.upload.first.text": "Denne side har ingen filer endnu", - "files.index.upload.first.button": "Upload den første fil", - "files.index.edit": "Rediger", - "files.index.delete": "Slet", - "files.index.error.disabled": "Denne side må ikke have filer", - "files.add.error.max": "Det maksimale antal filer for denne side er nået.", - "files.add.error.extension.missing": "Du kan ikke uploade filer uden fil-endelse", - "files.add.error.extension.forbidden": "Uacceptabel fil-endelse", - "files.add.error.mime.forbidden": "Uacceptabel fil-type", - "files.add.error.htaccess": "htaccess filer kan ikke uploades", - "files.add.error.invisible": "Usynlige filer kan ikke uploades", - "files.add.blueprint.type.error": "Siden tillader kun:", - "files.add.blueprint.size.error": "Siden tillader kun en fil-størrelse på:", - "files.show.name.label": "Filnavn", - "files.show.info.label": "Type / Vægt / Dimensioner", - "files.show.link.label": "Offentligt link", - "files.show.open": "Se og hent fil", - "files.show.back": "Tilbage", - "files.show.replace": "Erstat", - "files.show.delete": "Slet", - "files.show.error.rename": "Filen kunne ikke omdøbes", - "files.show.error.form": "Udfyld venligst alle felter korrekt", - "files.upload.drop": "Træk filer hertil…", - "files.upload.click": "…eller klik for at uploade", - "files.replace.drop": "Træk en fil hertil…", - "files.replace.click": "…eller klik for at erstatte", - "files.replace.error.type": "Den valgte fil skal være af samme filtype", - "files.delete.headline": "Ønsker du virkelig at slette denne fil?", - "files.error.missing.page": "Siden kunne ikke findes", - "files.error.missing.file": "Filen kunne ikke findes", - "users": "Brugere", - "users.index.headline": "Alle brugere", - "users.index.add": "Tilføj en ny bruger", - "users.index.edit": "Rediger", - "users.index.delete": "Slet", - "users.form.username.label": "Brugernavn", - "users.form.username.placeholder": "Dit brugernavn", - "users.form.username.help": "Tilladte tegn: små bogstaver a-z, 0-9 og bindestreger", - "users.form.username.readonly": "Brugernavnet kan ikke ændres", - "users.form.firstname.label": "Fornavn", - "users.form.lastname.label": "Efternavn", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@eksempel.dk", - "users.form.password.label": "Adgangskode", - "users.form.password.confirm.label": "Bekræft adgangskode", - "users.form.password.new.label": "Ny adgangskode", - "users.form.password.new.confirm.label": "Bekræft den nye adgangskode", - "users.form.password.new.help": "Lad stå tomt for at beholde den nuværende adgangskode", - "users.form.language.label": "Sprog", - "users.form.role.label": "Rolle", - "users.form.options.headline": "Konto instillinger", - "users.form.options.message": "Send email", - "users.form.options.delete": "Slet konto", - "users.form.avatar.headline": "Profilbillede", - "users.form.avatar.upload": "Upload profilbillede", - "users.form.avatar.replace": "Erstat profilbillede", - "users.form.avatar.delete": "Slet profilbillede", - "users.form.back": "Tilbage til brugere", - "users.form.error.password.confirm": "Bekræft venligst adgangskoden", - "users.form.error.update": "Brugeren kunne ikke redigeres", - "users.form.error.update.rights": "Du har ikke tilladelse til at opdatere denne bruger", - "users.form.error.create": "Brugeren kunne ikke oprettes", - "users.form.error.permissions.title": "Account mappen er ikke skrivbar", - "users.form.error.permissions.text": "Sørg venligst for at /site/accounts eksisterer og er skrivbar.", - "users.delete.headline": "Ønsker du virkelig at slette denne bruger?", - "users.delete.error": "Brugeren kunne ikke slettes", - "users.delete.error.permission": "Du har ikke tilladelse til at slette brugere", - "users.delete.error.permission.single": "Du har ikke tilladelse til at slette denne bruger", - "users.delete.error.lastadmin": "Du kan ikke slette den sidste admin", - "users.avatar.drop": "Træk et profilbillede hertil…", - "users.avatar.click": "…eller klik for at vælge", - "users.avatar.error.type": "Du kan kun uploade JPG, PNG og GIF filer", - "users.avatar.error.folder.headline": "Avatar mappen er ikke skrivbar", - "users.avatar.error.folder.text": "Opret venligst mappen /assets/avatars og sørg for at den er skrivbar for at kunne uploade profilbilleder.", - "users.avatar.error.permission": "Du har ikke tilladelse til at ændre avatar", - "users.avatar.delete.error": "Profilbilledet kunne ikke slettes", - "users.avatar.delete.error.permission": "Du har ikke tilladelse til at slette denne brugers avatar", - "users.avatar.delete.success": "Profilbilledet er nu slettet", - "users.avatar.missing": "Denne bruger har ikke nogen avatar", - "users.error.missing": "Brugeren kunne ikke findes", - "user.error.lastadmin": "Du er den eneste admin. Dette kan ikke ændres.", - "form.error.missing": "Formularen kunne ikke findes", - "form.construct.error.invalid": "Ugyldig formular construction method", - "fields.required": "Påkrævet", - "fields.date.label": "Dato", - "fields.date.months": [ - "Januar", - "Februar", - "Marts", - "April", - "Maj", - "Juni", - "Juli", - "August", - "September", - "Oktober", - "November", - "December" - ], - "fields.date.weekdays": [ - "Søndag", - "Mandag", - "Tirsdag", - "Onsdag", - "Torsdag", - "Fredag", - "Lørdag" - ], - "fields.date.weekdays.short": [ - "Søn", - "Man", - "Tir", - "Ons", - "Tor", - "Fre", - "Lør" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@eksempel.dk", - "fields.number.label": "Nummer", - "fields.number.placeholder": "#", - "fields.page.label": "Side", - "fields.page.placeholder": "sti/til/side", - "fields.password.label": "Adgangskode", - "fields.structure.add": "Tilføj", - "fields.structure.add.first": "Tilføj den første indtastning", - "fields.structure.empty": "Ingen indtastninger endnu.", - "fields.structure.entry.error": "Emnet blev ikke fundet", - "fields.structure.cancel": "Annuller", - "fields.structure.save": "Gem", - "fields.structure.edit": "Rediger", - "fields.structure.delete": "Slet", - "fields.structure.delete.label": "Ønsker du virkelig at slette denne indtastning?", - "fields.tags.label": "Tags", - "fields.tel.label": "Telefon", - "fields.textarea.buttons.bold.label": "Fed tekst", - "fields.textarea.buttons.bold.text": "Fed tekst", - "fields.textarea.buttons.italic.label": "Kursiv tekst", - "fields.textarea.buttons.italic.text": "Kursiv tekst", - "fields.textarea.buttons.link.label": "Link", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Billede", - "fields.textarea.buttons.file.label": "Fil", - "fields.toggle.yes": "Ja", - "fields.toggle.no": "Nej", - "fields.toggle.on": "Til", - "fields.toggle.off": "Fra", - "fields.error.missing.controller": "En field controller fil mangler", - "fields.error.missing.class": "En field controller class mangler", - "fields.error.route.invalid": "Ugyldig field route", - "fields.error.extended": "Field kan ikke blive extended", - "editor.link.url.label": "Indsæt URL", - "editor.link.text.label": "Link tekst", - "editor.link.text.help": "Link tekst er valgfri", - "editor.email.address.label": "Indsæt email adresse", - "editor.email.address.placeholder": "mail@eksempel.dk", - "editor.email.text.label": "Link tekst", - "editor.email.text.help": "Link tekst er valgfri", - "editor.file.empty": "Denne side har ingen filer", - "editor.image.empty": "Denne side har ingen billeder", - "autocomplete.method.error": "Ugyldig autocomplete method", - "blueprints.error.default.missing": "Mangler standard blueprint", - "error": "Fejl", - "error.headline": "Fejl" -} \ No newline at end of file diff --git a/panel/app/translations/da/package.json b/panel/app/translations/da/package.json deleted file mode 100644 index 24abc8f..0000000 --- a/panel/app/translations/da/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Dansk", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/de/core.json b/panel/app/translations/de/core.json deleted file mode 100644 index d442019..0000000 --- a/panel/app/translations/de/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Abbrechen", - "add": "Hinzufügen", - "addit": "Hinzufügen & Bearbeiten", - "save": "Speichern", - "saved": "Gespeichert!", - "change": "Ändern", - "delete": "Löschen", - "insert": "Einfügen", - "ok": "Ok", - "routes.error.invalid": "Ungültige Panel-URL", - "controller.error.invalid": "Ungültiger Controller", - "controller.error.action": "Ungültige Aktion", - "view.error.invalid": "Ungültiger View:", - "options.show": "Optionen einblenden", - "options.hide": "Optionen ausblenden", - "installation": "Installation", - "installation.check.headline": "Kirby Panel Installation", - "installation.check.text": "Kirby hat die folgenden Probleme festgestellt…", - "installation.check.retry": "Wiederholen", - "installation.check.error": "Es gibt einige Probleme!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts ist nicht beschreibbar", - "installation.check.error.avatars": "/assets/avatars ist nicht beschreibbar", - "installation.check.error.blueprints": "Bitte lege den Ordner /site/blueprints an", - "installation.check.error.content": "/content und alle Inhalte müssen beschreibbar sein.", - "installation.check.error.thumbs": "/thumbs muss vorhanden und beschreibbar sein.", - "installation.signup.username.label": "Erstelle den ersten Benutzer", - "installation.signup.username.placeholder": "Benutzername", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@beispiel.de", - "installation.signup.password.label": "Passwort", - "installation.signup.language.label": "Sprache", - "installation.signup.button": "Erstellen", - "login": "Anmelden", - "login.welcome": "Bitte melde dich mit deinem neuen Account an", - "login.username.label": "Benutzername", - "login.password.label": "Passwort", - "login.error": "Ungültiger Benutzername oder Passwort", - "login.button": "Anmelden", - "login.log.error.permissions": "Die Anmeldelog-Datei ist nicht beschreibbar.", - "logout": "Abmelden", - "topbar.error.class.definition": "Fehlende Topbar-Definition für Klasse:", - "dashboard": "Übersicht", - "dashboard.index.pages.title": "Seiten", - "dashboard.index.pages.edit": "Bearbeiten", - "dashboard.index.pages.add": "Hinzufügen", - "dashboard.index.site.title": "Seite", - "dashboard.index.account.title": "Dein Account", - "dashboard.index.account.edit": "Bearbeiten", - "dashboard.index.metatags.title": "Einstellungen", - "dashboard.index.metatags.edit": "Bearbeiten", - "dashboard.index.history.title": "Deine letzten Änderungen", - "dashboard.index.history.text": "Sobald du die ersten Änderungen an Seiten vornimmst, werden sie hier aufgelistet, um jeder Zeit schnell darauf zugreifen zu können.", - "dashboard.index.license.title": "Kirby Lizenz", - "dashboard.index.license.text": "Scheinbar nutzt Du Kirby auf einem öffentlichen Server ohne gültige Lizenz!\n\nBitte unterstütze Kirby und (link: {buy} text: kaufe jetzt eine Lizenz)\n\nWenn Du bereits einen Lizenzschlüssel hast, füge ihn zur Config-Datei hinzu: (link: {docs} text: site/config/config.php)", - "metatags": "Einstellungen", - "metatags.info": "Kirby Information", - "metatags.license": "Kirby Lizenz", - "metatags.version.toolkit": "Toolkit Version", - "metatags.version.kirby": "Kirby Version", - "metatags.version.panel": "Panel Version", - "metatags.back": "Zurück zur Übersicht", - "metatags.files": "Globale Dateien", - "site.delete.error": "Die Seite kann nicht gelöscht werden", - "pages.show.settings": "Seiteneinstellungen", - "pages.show.preview": "Seite öffnen", - "pages.show.template": "Vorlage", - "pages.show.changeurl": "URL ändern", - "pages.show.invisible": "Status: unsichtbar", - "pages.show.visible": "Status: sichtbar", - "pages.show.changes.text": "Du hast ungespeicherte Änderungen!", - "pages.show.changes.button": "Verwerfen", - "pages.show.delete": "Seite löschen", - "pages.show.subpages.title": "Seiten", - "pages.show.subpages.edit": "Bearbeiten", - "pages.show.subpages.add": "Hinzufügen", - "pages.show.subpages.empty": "Diese Seite hat keine Unterseiten", - "pages.show.files.title": "Dateien", - "pages.show.files.edit": "Bearbeiten", - "pages.show.files.add": "Hinzufügen", - "pages.show.files.empty": "Diese Seite hat keine Dateien", - "pages.show.error.permissions.title": "Die Seite ist nicht beschreibbar", - "pages.show.error.permissions.text": "Bitte überprüfe die Schreibrechte für /content und alle Inhalte", - "pages.show.error.permissions.retry": "Wiederholen", - "pages.show.error.notitle.title": "Das Blueprint hat kein Titelfeld", - "pages.show.error.notitle.text": "Bitte füge ein Titelfeld ein und versuche es erneut", - "pages.show.error.notitle.retry": "Wiederholen", - "pages.show.error.form": "Bitte fülle alle Felder vollständig und korrekt aus", - "pages.add.title.label": "Eine neue Seite hinzufügen", - "pages.add.title.placeholder": "Titel", - "pages.add.url.label": "URL-Anhang", - "pages.add.url.enter": "(URL eingeben)", - "pages.add.url.close": "Schließen", - "pages.add.url.help": "Format: Kleinbuchstaben a-z, 0-9 und Bindestriche", - "pages.add.template.label": "Vorlage", - "pages.add.error.create": "Die Seite konnte nicht hinzugefügt werden", - "pages.add.error.title": "Der Titel fehlt", - "pages.add.error.template": "Die Vorlage fehlt", - "pages.add.error.max.headline": "Keine weiteren Unterseiten zugelassen", - "pages.add.error.max.text": "Die maximale Anzahl an Unterseiten für die aktuelle Seite ist erreicht.", - "pages.url.uid.label": "URL-Anhang", - "pages.url.uid.label.option": "Aus Titel erzeugen", - "pages.url.error.exists": "Eine Seite mit dem selben Anhang besteht bereits.", - "pages.url.error.move": "Die URL konnte nicht geändert werden", - "pages.url.error.rights": "Du kannst die URL dieser Seite nicht ändern", - "pages.template.select.label": "Vorlage", - "pages.template.warning.text": "Folgende Felder werden sich ändern, wenn du die Vorlage wechselst. ", - "pages.template.warning.removed": "Gelöschte Felder", - "pages.template.warning.replaced": "Ersetzte Felder", - "pages.template.warning.added": "Hinzugefügte Felder", - "pages.template.error": "Die Vorlage für diese Seite kann nicht geändert werden", - "pages.toggle.position": "Position", - "pages.toggle.invisible": "unsichtbar", - "pages.toggle.publish": "Willst du den Status der Seite wirklich in **sichtbar** umändern?", - "pages.toggle.hide": "Willst du den Status der Seite wirklich in **unsichtbar** umändern?", - "pages.toggle.error.error": "Der Status der Fehlerseite kann nicht geändert werden", - "pages.delete.headline": "Willst du diese Seite wirklich löschen?", - "pages.delete.error.home.headline": "Die Startseite kann nicht gelöscht werden", - "pages.delete.error.home.text": "Du versuchst die Startseite zu löschen. Das ist nicht möglich und würde zu ungewollten Fehlern führen.", - "pages.delete.error.error.headline": "Die Fehlerseite kann nicht gelöscht werden", - "pages.delete.error.error.text": "Du versuchst die Fehlerseite zu löschen. Das ist nicht möglich und würde zu ungewollten Fehlern führen.", - "pages.delete.error.children.headline": "Die Seite kann nicht gelöscht werden", - "pages.delete.error.children.text": "Die Seite hat Unterseiten und kann daher nicht gelöscht werden. Bitte entferne zuerst alle Unterseiten.", - "pages.delete.error.blocked.headline": "Die Seite kann nicht gelöscht werden", - "pages.delete.error.blocked.text": "Die Seite ist blockiert und kann daher nicht gelöscht werden.", - "pages.search.help": "Durchsuche alle Seiten nach URL-Pfad. Du kannst dich durch Ergebnisse mit den Pfeiltasten bewegen und per Enter zur ausgewählten Seite springen.", - "pages.search.noresults": "Es gibt leider keine Seiten zu deiner Suche. Bitte versuche es mit einem anderen Pfad.", - "pages.error.missing": "Die Seite konnte nicht gefunden werden", - "subpages": "Seiten", - "subpages.index.headline": "Seiten in", - "subpages.index.back": "Zurück", - "subpages.index.add": "Neue Seite anlegen", - "subpages.index.add.first.text": "Diese Seite hat noch keine Unterseiten", - "subpages.index.add.first.button": "Lege die erste Seite an", - "subpages.index.visible": "Sichtbare Seiten", - "subpages.index.visible.help": "Ziehe unsichtbare Seiten hierher, um sie zu sortieren/sichtbar zu machen", - "subpages.index.invisible": "Unsichtbare Seiten", - "subpages.index.invisible.help": "Ziehe sichtbare Seiten hierher, um sie unsichtbar zu machen", - "subpages.add.error": "Diese Seite darf keine Unterseiten haben", - "subpages.add.error.more": "Diese Seite kann keine weiteren Unterseiten haben", - "subpages.error.missing": "Die Seite konnte nicht gefunden werden.", - "files": "Dateien", - "files.index.headline": "Dateien für", - "files.index.back": "Zurück", - "files.index.upload": "Neue Datei hochladen", - "files.index.upload.first.text": "Diese Seite hat noch keine Dateien", - "files.index.upload.first.button": "Lade die erste Datei hoch", - "files.index.edit": "Bearbeiten", - "files.index.delete": "Löschen", - "files.index.error.disabled": "Diese Seite darf keine Dateien haben", - "files.add.error.max": "Die maximale Anzahl an Dateien für die aktuelle Seite ist erreicht.", - "files.add.error.extension.missing": "Du kannst keine Dateien ohne Dateiendung hochladen", - "files.add.error.extension.forbidden": "Verbotene Dateiendung", - "files.add.error.mime.forbidden": "Verbotener MIME-Typ", - "files.add.error.htaccess": "htaccess-Dateien können nicht hochgeladen werden", - "files.add.error.invisible": "Versteckte Dateien können nicht hochgeladen werden", - "files.add.blueprint.type.error": "Seite erlaubt nur:", - "files.add.blueprint.size.error": "Seite erlaubt nur eine Dateigröße von", - "files.show.name.label": "Dateiname", - "files.show.info.label": "Typ / Größe / Abmessungen", - "files.show.link.label": "Öffentlicher Link", - "files.show.open": "Anzeigen/Download", - "files.show.back": "Zurück", - "files.show.replace": "Ersetzen", - "files.show.delete": "Löschen", - "files.show.error.rename": "Die Datei konnte nicht umbenannt werden", - "files.show.error.form": "Bitte fülle alle Felder vollständig aus", - "files.upload.drop": "Ziehe Dateien hierher…", - "files.upload.click": "…oder klicke, um Dateien hochzuladen", - "files.replace.drop": "Ziehe eine Datei hierher…", - "files.replace.click": "…oder klicke, um die Datei zu ersetzen", - "files.replace.error.type": "Die hochgeladene Datei muss den selben Dateityp haben", - "files.delete.headline": "Willst du diese Datei wirklich löschen?", - "files.error.missing.page": "Die Seite konnte nicht gefunden werden", - "files.error.missing.file": "Die Datei konnte nicht gefunden werden", - "users": "Benutzer", - "users.index.headline": "Alle Benutzer", - "users.index.add": "Neuen Benutzer anlegen", - "users.index.edit": "Bearbeiten", - "users.index.delete": "Löschen", - "users.form.username.label": "Benutzername", - "users.form.username.placeholder": "Dein Benutzername", - "users.form.username.help": "Format: Kleinbuchstaben a-z, 0-9 und Bindestriche", - "users.form.username.readonly": "Der Benutzername kann nicht geändert werden", - "users.form.firstname.label": "Vorname", - "users.form.lastname.label": "Nachname", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@beispiel.de", - "users.form.password.label": "Passwort", - "users.form.password.confirm.label": "Passwort bestätigen", - "users.form.password.new.label": "Neues Passwort", - "users.form.password.new.confirm.label": "Neues Passwort bestätigen", - "users.form.password.new.help": "Leer lassen, um das aktuelle Passwort zu behalten", - "users.form.language.label": "Sprache", - "users.form.role.label": "Rolle", - "users.form.options.headline": "Accounteinstellungen", - "users.form.options.message": "Email schicken", - "users.form.options.delete": "Account löschen", - "users.form.avatar.headline": "Profilbild", - "users.form.avatar.upload": "Profilbild hochladen", - "users.form.avatar.replace": "Profilbild ersetzen", - "users.form.avatar.delete": "Profilbild löschen", - "users.form.back": "Zurück zur Benutzerübersicht", - "users.form.error.password.confirm": "Bitte bestätige das Passwort", - "users.form.error.update": "Der Benutzer konnte nicht gespeichert werden", - "users.form.error.update.rights": "Du darfst diesen Benutzer nicht aktualisieren", - "users.form.error.create": "Der Benutzer konnte nicht erstellt werden", - "users.form.error.permissions.title": "Der accounts Ordner ist nicht beschreibbar", - "users.form.error.permissions.text": "Bitte stelle sicher, dass /site/accounts besteht und beschreibbar ist.", - "users.delete.headline": "Willst du diesen Benutzer wirklich löschen?", - "users.delete.error": "Der Benutzer konnte nicht gelöscht werden", - "users.delete.error.permission": "Du darfst keine Benutzer löschen", - "users.delete.error.permission.single": "Du darfst diesen Benutzer nicht löschen", - "users.delete.error.lastadmin": "Du kannst den letzten Admin nicht löschen", - "users.avatar.drop": "Ziehe ein Profilbild hierher…", - "users.avatar.click": "…oder klicke, um ein Profilbild hochzuladen", - "users.avatar.error.type": "Es sind nur JPG, PNG und GIF Dateien erlaubt.", - "users.avatar.error.folder.headline": "Der Profilbild Ordner ist nicht beschreibbar", - "users.avatar.error.folder.text": "Bitte erstelle den Ordner /assets/avatars und stelle sicher, dass er beschreibbar ist.", - "users.avatar.error.permission": "Du darfst den Avatar nicht verändern", - "users.avatar.delete.error": "Das Profilbild konnte nicht gelöscht werden", - "users.avatar.delete.error.permission": "Du darfst den Avater dieses Users nicht löschen", - "users.avatar.delete.success": "Das Profilbild wurde gelöscht", - "users.avatar.missing": "Der Benutzer hat kein Profilbild", - "users.error.missing": "Der Benutzer wurde nicht gefunden", - "user.error.lastadmin": "Du bist der letzte Admin. Das kann nicht verändert werden.", - "form.error.missing": "Das Formular kann nicht gefunden werden", - "form.construct.error.invalid": "Ungültiger Formularkonstruktor", - "fields.required": "Pflichtfeld", - "fields.date.label": "Datum", - "fields.date.months": [ - "Januar", - "Februar", - "März", - "April", - "Mai", - "Juni", - "Juli", - "August", - "September", - "Oktober", - "November", - "Dezember" - ], - "fields.date.weekdays": [ - "Sonntag", - "Montag", - "Dienstag", - "Mittwoch", - "Donnerstag", - "Freitag", - "Samstag" - ], - "fields.date.weekdays.short": [ - "So", - "Mo", - "Di", - "Mi", - "Do", - "Fr", - "Sa" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@beispiel.de", - "fields.number.label": "Nummer", - "fields.number.placeholder": "#", - "fields.page.label": "Seite", - "fields.page.placeholder": "pfad/zur/seite", - "fields.password.label": "Passwort", - "fields.structure.add": "Hinzufügen", - "fields.structure.add.first": "Füge den ersten Eintrag hinzu", - "fields.structure.empty": "Es bestehen keine Einträge.", - "fields.structure.entry.error": "Der Eintrag konnte nicht gefunden werden", - "fields.structure.cancel": "Abbrechen", - "fields.structure.save": "Ok", - "fields.structure.edit": "Bearbeiten", - "fields.structure.delete": "Löschen", - "fields.structure.delete.label": "Willst du diesen Eintrag wirklich löschen?", - "fields.tags.label": "Tags", - "fields.tel.label": "Telefon", - "fields.textarea.buttons.bold.label": "Fetter Text", - "fields.textarea.buttons.bold.text": "Fetter Text", - "fields.textarea.buttons.italic.label": "Kursiver Text", - "fields.textarea.buttons.italic.text": "Kursiver Text", - "fields.textarea.buttons.link.label": "Link", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Bild", - "fields.textarea.buttons.file.label": "Datei", - "fields.toggle.yes": "Ja", - "fields.toggle.no": "Nein", - "fields.toggle.on": "An", - "fields.toggle.off": "Aus", - "fields.error.missing.controller": "Die Feldcontroller-Datei fehlt", - "fields.error.missing.class": "Die Feldcontroller-Klasse fehlt", - "fields.error.route.invalid": "Ungültige Feld-Route", - "fields.error.extended": "Das Feld kann nicht erweitert werden", - "editor.link.url.label": "URL einfügen", - "editor.link.text.label": "Linktext", - "editor.link.text.help": "Der Linktext ist optional", - "editor.email.address.label": "Email Adresse einfügen", - "editor.email.address.placeholder": "mail@beispiel.de", - "editor.email.text.label": "Linktext", - "editor.email.text.help": "Der Linktext ist optional", - "editor.file.empty": "Diese Seite hat keine Dateien", - "editor.image.empty": "Diese Seite hat keine Bilder", - "autocomplete.method.error": "Ungültige Autocomplete-Methode", - "blueprints.error.default.missing": "Standard-Blueprint fehlt", - "error": "Fehler", - "error.headline": "Fehler" -} \ No newline at end of file diff --git a/panel/app/translations/de/package.json b/panel/app/translations/de/package.json deleted file mode 100644 index dd2707c..0000000 --- a/panel/app/translations/de/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Deutsch", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/en/core.json b/panel/app/translations/en/core.json deleted file mode 100644 index 23e5414..0000000 --- a/panel/app/translations/en/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Cancel", - "add": "Add", - "addit": "Add & Edit", - "save": "Save", - "saved": "Saved!", - "change": "Change", - "delete": "Delete", - "insert": "Insert", - "ok": "Ok", - "routes.error.invalid": "Invalid Panel URL", - "controller.error.invalid": "Invalid controller", - "controller.error.action": "Invalid action", - "view.error.invalid": "Invalid view:", - "options.show": "Show options", - "options.hide": "Hide options", - "installation": "Installation", - "installation.check.headline": "Kirby Panel Installation", - "installation.check.text": "Kirby encountered the following issues during installation…", - "installation.check.retry": "Retry", - "installation.check.error": "There are some issues!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts is not writable", - "installation.check.error.avatars": "/assets/avatars is not writable", - "installation.check.error.blueprints": "Please add a /site/blueprints folder", - "installation.check.error.content": "The content folder and all contained files and folders must be writable.", - "installation.check.error.thumbs": "The thumbs folder must be writable.", - "installation.signup.username.label": "Create your first account", - "installation.signup.username.placeholder": "Username", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@example.com", - "installation.signup.password.label": "Password", - "installation.signup.language.label": "Language", - "installation.signup.button": "Create your account", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Username", - "login.password.label": "Password", - "login.error": "Invalid username or password", - "login.button": "Log in", - "login.log.error.permissions": "Login log file is not writable.", - "logout": "Log out", - "topbar.error.class.definition": "Missing topbar definition for class:", - "dashboard": "Dashboard", - "dashboard.index.pages.title": "Pages", - "dashboard.index.pages.edit": "Edit", - "dashboard.index.pages.add": "Add", - "dashboard.index.site.title": "Your site's URL", - "dashboard.index.account.title": "Your account", - "dashboard.index.account.edit": "Edit", - "dashboard.index.metatags.title": "Site options", - "dashboard.index.metatags.edit": "Edit", - "dashboard.index.history.title": "Your last updates", - "dashboard.index.history.text": "Your last modified pages will be displayed here to make it easy to find them again later.", - "dashboard.index.license.title": "Kirby license", - "dashboard.index.license.text": "It seems you are running Kirby on a public server without a valid license!\n\nPlease, support Kirby and (link: {buy} text: buy a license now)\n\nIf you already have a license key, just add it to your config file: (link: {docs} text: site/config/config.php)", - "metatags": "Site options", - "metatags.info": "Kirby info", - "metatags.license": "Kirby license", - "metatags.version.toolkit": "Toolkit version", - "metatags.version.kirby": "Kirby version", - "metatags.version.panel": "Panel version", - "metatags.back": "Back to the dashboard", - "metatags.files": "Site files", - "site.delete.error": "The site cannot be deleted", - "pages.show.settings": "Page settings", - "pages.show.preview": "Open preview", - "pages.show.template": "Template", - "pages.show.changeurl": "Change URL", - "pages.show.invisible": "Status: invisible", - "pages.show.visible": "Status: visible", - "pages.show.changes.text": "You have unsaved changes!", - "pages.show.changes.button": "Discard", - "pages.show.delete": "Delete this page", - "pages.show.subpages.title": "Pages", - "pages.show.subpages.edit": "Edit", - "pages.show.subpages.add": "Add", - "pages.show.subpages.empty": "This page has no subpages", - "pages.show.files.title": "Files", - "pages.show.files.edit": "Edit", - "pages.show.files.add": "Add", - "pages.show.files.empty": "This page has no files", - "pages.show.error.permissions.title": "The page is not writable", - "pages.show.error.permissions.text": "Please check the permissions for the content folder and all files.", - "pages.show.error.permissions.retry": "Retry", - "pages.show.error.notitle.title": "The blueprint does not have a title field", - "pages.show.error.notitle.text": "Please add a title field and try again", - "pages.show.error.notitle.retry": "Retry", - "pages.show.error.form": "Please fill in all fields correctly", - "pages.add.title.label": "Add a new page", - "pages.add.title.placeholder": "Title", - "pages.add.url.label": "URL-appendix", - "pages.add.url.enter": "(enter your title)", - "pages.add.url.close": "Close", - "pages.add.url.help": "Format: lowercase a-z, 0-9 and regular dashes", - "pages.add.template.label": "Template", - "pages.add.error.create": "The page could not be created", - "pages.add.error.title": "The title is missing", - "pages.add.error.template": "The template is missing", - "pages.add.error.max.headline": "No new pages allowed", - "pages.add.error.max.text": "The maximum number of subpages for the current page has been reached.", - "pages.url.uid.label": "URL-appendix", - "pages.url.uid.label.option": "Create from title", - "pages.url.error.exists": "A page with the same appendix already exists", - "pages.url.error.move": "The appendix could not be changed", - "pages.url.error.rights": "You cannot change the URL of this page", - "pages.template.select.label" : "Template", - "pages.template.warning.text" : "The following fields will change, when you switch the template", - "pages.template.warning.removed" : "Removed fields", - "pages.template.warning.replaced" : "Replaced fields", - "pages.template.warning.added" : "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Position", - "pages.toggle.invisible": "invisible", - "pages.toggle.publish": "Do you really want to change the status of this page to **visible?**", - "pages.toggle.hide": "Do you really want to change the status of this page to **invisible?**", - "pages.toggle.error.error": "The status of the error page cannot be changed", - "pages.delete.headline": "Do you really want to delete this page?", - "pages.delete.error.home.headline": "The home page cannot be deleted", - "pages.delete.error.home.text": "You are trying to delete the home page. This is not possible and would lead to unwanted effects.", - "pages.delete.error.error.headline": "The error page cannot be deleted", - "pages.delete.error.error.text": "You are trying to delete the error page. This is not possible and would lead to unwanted effects.", - "pages.delete.error.children.headline": "The page cannot be deleted", - "pages.delete.error.children.text": "This page has subpages and cannot be deleted. Please delete all subpages first.", - "pages.delete.error.blocked.headline": "The page cannot be deleted", - "pages.delete.error.blocked.text": "This page is locked and cannot be deleted.", - "pages.search.help": "Search pages by URL. Navigate through search results with your up and down arrow keys and hit enter to jump to the selected page.", - "pages.search.noresults": "There are no search results for your query. Please try again with a different URL.", - "pages.error.missing": "The page could not be found", - "subpages": "Pages", - "subpages.index.headline": "Pages in", - "subpages.index.back": "Back", - "subpages.index.add": "Add a new page", - "subpages.index.add.first.text": "This page has no subpages yet", - "subpages.index.add.first.button": "Add the first page", - "subpages.index.visible": "Visible pages", - "subpages.index.visible.help": "Drag invisible pages here to sort them/make them visible.", - "subpages.index.invisible": "Invisible pages", - "subpages.index.invisible.help": "Drag visible pages here to unsort them/make them invisible.", - "subpages.add.error": "This page is not allowed to have subpages", - "subpages.add.error.more": "This page cannot have any more subpages", - "subpages.error.missing": "The page could not be found", - "files": "Files", - "files.index.headline": "Files for", - "files.index.back": "Back", - "files.index.upload": "Upload a new file", - "files.index.upload.first.text": "This page has no files yet", - "files.index.upload.first.button": "Upload the first file", - "files.index.edit": "Edit", - "files.index.delete": "Delete", - "files.index.error.disabled": "The page is not allowed to have any files", - "files.add.error.max": "The maximum number of files for the current page has been reached.", - "files.add.error.extension.missing": "You cannot upload files without extension", - "files.add.error.extension.forbidden": "Forbidden file extension", - "files.add.error.mime.forbidden": "Forbidden mime type", - "files.add.error.htaccess": "htaccess files cannot be uploaded", - "files.add.error.invisible": "Invisible files cannot be uploaded", - "files.add.blueprint.type.error": "Page only allows:", - "files.add.blueprint.size.error": "Page only allows file size of", - "files.show.name.label": "Filename", - "files.show.info.label": "Type / Size / Dimensions", - "files.show.link.label": "Public link", - "files.show.open": "Show/download file", - "files.show.back": "Back", - "files.show.replace": "Replace", - "files.show.delete": "Delete", - "files.show.error.rename": "The file could not be renamed", - "files.show.error.form": "Please fill in all fields correctly", - "files.upload.drop": "Drop files here…", - "files.upload.click": "…or click to upload", - "files.replace.drop": "Drop a file here…", - "files.replace.click": "…or click to replace", - "files.replace.error.type": "The uploaded file must have the same file type", - "files.delete.headline": "Do you really want to delete this file?", - "files.error.missing.page": "The page could not be found", - "files.error.missing.file": "The file could not be found", - "users": "Users", - "users.index.headline": "All users", - "users.index.add": "Add a new user", - "users.index.edit": "Edit", - "users.index.delete": "Delete", - "users.form.username.label": "Username", - "users.form.username.placeholder": "Your username", - "users.form.username.help": "Allowed characters: lowercase a-z, 0-9 and dashes", - "users.form.username.readonly": "The username cannot be changed", - "users.form.firstname.label": "First name", - "users.form.lastname.label": "Last name", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@example.com", - "users.form.password.label": "Password", - "users.form.password.confirm.label": "Confirm password", - "users.form.password.new.label": "New password", - "users.form.password.new.confirm.label": "Confirm the new password", - "users.form.password.new.help": "Leave blank to keep the current password", - "users.form.language.label": "Language", - "users.form.role.label": "Role", - "users.form.options.headline": "Account options", - "users.form.options.message": "Send email", - "users.form.options.delete": "Delete account", - "users.form.avatar.headline": "Profile picture", - "users.form.avatar.upload": "Upload profile picture", - "users.form.avatar.replace": "Replace profile picture", - "users.form.avatar.delete": "Delete profile picture", - "users.form.back": "Back to users", - "users.form.error.password.confirm": "Please confirm the password", - "users.form.error.update": "The user could not be updated", - "users.form.error.update.rights": "You are not allowed to update this user", - "users.form.error.create": "The user could not be created", - "users.form.error.permissions.title": "The account folder is not writable", - "users.form.error.permissions.text": "Please make sure that /site/accounts exists and is writable.", - "users.delete.headline": "Do you really want to delete this user?", - "users.delete.error": "The user could not be deleted", - "users.delete.error.permission": "You are not allowed to delete users", - "users.delete.error.permission.single": "You are not allowed to delete this user", - "users.delete.error.lastadmin": "You cannot delete the last admin", - "users.avatar.drop": "Drop a profile picture here…", - "users.avatar.click": "…or click to upload", - "users.avatar.error.type": "You can only upload JPG, PNG and GIF files", - "users.avatar.error.folder.headline": "The avatar folder is not writable", - "users.avatar.error.folder.text": "Please create the folder /assets/avatars and make it writable to upload profile pictures.", - "users.avatar.error.permission": "You are not allowed to change the avatar", - "users.avatar.delete.error": "The profile picture could not be deleted", - "users.avatar.delete.error.permission": "You are not allowed to delete the avatar of this user", - "users.avatar.delete.success": "The profile picture has been deleted", - "users.avatar.missing": "This user has no avatar", - "users.error.missing": "The user could not be found", - "user.error.lastadmin": "You are the only admin. This cannot be changed.", - "form.error.missing": "The form cannot be found", - "form.construct.error.invalid": "Invalid form construction method", - "fields.required": "Required", - "fields.date.label": "Date", - "fields.date.months": [ - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December" - ], - "fields.date.weekdays": [ - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday" - ], - "fields.date.weekdays.short": [ - "Sun", - "Mon", - "Tue", - "Wed", - "Thu", - "Fri", - "Sat" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@example.com", - "fields.number.label": "Number", - "fields.number.placeholder": "#", - "fields.page.label": "Page", - "fields.page.placeholder": "path/to/page", - "fields.password.label": "Password", - "fields.structure.add": "Add", - "fields.structure.add.first": "Add the first entry", - "fields.structure.empty": "No entries yet.", - "fields.structure.entry.error": "The item could not be found", - "fields.structure.cancel": "Cancel", - "fields.structure.save": "Ok", - "fields.structure.edit": "Edit", - "fields.structure.delete": "Delete", - "fields.structure.delete.label": "Do you really want to delete this entry?", - "fields.tags.label": "Tags", - "fields.tel.label": "Phone", - "fields.textarea.buttons.bold.label": "Bold text", - "fields.textarea.buttons.bold.text": "Bold text", - "fields.textarea.buttons.italic.label": "Italic text", - "fields.textarea.buttons.italic.text": "Italic text", - "fields.textarea.buttons.link.label": "Link", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Image", - "fields.textarea.buttons.file.label": "File", - "fields.toggle.yes": "Yes", - "fields.toggle.no": "No", - "fields.toggle.on": "On", - "fields.toggle.off": "Off", - "fields.error.missing.controller": "The field controller file is missing", - "fields.error.missing.class": "The field controller class is missing", - "fields.error.route.invalid": "Invalid field route", - "fields.error.extended": "The field cannot be extended", - "editor.link.url.label": "Insert URL", - "editor.link.text.label": "Link text", - "editor.link.text.help": "The link text is optional", - "editor.email.address.label": "Insert email address", - "editor.email.address.placeholder": "mail@example.com", - "editor.email.text.label": "Link text", - "editor.email.text.help": "The link text is optional", - "editor.file.empty": "This page has no files", - "editor.image.empty": "This page has no images", - "autocomplete.method.error": "Invalid autocomplete method", - "blueprints.error.default.missing": "Missing default blueprint", - "error": "Error", - "error.headline": "Error" -} diff --git a/panel/app/translations/en/package.json b/panel/app/translations/en/package.json deleted file mode 100644 index fd2592d..0000000 --- a/panel/app/translations/en/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "English", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/es_419/core.json b/panel/app/translations/es_419/core.json deleted file mode 100644 index e0d11ff..0000000 --- a/panel/app/translations/es_419/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Cancelar", - "add": "Agregar", - "addit": "Agregar y Editar", - "save": "Guardar", - "saved": "¡Guardado!", - "change": "Cambiar", - "delete": "Eliminar", - "insert": "Insertar", - "ok": "OK", - "routes.error.invalid": "URL del Panel no válida", - "controller.error.invalid": "Controlador no válido", - "controller.error.action": "Acción no válida", - "view.error.invalid": "Vista no válida:", - "options.show": "Mostrar opciones", - "options.hide": "Ocultar opciones", - "installation": "Instalación", - "installation.check.headline": "Instalación del Panel de Kirby", - "installation.check.text": "Kirby encontró los siguientes errores durante la instalación…", - "installation.check.retry": "Reintentar", - "installation.check.error": "¡Tenemos problemas!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts no tine permisos de escritura", - "installation.check.error.avatars": "/assets/avatars no tine permisos de escritura", - "installation.check.error.blueprints": "Por favor agrega una carpeta /site/blueprints", - "installation.check.error.content": "La carpeta \"contenido\" y todos sus archivos y subcarpetas deben de tener permiso de escritura.", - "installation.check.error.thumbs": "La carpeta \"thumbs\" debe tener permisos de escritura.", - "installation.signup.username.label": "Crea tu primera cuenta", - "installation.signup.username.placeholder": "Usuario", - "installation.signup.email.label": "Correo electrónico", - "installation.signup.email.placeholder": "correo@ejemplo.com", - "installation.signup.password.label": "Contraseña", - "installation.signup.language.label": "Idioma", - "installation.signup.button": "Crear tu cuenta", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Usuario", - "login.password.label": "Contraseña", - "login.error": "Usuario o Contraseña equivocada", - "login.button": "Log in", - "login.log.error.permissions": "El archivo de registro del inicio de sesión no es modificable", - "logout": "Log out", - "topbar.error.class.definition": "Falta la definición topbar para la clase:", - "dashboard": "Inicio", - "dashboard.index.pages.title": "Páginas", - "dashboard.index.pages.edit": "Editar", - "dashboard.index.pages.add": "Agregar", - "dashboard.index.site.title": "URL de tu sitio", - "dashboard.index.account.title": "Tu cuenta", - "dashboard.index.account.edit": "Editar", - "dashboard.index.metatags.title": "Variables del sitio", - "dashboard.index.metatags.edit": "Editar", - "dashboard.index.history.title": "Actualizaciones recientes", - "dashboard.index.history.text": "Las últimas páginas modificadas serán desplegadas aquí para facilitar su acceso en el futuro.", - "dashboard.index.license.title": "Licencia Kirby", - "dashboard.index.license.text": "¡Parece que estás ejecutando Kirby en un servidor público sin una licencia válida!\n\nPor favor, apoya a Kirby y (link: {buy} text: compra una licencia)\n\nSi ya has adquirido una licencia, sólo agrégala a tu archivo de configuración: (link: {docs} text: site/config/config.php)", - "metatags": "Variables del sitio", - "metatags.info": "Información de Kirby", - "metatags.license": "Licencia Kirby", - "metatags.version.toolkit": "Versión del Toolkit", - "metatags.version.kirby": "Versión de Kirby", - "metatags.version.panel": "Versión del Panel", - "metatags.back": "Regresar al Inicio", - "metatags.files": "Archivos del sitio", - "site.delete.error": "El sitio no puede ser borrado", - "pages.show.settings": "Opciones de Página", - "pages.show.preview": "Abrir previsualización", - "pages.show.template": "Plantilla", - "pages.show.changeurl": "Cambiar URL", - "pages.show.invisible": "Estatus: invisible", - "pages.show.visible": "Estatus: visible", - "pages.show.changes.text": "¡Tienes cambios sin guardar!", - "pages.show.changes.button": "Descartar", - "pages.show.delete": "Eliminar esta página", - "pages.show.subpages.title": "Páginas", - "pages.show.subpages.edit": "Editar", - "pages.show.subpages.add": "Agregar", - "pages.show.subpages.empty": "Esta página no posee subpáginas", - "pages.show.files.title": "Archivos", - "pages.show.files.edit": "Editar", - "pages.show.files.add": "Agregar", - "pages.show.files.empty": "Esta página no contiene archivos", - "pages.show.error.permissions.title": "Esta página no es modificable", - "pages.show.error.permissions.text": "Por favor revisa los permisos para la carpeta de contenido y todos los archivos.", - "pages.show.error.permissions.retry": "Reintentar", - "pages.show.error.notitle.title": "El blueprint no posee un campo de título", - "pages.show.error.notitle.text": "Por favor agrega un campo de título e intenta de nuevo", - "pages.show.error.notitle.retry": "Reintentar", - "pages.show.error.form": "Por favor llena todos los campos correctamente", - "pages.add.title.label": "Agregar nueva página", - "pages.add.title.placeholder": "Título", - "pages.add.url.label": "Apéndice-URL", - "pages.add.url.enter": "(ingresa un título)", - "pages.add.url.close": "Cerrar", - "pages.add.url.help": "Formato: minúsculas a-z, 0-9 y guiones regulares", - "pages.add.template.label": "Plantilla", - "pages.add.error.create": "La página no pudo ser eliminada", - "pages.add.error.title": "Falta un título", - "pages.add.error.template": "Falta una plantilla", - "pages.add.error.max.headline": "No se permiten páginas nuevas", - "pages.add.error.max.text": "El número máximo de subpáginas para la página actual se ha alcanzado.", - "pages.url.uid.label": "Apéndice-URL", - "pages.url.uid.label.option": "Crear a partir del título", - "pages.url.error.exists": "Una página con el mismo apéndice-url ya existe", - "pages.url.error.move": "El apéndice-url no pudo ser cambiado", - "pages.url.error.rights": "Usted no puede cambiar la URL de esta página", - "pages.template.select.label": "Plantilla", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Posición", - "pages.toggle.invisible": "invisible", - "pages.toggle.publish": "¿En realidad deseas cambiar el estatus de esta página a **visible?**", - "pages.toggle.hide": "¿En realidad deseas cambiar el estatus de esta página a **invisible?**", - "pages.toggle.error.error": "El estado de la pagina de error no puede ser cambiado", - "pages.delete.headline": "¿Estás seguro que deseas eliminar esta página?", - "pages.delete.error.home.headline": "La página \"Home\" no puede ser eliminada", - "pages.delete.error.home.text": "Estás intentando eliminar la página \"Home\". Esto no es posible y podría causar efectos indeseados.", - "pages.delete.error.error.headline": "La página \"Error\" no puede ser eliminada", - "pages.delete.error.error.text": "Estás intentando eliminar la página \"Error\". Esto no es posible y podría causar efectos indeseados.", - "pages.delete.error.children.headline": "Esta página no puede ser eliminada", - "pages.delete.error.children.text": "La página contiene subpáginas y no puede ser eliminada. Por favor elimina todas las subpáginas primero.", - "pages.delete.error.blocked.headline": "Esta página no puede ser eliminada", - "pages.delete.error.blocked.text": "La página esta bloqueada y no puede ser eliminada.", - "pages.search.help": "Buscar páginas por URL. Navega por los resultados de búsqueda con las flechas arriba y abajo y presiona enter para ir a la página seleccionada.", - "pages.search.noresults": "No hay resultados de búsqueda. Por favor intenta con un URL diferente.", - "pages.error.missing": "La página no fue encontrada", - "subpages": "Páginas", - "subpages.index.headline": "Páginas dentro de", - "subpages.index.back": "Regresar", - "subpages.index.add": "Agregar nueva página", - "subpages.index.add.first.text": "Esta página aún no tiene subpáginas", - "subpages.index.add.first.button": "Agrega la primera página", - "subpages.index.visible": "Páginas visibles", - "subpages.index.visible.help": "Arrastra las páginas invisibles aquí para ordenar y hacerlas visibles.", - "subpages.index.invisible": "Páginas invisibles", - "subpages.index.invisible.help": "Arrastra las páginas visibles aquí para eliminar el numero de orden y hacerlas invisibles.", - "subpages.add.error": "Esta página no permite tener subpáginas", - "subpages.add.error.more": "Esta página ya no puede tener más subpáginas", - "subpages.error.missing": "La página no pudo ser encontrada", - "files": "Archivos", - "files.index.headline": "Archivos de", - "files.index.back": "Regresar", - "files.index.upload": "Subir nuevo archivo", - "files.index.upload.first.text": "Esta página aún no contiene archivos", - "files.index.upload.first.button": "Subir el primer archivo", - "files.index.edit": "Editar", - "files.index.delete": "Eliminar", - "files.index.error.disabled": "Esta página no permite tener archivos", - "files.add.error.max": "El máximo número de archivos para la página actual ya han sido alcanzados", - "files.add.error.extension.missing": "Usted no puede subir archivos sin extensión", - "files.add.error.extension.forbidden": "Extensión de archivo prohibida", - "files.add.error.mime.forbidden": "Tipo mime prohibido", - "files.add.error.htaccess": "Los archivos htaccess no pueden ser subidos", - "files.add.error.invisible": "Los archivos invisibles no pueden ser subidos", - "files.add.blueprint.type.error": "La página únicamente permite:", - "files.add.blueprint.size.error": "La página únicamente permite archivos de tamaño", - "files.show.name.label": "Nombre", - "files.show.info.label": "Tipo / Tamaño / Dimensiones", - "files.show.link.label": "Enlace público", - "files.show.open": "Mostrar/descargar archivo", - "files.show.back": "Regresar", - "files.show.replace": "Reemplazar", - "files.show.delete": "Eliminar", - "files.show.error.rename": "El archivo no pudo ser renombrado", - "files.show.error.form": "Por favor llena todos los campos correctamente", - "files.upload.drop": "Arrastra y suelta los archivos aquí…", - "files.upload.click": "…o haz click para subir", - "files.replace.drop": "Arrastra y suelta un archivo aquí…", - "files.replace.click": "…o haz click para reemplazar", - "files.replace.error.type": "El archivo subido debe ser del mismo tipo", - "files.delete.headline": "¿Estás seguro que deseas eliminar este archivo?", - "files.error.missing.page": "La página no pudo ser encontrada", - "files.error.missing.file": "El archivo no pudo ser encontrado", - "users": "Usuarios", - "users.index.headline": "Todos los usuarios", - "users.index.add": "Agregar un nuevo usuario", - "users.index.edit": "Editar", - "users.index.delete": "Eliminar", - "users.form.username.label": "Usuario", - "users.form.username.placeholder": "Tu nombre de usuario", - "users.form.username.help": "Caracteres permitidos: minúsculas a-z, 0-9 y guiones regulares", - "users.form.username.readonly": "El nombre de usuario no puede ser cambiado", - "users.form.firstname.label": "Nombre", - "users.form.lastname.label": "Apellido", - "users.form.email.label": "Email", - "users.form.email.placeholder": "correo@ejemplo.com", - "users.form.password.label": "Contraseña", - "users.form.password.confirm.label": "Confirmar contraseña", - "users.form.password.new.label": "Nueva contraseña", - "users.form.password.new.confirm.label": "Confirmar la nueva contraseña", - "users.form.password.new.help": "Dejar en blanco para mantener la misma contraseña", - "users.form.language.label": "Idioma", - "users.form.role.label": "Rol", - "users.form.options.headline": "Opciones de cuenta", - "users.form.options.message": "Enviar email", - "users.form.options.delete": "Eliminar cuenta", - "users.form.avatar.headline": "Foto de perfil", - "users.form.avatar.upload": "Subir foto de perfil", - "users.form.avatar.replace": "Reemplazar foto de perfil", - "users.form.avatar.delete": "Eliminar foto de perfil", - "users.form.back": "Regresar a usuarios", - "users.form.error.password.confirm": "Por favor confirma la contraseña", - "users.form.error.update": "El usuario no pudo ser actualizado", - "users.form.error.update.rights": "Usted no tiene permitido actualizar este usuario", - "users.form.error.create": "El usuario no pudo ser creado", - "users.form.error.permissions.title": "La carpeta de la cuenta no es modificable", - "users.form.error.permissions.text": "Por favor asegúrate de que la carpeta \"/site/accounts\" exista y sea modificable.", - "users.delete.headline": "¿Estás seguro que deseas eliminar este usuario?", - "users.delete.error": "El ususario no pudo ser eliminado", - "users.delete.error.permission": "Usted no tiene permitido borrar usuarios", - "users.delete.error.permission.single": "Usted no tiene permitido borrar este usuario", - "users.delete.error.lastadmin": "Usted no puede borrar el último administrador", - "users.avatar.drop": "Arrastra y suelta una imagen aquí…", - "users.avatar.click": "…o haz click para subir", - "users.avatar.error.type": "Sólo se pueden subir archivos con extensión JPG, PNG y GIF", - "users.avatar.error.folder.headline": "La carpeta \"avatar\" no es modificable", - "users.avatar.error.folder.text": "Por favor crea la carpeta /assets/avatars y hazla modificable para subir fotos de perfil.", - "users.avatar.error.permission": "Usted no tiene permitido cambiar el avatar", - "users.avatar.delete.error": "La foto de perfil no pudo ser eliminada", - "users.avatar.delete.error.permission": "Usted no tiene permitido borrar el avatar de este usuario", - "users.avatar.delete.success": "La foto de perfil ha sido eliminada", - "users.avatar.missing": "Este usuario no tiene avatar", - "users.error.missing": "El usuario no pudo ser encontrado", - "user.error.lastadmin": "Usted es el único administrador, Esto no puede ser cambiado", - "form.error.missing": "No se pudo encontrar el formulario", - "form.construct.error.invalid": "El método de construcción del formulario es inválido", - "fields.required": "Requerido", - "fields.date.label": "Fecha", - "fields.date.months": [ - "Enero", - "Febrero", - "Marzo", - "Abril", - "Mayo", - "Junio", - "Julio", - "Agosto", - "Septiembre", - "Octubre", - "Noviembre", - "Diciembre" - ], - "fields.date.weekdays": [ - "Domingo", - "Lunes", - "Martes", - "Miércoles", - "Jueves", - "Viernes", - "Sábado" - ], - "fields.date.weekdays.short": [ - "Dom", - "Lun", - "Mar", - "Mié", - "Jue", - "Vie", - "Sáb" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "correo@ejemplo.com", - "fields.number.label": "Número", - "fields.number.placeholder": "#", - "fields.page.label": "Página", - "fields.page.placeholder": "ruta/a/página", - "fields.password.label": "Contraseña", - "fields.structure.add": "Agregar", - "fields.structure.add.first": "Agregar la primera entrada", - "fields.structure.empty": "Aún no existen entradas.", - "fields.structure.entry.error": "No se pudo encontrar el item", - "fields.structure.cancel": "Cancelar", - "fields.structure.save": "Guardar", - "fields.structure.edit": "Editar", - "fields.structure.delete": "Eliminar", - "fields.structure.delete.label": "¿En realidad desea borrar esta entrada?", - "fields.tags.label": "Etiquetas", - "fields.tel.label": "Teléfono", - "fields.textarea.buttons.bold.label": "Texto en Negrita", - "fields.textarea.buttons.bold.text": "Texto en Negrita", - "fields.textarea.buttons.italic.label": "Texto en Itálicas", - "fields.textarea.buttons.italic.text": "Texto en Itálicas", - "fields.textarea.buttons.link.label": "Enlace", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Imágen", - "fields.textarea.buttons.file.label": "Archivo", - "fields.toggle.yes": "Sí", - "fields.toggle.no": "No", - "fields.toggle.on": "Encendido", - "fields.toggle.off": "Apagado", - "fields.error.missing.controller": "Falta el archivo del controlador del campo ", - "fields.error.missing.class": "Falta la clase del controlador del campo", - "fields.error.route.invalid": "La ruta del campo es inválida", - "fields.error.extended": "El campo no puede ser extendido", - "editor.link.url.label": "Insertar URL", - "editor.link.text.label": "Texto de Enlace", - "editor.link.text.help": "El texto de enlace es opcional", - "editor.email.address.label": "Insertar dirección email", - "editor.email.address.placeholder": "correo@ejemplo.com", - "editor.email.text.label": "Texto de Enlace", - "editor.email.text.help": "El texto de enlace es opcional", - "editor.file.empty": "Esta página no contiene archivos", - "editor.image.empty": "Esta página no contiene imágenes", - "autocomplete.method.error": "Método de autocompletar no válido", - "blueprints.error.default.missing": "Falta el blueprint predeterminado", - "error": "Error", - "error.headline": "Error" -} \ No newline at end of file diff --git a/panel/app/translations/es_419/package.json b/panel/app/translations/es_419/package.json deleted file mode 100644 index 5a9f078..0000000 --- a/panel/app/translations/es_419/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Español (América Latina)‎", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/es_ES/core.json b/panel/app/translations/es_ES/core.json deleted file mode 100644 index 1019834..0000000 --- a/panel/app/translations/es_ES/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Cancelar", - "add": "Añadir", - "addit": "Añadir y Editar", - "save": "Guardar", - "saved": "¡Guardado!", - "change": "Cambiar", - "delete": "Eliminar", - "insert": "Insertar", - "ok": "OK", - "routes.error.invalid": "La URL del Panel es inválida", - "controller.error.invalid": "Controlador inválido", - "controller.error.action": "Acción inválida", - "view.error.invalid": "Vista inválida", - "options.show": "Mostrar opciones", - "options.hide": "Ocultar opciones", - "installation": "Instalación", - "installation.check.headline": "Instalación de Kirby Panel", - "installation.check.text": "Kirby encontró los siguientes errores durante la instalación…", - "installation.check.retry": "Reintentar", - "installation.check.error": "¡Hay un problema!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts no tiene permisos de escritura", - "installation.check.error.avatars": "/assets/avatars no tiene permisos de escritura", - "installation.check.error.blueprints": "Por favor, crea la carpeta /site/blueprints", - "installation.check.error.content": "La carpeta de contenido y todos sus archivos y carpetas deben tener permisos de escritura.", - "installation.check.error.thumbs": "La carpeta /thumbs debe tener permisos de escritura.", - "installation.signup.username.label": "Crea tu primera cuenta", - "installation.signup.username.placeholder": "Nombre de usuario", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@ejemplo.com", - "installation.signup.password.label": "Contraseña", - "installation.signup.language.label": "Idioma", - "installation.signup.button": "Crear cuenta", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Nombre de usuario", - "login.password.label": "Contraseña", - "login.error": "Nombre de usuario o contraseña incorrecto", - "login.button": "Log in", - "login.log.error.permissions": "El archivo de logs de inicios de sesión no tiene permisos de escritura", - "logout": "Log out", - "topbar.error.class.definition": "Falta la definición de topbar para la clase:", - "dashboard": "Tablero", - "dashboard.index.pages.title": "Páginas", - "dashboard.index.pages.edit": "Editar", - "dashboard.index.pages.add": "Añadir", - "dashboard.index.site.title": "URL de tu sitio", - "dashboard.index.account.title": "Tu cuenta", - "dashboard.index.account.edit": "Editar", - "dashboard.index.metatags.title": "Variables del sitio", - "dashboard.index.metatags.edit": "Editar", - "dashboard.index.history.title": "Tus últimas actualizaciones", - "dashboard.index.history.text": "Las páginas modificadas recientemente se mostrarán aquí para que puedas encontrarlas fácilmente.", - "dashboard.index.license.title": "Licencia de Kirby", - "dashboard.index.license.text": "It seems you are running Kirby on a public server without a valid license!\n\nPlease, support Kirby and (link: {buy} text: buy a license now)\n\nIf you already have a license key, just add it to your config file: (link: {docs} text: site/config/config.php)", - "metatags": "Variables del sitio", - "metatags.info": "Información de Kirby", - "metatags.license": "Licencia de Kirby", - "metatags.version.toolkit": "Versión del Toolkit", - "metatags.version.kirby": "Versión de Kirby", - "metatags.version.panel": "Versión del Panel", - "metatags.back": "Volver al tablero", - "metatags.files": "Archivos del sitio", - "site.delete.error": "No se puede eliminar el sitio", - "pages.show.settings": "Ajustes de página", - "pages.show.preview": "Abrir previsualización", - "pages.show.template": "Plantilla", - "pages.show.changeurl": "Cambiar URL", - "pages.show.invisible": "Estado: Invisible", - "pages.show.visible": "Estado: Visible", - "pages.show.changes.text": "¡Tienes cambios sin guardar!", - "pages.show.changes.button": "Descartar", - "pages.show.delete": "Eliminar esta página", - "pages.show.subpages.title": "Páginas", - "pages.show.subpages.edit": "Editar", - "pages.show.subpages.add": "Añadir", - "pages.show.subpages.empty": "Esta página no tiene subpáginas", - "pages.show.files.title": "Archivos", - "pages.show.files.edit": "Editar", - "pages.show.files.add": "Añadir", - "pages.show.files.empty": "Esta página no tiene archivos", - "pages.show.error.permissions.title": "Esta página no tiene permisos de escritura", - "pages.show.error.permissions.text": "Por favor, revisa los permisos de la carpeta de contenido y todos sus archivos.", - "pages.show.error.permissions.retry": "Volver a intentar", - "pages.show.error.notitle.title": "El blueprint no tiene un campo título", - "pages.show.error.notitle.text": "Por favor, añade un título e inténtalo de nuevo", - "pages.show.error.notitle.retry": "Volver a intentar", - "pages.show.error.form": "Por favor, rellena todos los campos correctamente", - "pages.add.title.label": "Añadir una nueva página", - "pages.add.title.placeholder": "Título", - "pages.add.url.label": "URL de la página", - "pages.add.url.enter": "(añadir título)", - "pages.add.url.close": "Cerrar", - "pages.add.url.help": "Formato: minúsculas a-z, 0-9 y guiones", - "pages.add.template.label": "Plantilla", - "pages.add.error.create": "No se ha podido crear la página", - "pages.add.error.title": "Falta el título", - "pages.add.error.template": "Falta la plantilla", - "pages.add.error.max.headline": "No se permite añadir nuevas páginas", - "pages.add.error.max.text": "Se ha alcanzado el máximo número de subpáginas para la página actual.", - "pages.url.uid.label": "URL de la página", - "pages.url.uid.label.option": "Crear a partir del título", - "pages.url.error.exists": "Ya existe una página con la misma URL", - "pages.url.error.move": "No se ha podido cambiar la URL", - "pages.url.error.rights": "No se puede cambiar la URL de esta página", - "pages.template.select.label": "Plantilla", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Posición", - "pages.toggle.invisible": "invisible", - "pages.toggle.publish": "¿Realmente quieres eliminar esta cambiar el estado de esta página a **visible?**", - "pages.toggle.hide": "¿Realmente quieres cambiar el estado de esta página a **invisible?**", - "pages.toggle.error.error": "No se puede cambiar el estado de la página de error", - "pages.delete.headline": "¿Realmente quieres eliminar esta página?", - "pages.delete.error.home.headline": "No se puede eliminar la página de inicio", - "pages.delete.error.home.text": "Estás intentando eliminar la página de inicio. Esto no es posible y podría causar efectos indeseados.", - "pages.delete.error.error.headline": "No se puede eliminar la página de error", - "pages.delete.error.error.text": "Estás intentando eliminar la página de error. Esto no es posible y podría causar efectos indeseados.", - "pages.delete.error.children.headline": "No se puede eliminar la página", - "pages.delete.error.children.text": "Esta página tiene subpáginas y no puede ser eliminada. Por favor, elimina primero las subpáginas.", - "pages.delete.error.blocked.headline": "No se puede eliminar la página", - "pages.delete.error.blocked.text": "Esta página está bloqueada y no puede ser eliminada.", - "pages.search.help": "Buscar páginas por URL. Navega a través de los resultados de la búsqueda mediante las flechas del teclado y pulsa Enter para ir a la página seleccionada.", - "pages.search.noresults": "No se han encontrado resultados para tu búsqueda. Por favor, inténtalo de nuevo con una URL distinta.", - "pages.error.missing": "No se ha encontrado la página", - "subpages": "Páginas", - "subpages.index.headline": "Páginas en", - "subpages.index.back": "Atrás", - "subpages.index.add": "Añadir una página nueva", - "subpages.index.add.first.text": "Esta página aún no tiene subpáginas", - "subpages.index.add.first.button": "Añade la primera página", - "subpages.index.visible": "Páginas visibles", - "subpages.index.visible.help": "Arrastra páginas invisibles aquí para ordenarlas/hacerlas visibles.", - "subpages.index.invisible": "Páginas invisibles", - "subpages.index.invisible.help": "Arrastra páginas visibles aquí para desordenarlas/hacerlas invisibles.", - "subpages.add.error": "Esta página no admite subpáginas", - "subpages.add.error.more": "Esta página no admite más sumpáginas", - "subpages.error.missing": "No se ha podido encontrar la página", - "files": "Archivos", - "files.index.headline": "Archivos para", - "files.index.back": "Atrás", - "files.index.upload": "Subir un archivo", - "files.index.upload.first.text": "Esta página no tiene archivos", - "files.index.upload.first.button": "Sube un primer archivo", - "files.index.edit": "Editar", - "files.index.delete": "Eliminar", - "files.index.error.disabled": "La página no admite archivos", - "files.add.error.max": "Se ha alcanzado el número máximo de archivos para esta página", - "files.add.error.extension.missing": "No se pueden subir archivos sin extensión", - "files.add.error.extension.forbidden": "Extensión de archivo prohibida", - "files.add.error.mime.forbidden": "mime type prohibido", - "files.add.error.htaccess": "No se pueden subir archivos htacces", - "files.add.error.invisible": "No se pueden subir archivos invisibles", - "files.add.blueprint.type.error": "La página únicamente admite:", - "files.add.blueprint.size.error": "La página únicamente admite tamaño de archivo de", - "files.show.name.label": "Nombre del archivo", - "files.show.info.label": "Tipo / Tamaño / Dimensiones", - "files.show.link.label": "Enlace público", - "files.show.open": "Mostrar/descargar archivo", - "files.show.back": "Atrás", - "files.show.replace": "Reemplazar", - "files.show.delete": "Eliminar", - "files.show.error.rename": "No se ha podido renombrar el archivo", - "files.show.error.form": "Por favor, rellena todos los campos correctamente", - "files.upload.drop": "Suelta archivos aquí…", - "files.upload.click": "…o haz clic para subir", - "files.replace.drop": "Suelta un archivo aquí……", - "files.replace.click": "…o haz clic para reemplazar", - "files.replace.error.type": "El archivo subido debe ser del mismo tipo", - "files.delete.headline": "¿Realmente quieres eliminar este archivo?", - "files.error.missing.page": "No se ha podido encontrar la página", - "files.error.missing.file": "No se ha podido encontrar el archivo", - "users": "Usuarios", - "users.index.headline": "Todos los usuarios", - "users.index.add": "Añadir usuario", - "users.index.edit": "Editar", - "users.index.delete": "Eliminar", - "users.form.username.label": "Nombre de usuario", - "users.form.username.placeholder": "Tu nombre de usuario", - "users.form.username.help": "Caracteres permitidos: minúsculas a-z, 0-9 y guiones", - "users.form.username.readonly": "No se puede cambiar el nombre de usuario", - "users.form.firstname.label": "Nombre", - "users.form.lastname.label": "Apellido", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@ejemplo.com", - "users.form.password.label": "Contraseña", - "users.form.password.confirm.label": "Confirmar contraseña", - "users.form.password.new.label": "Nueva contraseña", - "users.form.password.new.confirm.label": "Confirmar la nueva contraseña", - "users.form.password.new.help": "Dejar vacío para mantener la contraseña actual", - "users.form.language.label": "Idioma", - "users.form.role.label": "Rol", - "users.form.options.headline": "Opciones de cuenta", - "users.form.options.message": "Enviar email", - "users.form.options.delete": "Eliminar cuenta", - "users.form.avatar.headline": "Foto de perfil", - "users.form.avatar.upload": "Subir una foto de perfil", - "users.form.avatar.replace": "Reemplazar la foto de perfil", - "users.form.avatar.delete": "Eliminar la foto de perfil", - "users.form.back": "Volver a Usuarios", - "users.form.error.password.confirm": "Por favor, confirma tu contraseña", - "users.form.error.update": "No se ha podido actualizar el usuario", - "users.form.error.update.rights": "No dispones de autorización para actualizar este usuario", - "users.form.error.create": "No se ha podido crear el usuario", - "users.form.error.permissions.title": "La carpeta de cuentas no tiene permisos de escritura", - "users.form.error.permissions.text": "Por favor, asegúrate de que /site/accounts existe y tiene permisos de escritura.", - "users.delete.headline": "¿Realmente quieres eliminar este usuario?", - "users.delete.error": "No se ha podido eliminar el usuario", - "users.delete.error.permission": "No dispones de autorización para eliminar usuarios", - "users.delete.error.permission.single": "No dispones de autorización para eliminar este usuario", - "users.delete.error.lastadmin": "No puedes eliminar al último admin", - "users.avatar.drop": "Suelta una foto de perfil aquí…", - "users.avatar.click": "…o haz clic para subir", - "users.avatar.error.type": "Sólo se pueden subir archivos JPG, PNG y GIF", - "users.avatar.error.folder.headline": "La carpeta de fotos de perfil no tiene permisos de escritura", - "users.avatar.error.folder.text": "Por favor, crea la carpeta /assets/avatars y asegúrate de que tiene permisos de escritura para poder subir fotos de perfil.", - "users.avatar.error.permission": "No dispones de autorización para cambiar el avatar", - "users.avatar.delete.error": "No se ha podido eliminar la foto de perfil", - "users.avatar.delete.error.permission": "No dispones de autorización para eliminar el avatar de este usuario", - "users.avatar.delete.success": "Se ha eliminado la foto de perfil", - "users.avatar.missing": "Este usuario no tiene avatar", - "users.error.missing": "Usuario no encontrado", - "user.error.lastadmin": "Eres el único administrador. Esto no se puede cambiar.", - "form.error.missing": "No se ha encontrado el formulario", - "form.construct.error.invalid": "Método de construcción de formulario inválido", - "fields.required": "Obligatorio", - "fields.date.label": "Fecha", - "fields.date.months": [ - "Enero", - "Febrero", - "Marzo", - "Abril", - "Mayo", - "Junio", - "Julio", - "Agosto", - "Septiembre", - "Octubre", - "Noviembre", - "Diciembre" - ], - "fields.date.weekdays": [ - "Domingo", - "Lunes", - "Martes", - "Miércoles", - "Jueves", - "Viernes", - "Sábado" - ], - "fields.date.weekdays.short": [ - "Do", - "Lu", - "Ma", - "Mi", - "Ju", - "Vi", - "Sa" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@ejemplo.com", - "fields.number.label": "Número", - "fields.number.placeholder": "#", - "fields.page.label": "Página", - "fields.page.placeholder": "ruta/a/pagina", - "fields.password.label": "Contraseña", - "fields.structure.add": "Añadir", - "fields.structure.add.first": "Añadir la primera entrada", - "fields.structure.empty": "Aún no hay entradas.", - "fields.structure.entry.error": "No se ha podido encontrar el item", - "fields.structure.cancel": "Cancelar", - "fields.structure.save": "Guardar", - "fields.structure.edit": "Editar", - "fields.structure.delete": "Eliminar", - "fields.structure.delete.label": "¿Realmente quieres eliminar esta entrada?", - "fields.tags.label": "Etiquetas", - "fields.tel.label": "Teléfono", - "fields.textarea.buttons.bold.label": "Negrita", - "fields.textarea.buttons.bold.text": "Negrita", - "fields.textarea.buttons.italic.label": "Cursiva", - "fields.textarea.buttons.italic.text": "Cursiva", - "fields.textarea.buttons.link.label": "Enlace", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Imágen", - "fields.textarea.buttons.file.label": "Archivo", - "fields.toggle.yes": "Sí", - "fields.toggle.no": "No", - "fields.toggle.on": "On", - "fields.toggle.off": "Off", - "fields.error.missing.controller": "Falta el archivo del controlador de campos", - "fields.error.missing.class": "Falta la clase del controlador de campos", - "fields.error.route.invalid": "Ruta del campo inválida", - "fields.error.extended": "El campo no puede ser extendido", - "editor.link.url.label": "Insertar URL", - "editor.link.text.label": "Texto del enlace", - "editor.link.text.help": "El texto del enlace es opcional", - "editor.email.address.label": "Añadir dirección de email", - "editor.email.address.placeholder": "mail@ejemplo.com", - "editor.email.text.label": "Texto del enlace", - "editor.email.text.help": "El texto del enlace es opcional", - "editor.file.empty": "Esta página no tiene archivos", - "editor.image.empty": "Esta página no tiene imágenes", - "autocomplete.method.error": "Método de autocompletado inválido", - "blueprints.error.default.missing": "Falta el blueprint por defecto", - "error": "Error", - "error.headline": "Error" -} \ No newline at end of file diff --git a/panel/app/translations/es_ES/package.json b/panel/app/translations/es_ES/package.json deleted file mode 100644 index 16056dd..0000000 --- a/panel/app/translations/es_ES/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Español (España)", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/fa/core.json b/panel/app/translations/fa/core.json deleted file mode 100644 index 18d24f9..0000000 --- a/panel/app/translations/fa/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "انصراف", - "add": "افزودن", - "addit": "اضافه کردن و ویرایش", - "save": "ذخیره", - "saved": "ذخیره شد!", - "change": "اصلاح", - "delete": "حذف", - "insert": "درج", - "ok": "تایید", - "routes.error.invalid": "آدرس پنل نامعتبر است", - "controller.error.invalid": "کنترلر نامعتبر است", - "controller.error.action": "اقدام نامعتبر", - "view.error.invalid": "ویو نامعتبر است", - "options.show": "نمایش گزینه ها", - "options.hide": "پنهان کردن گزینه ها", - "installation": "نصب و راه اندازی", - "installation.check.headline": "نصب و راه اندازی کربی پنل", - "installation.check.text": "کربی در هنگام نصب با موارد زیر روبرو شده است…", - "installation.check.retry": "تلاش مجدد", - "installation.check.error": "مشکلی رخ داده است!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts قابل نوشتن نیست", - "installation.check.error.avatars": "/assets/avatars قابل نوشتن نیست", - "installation.check.error.blueprints": "لطفا پوشه /site/blueprints را ایجاد کنید", - "installation.check.error.content": "پوشه content و همه فایل ها و پوشه های موجود باید قابل نوشتن باشد.", - "installation.check.error.thumbs": "پوشه thumbs باید قابل نوشتن باشد.", - "installation.signup.username.label": "ایجاد اولین حساب کاربری", - "installation.signup.username.placeholder": "نام کاربری", - "installation.signup.email.label": "پست الکترونیک", - "installation.signup.email.placeholder": "mail@example.com", - "installation.signup.password.label": "گذرواژه", - "installation.signup.language.label": "زبان", - "installation.signup.button": "ایجاد حساب کاربری", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "نام کاربری", - "login.password.label": "گذرواژه", - "login.error": "نام کاربری یا گذرواژه صحیح نیست", - "login.button": "Log in", - "login.log.error.permissions": "فایل تاریخچه ورود کاربران غیرقابل نوشتن است", - "logout": "Log out", - "topbar.error.class.definition": "topbar برای کلاس تعریف نشده است:", - "dashboard": "پیشخوان", - "dashboard.index.pages.title": "صفحات", - "dashboard.index.pages.edit": "ویرایش", - "dashboard.index.pages.add": "افزودن", - "dashboard.index.site.title": "آدرس وبسایت شما", - "dashboard.index.account.title": "مشخصات کاربر جاری", - "dashboard.index.account.edit": "ویرایش", - "dashboard.index.metatags.title": "تنطیمات سایت", - "dashboard.index.metatags.edit": "ویرایش", - "dashboard.index.history.title": "آخرین بروزرسانی ها", - "dashboard.index.history.text": "آخرین صفحاتی که تغییر داده اید در این مکان جهت سهولت دسترسی نمایش داده خواهد شد.", - "dashboard.index.license.title": "مجوز نرم افزار", - "dashboard.index.license.text": "به نظر می‌رسد در حال اجرای کربی در یک سرور عمومی بدون یک مجوز معتبر هستید!\n\nلطفا پشتیبان کربی باشید و (link: {buy} text: همین حالا یک مجوز خریداری کنید)\n\nاگر در حال حاضر دارای یک کلید مجوز هستید، کافی است آن را به فایل پیکربندی خود اضافه کنید: (link: {docs} text: site/config/config.php)", - "metatags": "تنظیمات سایت", - "metatags.info": "اطلاعات نرم افزار", - "metatags.license": "مجوز", - "metatags.version.toolkit": "نسخه هسته", - "metatags.version.kirby": "نسخه نرم افزار", - "metatags.version.panel": "نسخه پنل مدیریت", - "metatags.back": "بازگشت به پیشخوان", - "metatags.files": "فایل های عمومی", - "site.delete.error": "حذف سایت ممکن نیست", - "pages.show.settings": "تنظیمات صفحه", - "pages.show.preview": "پیش نمایش", - "pages.show.template": "قالب صفحه", - "pages.show.changeurl": "تغییر نشانی اینترنتی صفحه", - "pages.show.invisible": "وضعیت: مخفی", - "pages.show.visible": "وضعیت: قابل مشاهده", - "pages.show.changes.text": "برخی تغییرات ذخیره نشده است!", - "pages.show.changes.button": "انصراف", - "pages.show.delete": "حذف صفحه جاری", - "pages.show.subpages.title": "صفحات", - "pages.show.subpages.edit": "ویرایش", - "pages.show.subpages.add": "افزودن", - "pages.show.subpages.empty": "فاقد صفحه فرعی", - "pages.show.files.title": "فایل ها", - "pages.show.files.edit": "ویرایش", - "pages.show.files.add": "افزودن", - "pages.show.files.empty": "فاقد فایل", - "pages.show.error.permissions.title": "صفحه قابل نوشتن نیست", - "pages.show.error.permissions.text": "لطفا دسترسی پوشه محتوا و تمام فایل ها را بررسی نمایید.", - "pages.show.error.permissions.retry": "تلاش مجدد", - "pages.show.error.notitle.title": "طرح الگو فیلد عنوان ندارد.", - "pages.show.error.notitle.text": "لطفا یک فیلد عنوان اضافه کنید و دوباره سعی کنید", - "pages.show.error.notitle.retry": "تلاش مجدد", - "pages.show.error.form": "لطفا همه فیلدها را به درستی پر نمایید", - "pages.add.title.label": "افزودن صفحه جدید", - "pages.add.title.placeholder": "عنوان", - "pages.add.url.label": "پیوست نشانی اینترنتی", - "pages.add.url.enter": "(عنوان خود را وارد کنید)", - "pages.add.url.close": "بستن", - "pages.add.url.help": "Format: lowercase a-z, 0-9 and regular dashes", - "pages.add.template.label": "قالب صفحه", - "pages.add.error.create": "صفحه ایجاد نشد", - "pages.add.error.title": "عنوان وارد نشده است", - "pages.add.error.template": "فالب وارد نشده است.", - "pages.add.error.max.headline": "ساخت صفحه جدید ممکن نیست", - "pages.add.error.max.text": "حداکثر تعداد زیرصفحه برای صفحه فعلی پر شده است.", - "pages.url.uid.label": "پیوست نشانی اینترنتی", - "pages.url.uid.label.option": "ایجاد از روی عنوان", - "pages.url.error.exists": "یک صفحه با پیوست مشابه در حال حاضر وجود دارد", - "pages.url.error.move": "پیوست تغییر نکرد", - "pages.url.error.rights": "شما امکان تغییر آدرس این صفحه را ندارید", - "pages.template.select.label": "قالب صفحه", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "موقعیت", - "pages.toggle.invisible": "مخفی", - "pages.toggle.publish": "آیااز تغییر وضعیت صفحه به **قابل مشاهده** مطمئن هستید؟", - "pages.toggle.hide": "آیااز تغییر وضعیت صفحه به **مخفی** مطمئن هستید؟", - "pages.toggle.error.error": "وضعیت صفحه خطا قابل تغییر نیست", - "pages.delete.headline": "صفحه جاری حذف شود؟", - "pages.delete.error.home.headline": "صفحه اصلی وب سایت نمی تواند حذف شود", - "pages.delete.error.home.text": "شما در حال تلاش برای حذف صفحه اصلی هستید. این امکان پذیر نمی باشد و به اثرات ناخواسته منجر می شود.", - "pages.delete.error.error.headline": "صفحه خطا نمی تواند حذف شود", - "pages.delete.error.error.text": "شما در حال تلاش برای حذف صفحه خطا هستید. این امکان پذیر نمی باشد و به اثرات ناخواسته منجر می شود.", - "pages.delete.error.children.headline": "حذف صفحه ممکن نیست", - "pages.delete.error.children.text": "این صفحه دارای زیرصفحه است و نمی تواند حذف شود. لطفا ابتدا تمام زیرصفحه های آنرا حذف کنید.", - "pages.delete.error.blocked.headline": "حذف صفحه ممکن نیست", - "pages.delete.error.blocked.text": "این صفحه قفل شده است و نمی تواند حذف شود.", - "pages.search.help": "صفحات را بر اساس نشانی اینترنتی جستجو کنید. با استفاده از کلیدهای جهت دار بالا و پایین ردیف مورد نظر خود را انتخاب و جهت انتقال به صفحه انتخابی کلید Enter را فشار دهید.", - "pages.search.noresults": "هیچ نتیجه ای منطبق بر درخواست شما وجود دارد. لطفا دوباره با یک نشانی اینترنتی متفاوت امتحان کنید.", - "pages.error.missing": "صفحه مورد نظر پیدا نشد.", - "subpages": "صفحات", - "subpages.index.headline": "صفحات فرعی", - "subpages.index.back": "بازگشت", - "subpages.index.add": "افزودن صفحه جدید", - "subpages.index.add.first.text": "این صفحه در حال حاضر هیچ زیرصفحه ای ندارد", - "subpages.index.add.first.button": "افزودن نخستین صفحه", - "subpages.index.visible": "صفحات قابل مشاهده", - "subpages.index.visible.help": "صفحات مخفی را جهت مرتب سازی و آشکارسازی به اینجا بکشید.", - "subpages.index.invisible": "صفحات مخفی", - "subpages.index.invisible.help": "صفحات آشکار را جهت مخفی کردن به اینجا بکشید.", - "subpages.add.error": "این صفحه نمی‌تواند دارای صفحات فرعی باشد", - "subpages.add.error.more": "ایجاد صفحات فرعی بیشتر ممکن نیست", - "subpages.error.missing": "صفحه مورد نظر پیدا نشد.", - "files": "فایل ها", - "files.index.headline": "فایل های مرتبط با", - "files.index.back": "بازگشت", - "files.index.upload": "آپلود فایل جدید", - "files.index.upload.first.text": "این صفحه در حال حاضر فاقد فایل است", - "files.index.upload.first.button": "آپلود نخستین فایل", - "files.index.edit": "ویرایش", - "files.index.delete": "حذف", - "files.index.error.disabled": "این صفحه نمی‌تواند دارای فایل باشد", - "files.add.error.max": "محدودیت حداکثر تعداد فایل برای صفحه فعلی سر رسیده است.", - "files.add.error.extension.missing": "شما نمی‌توانید فایل‌های بدون پسوند را آپلود کنید", - "files.add.error.extension.forbidden": "پسوند فایل غیرمجاز است", - "files.add.error.mime.forbidden": "فرمت فایل غیرمجاز است", - "files.add.error.htaccess": "امکان آپلود فایل htaccess وجود ندارد", - "files.add.error.invisible": "امکان آپلود فایلهای مخفی وجود ندارد", - "files.add.blueprint.type.error": "صفحه تنها اجازه می‌دهد که:", - "files.add.blueprint.size.error": "سایز فایل مجاز برای صفحه", - "files.show.name.label": "نام فایل", - "files.show.info.label": "نوع / حجم / ابعاد", - "files.show.link.label": "لینک عمومی", - "files.show.open": "نمایش/دانلود فایل", - "files.show.back": "بازگشت", - "files.show.replace": "جایگزینی", - "files.show.delete": "حذف", - "files.show.error.rename": "فایل را نمی توان تغییر نام داد", - "files.show.error.form": "لطفا همه فیلدها را به درستی پر نمایید", - "files.upload.drop": "فایل ها را اینجا رها کنید…", - "files.upload.click": "…یا جهت انتخاب فایل کلیک کنید", - "files.replace.drop": "فایل ها را اینجا رها کنید…", - "files.replace.click": "…یا جهت انتخاب فایل کلیک کنید", - "files.replace.error.type": "فایل آپلود شده باید نوع فایل یکسان داشته باشد", - "files.delete.headline": "آیا شما واقعا می خواهید این فایل را حذف کنید؟", - "files.error.missing.page": "صفحه مورد نظر پیدا نشد.", - "files.error.missing.file": "فایل مورد نظر پیدا نشد.", - "users": "کاربران", - "users.index.headline": "همه کاربران", - "users.index.add": "افزودن کاربر جدید", - "users.index.edit": "ویرایش", - "users.index.delete": "حذف", - "users.form.username.label": "نام کاربری", - "users.form.username.placeholder": "نام کاربری شما", - "users.form.username.help": "حروف مجاز: حروف کوچک a-z، اعداد 0-9 و خط تیره -", - "users.form.username.readonly": "نام کاربری را نمیتوان تغییر داد", - "users.form.firstname.label": "نام", - "users.form.lastname.label": "نام خانوادگی", - "users.form.email.label": "پست الکترونیک", - "users.form.email.placeholder": "mail@example.com", - "users.form.password.label": "گذرواژه", - "users.form.password.confirm.label": "تکرار گذرواژه", - "users.form.password.new.label": "گذرواژه جدید", - "users.form.password.new.confirm.label": "تکرار گذرواژه", - "users.form.password.new.help": "برای حفظ گذرواژه فعلی فیلد را خالی رها کنید", - "users.form.language.label": "زبان", - "users.form.role.label": "نقش", - "users.form.options.headline": "گزینه های حساب کاربری", - "users.form.options.message": "ارسال پست الکترونیک", - "users.form.options.delete": "حذف حساب کاربری", - "users.form.avatar.headline": "تصویر پروفایل", - "users.form.avatar.upload": "آپلود تصویر پروفایل", - "users.form.avatar.replace": "جایگزینی تصویر پروفایل", - "users.form.avatar.delete": "حذف نصویر پروفایل", - "users.form.back": "بازگشت به لیست کاربران", - "users.form.error.password.confirm": "لطفا تکرار گذرواژه را وارد نمایید", - "users.form.error.update": "کاربر نمی تواند به روز شود", - "users.form.error.update.rights": "شما اجازه بروزرسانی این کاربر را ندارید", - "users.form.error.create": "کاربر نمی تواند ایجاد شود", - "users.form.error.permissions.title": "پوشه account قابل نوشتن نیست", - "users.form.error.permissions.text": "لطفا مطمئن شوید که /site/accounts موجود و قابل نوشتن است.", - "users.delete.headline": "کاربر جاری حذف شود؟", - "users.delete.error": "کاربر نمی تواند حذف شود", - "users.delete.error.permission": "شما اجازه حذف کاربران را ندارید", - "users.delete.error.permission.single": "شما اجازه حذف این کاربر را ندارید", - "users.delete.error.lastadmin": "حذف آخرین مدیر سیستم ممکن نیست", - "users.avatar.drop": "تصویر پروفایل را اینجا رها کنید…", - "users.avatar.click": "یا برای انتخاب و آپلود کلیک کنید", - "users.avatar.error.type": "شما فقط می توانید فایل های JPG، PNG و GIF آپلود کنید", - "users.avatar.error.folder.headline": "پوشه avatar قایل نوشتن نیست", - "users.avatar.error.folder.text": "جهت آپلود تصویر پروفایل پوشه /assets/avatars را ایجاد و آن را قابل نوشتن کنید.", - "users.avatar.error.permission": "شما اجازه تغییر تصویر پروفایل را ندارید", - "users.avatar.delete.error": "تصویر پروفایل را نمیتوان حذف کرد", - "users.avatar.delete.error.permission": "شما اجازه حذف تصویر پروفایل این کاربر را ندارید", - "users.avatar.delete.success": "تصویر پروفایل حذف شد", - "users.avatar.missing": "فاقد تصویر پروفایل", - "users.error.missing": "کاربر مورد نظر پیدا نشد", - "user.error.lastadmin": "شما تنها کاربر مدیر این سیستم هستید و تغییر آن ممکن نیست", - "form.error.missing": "فرم یافت نشد", - "form.construct.error.invalid": "روال ساخت فرم نامعتبر است", - "fields.required": "اجباری", - "fields.date.label": "تاریخ", - "fields.date.months": [ - "ژانویه", - "فوریه", - "مارس", - "آوریل", - "می", - "ژوئن", - "ژوئیه", - "اوت", - "سپتامبر", - "اکتبر", - "نوامبر", - "دسامبر" - ], - "fields.date.weekdays": [ - "یکشنبه", - "دوشنبه", - "سه شنبه", - "چهارشنبه", - "پنجشنبه", - "جمعه", - "شنبه" - ], - "fields.date.weekdays.short": [ - "یکشنبه", - "دوشنبه", - "سه شنبه", - "چهارشنبه", - "پنجشنبه", - "جمعه", - "شنبه" - ], - "fields.email.label": "پست الکترونیک", - "fields.email.placeholder": "mail@example.com", - "fields.number.label": "عدد", - "fields.number.placeholder": "#", - "fields.page.label": "صفحه", - "fields.page.placeholder": "path/to/page", - "fields.password.label": "گذرواژه", - "fields.structure.add": "افزودن", - "fields.structure.add.first": "افزودن نخستین مورد", - "fields.structure.empty": "موردی وجود ندارد.", - "fields.structure.entry.error": "آیتم یافت نشد", - "fields.structure.cancel": "انصراف", - "fields.structure.save": "تایید", - "fields.structure.edit": "ویرایش", - "fields.structure.delete": "حذف", - "fields.structure.delete.label": "مدخل جاری حذف شود؟", - "fields.tags.label": "برچسب ها", - "fields.tel.label": "تلفن", - "fields.textarea.buttons.bold.label": "متن با حروف درشت", - "fields.textarea.buttons.bold.text": "متن با حروف درشت", - "fields.textarea.buttons.italic.label": "متن اریب", - "fields.textarea.buttons.italic.text": "متن اریب", - "fields.textarea.buttons.link.label": "پیوند", - "fields.textarea.buttons.email.label": "پست الکترونیک", - "fields.textarea.buttons.image.label": "تصویر", - "fields.textarea.buttons.file.label": "فایل", - "fields.toggle.yes": "بله", - "fields.toggle.no": "خیر", - "fields.toggle.on": "روشن", - "fields.toggle.off": "خاموش", - "fields.error.missing.controller": "فایل کنترلر فیلد یافت نشد", - "fields.error.missing.class": "کلاس کنترلر فیلد سافت نشد", - "fields.error.route.invalid": "مسید فیلد نامعتبر است", - "fields.error.extended": "توسعه فیلد ممکن نیست", - "editor.link.url.label": "آدرس پیوند", - "editor.link.text.label": "متن پیوند", - "editor.link.text.help": "متن پیوند اختیاری است", - "editor.email.address.label": "درج نشانی پست الکترونیک", - "editor.email.address.placeholder": "mail@example.com", - "editor.email.text.label": "متن پیوند", - "editor.email.text.help": "متن پیوند اختیاری است", - "editor.file.empty": "این صفحه فاقد فایل است", - "editor.image.empty": "این صفحه فاقد تصویر است", - "autocomplete.method.error": "روال تکمیل خودکار معتبر نیست", - "blueprints.error.default.missing": "طرح الگوی پیش‌فرض یافت نشد", - "error": "خطا", - "error.headline": "خطا" -} \ No newline at end of file diff --git a/panel/app/translations/fa/package.json b/panel/app/translations/fa/package.json deleted file mode 100644 index a80ab8f..0000000 --- a/panel/app/translations/fa/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "پارسی", - "direction": "rtl" -} \ No newline at end of file diff --git a/panel/app/translations/fi/core.json b/panel/app/translations/fi/core.json deleted file mode 100644 index ddfa940..0000000 --- a/panel/app/translations/fi/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Peruuta", - "add": "Lisää", - "addit": "Add & Edit", - "save": "Tallenna", - "saved": "Tallennettu!", - "change": "Change", - "delete": "Poista", - "insert": "Lisää", - "ok": "Ok", - "routes.error.invalid": "Invalid Panel URL", - "controller.error.invalid": "Invalid controller", - "controller.error.action": "Invalid action", - "view.error.invalid": "Invalid view:", - "options.show": "Näytä asetukset", - "options.hide": "Piilota asetukset", - "installation": "Asennus", - "installation.check.headline": "Kirby Panel asennus", - "installation.check.text": "Kirby havaitsi seuraavat virheet asennuksen yhteydessä…", - "installation.check.retry": "Yritä uudelleen", - "installation.check.error": "Muutama ongelma löytyi!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts edellyttää kirjoitusoikeudet", - "installation.check.error.avatars": "/assets/avatars edellyttää kirjoitusoikeudet", - "installation.check.error.blueprints": "Ole hyvä ja lisää /site/blueprints kansio", - "installation.check.error.content": "/content ja kaikki sen alla olevat tiedostot ja kansiot edellyttävät kirjoitusoikeudet.", - "installation.check.error.thumbs": "/thumbs edellyttää kirjoitusikeudet.", - "installation.signup.username.label": "Luo ensimmäinen käyttäjä", - "installation.signup.username.placeholder": "Tunnus", - "installation.signup.email.label": "Sähköposti", - "installation.signup.email.placeholder": "nimi@osoite.fi", - "installation.signup.password.label": "Salasana", - "installation.signup.language.label": "Kieli", - "installation.signup.button": "Luo käyttäjä", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Käyttäjätunnus", - "login.password.label": "Salasana", - "login.error": "Tunnus tai salasana on virheellinen", - "login.button": "Log in", - "login.log.error.permissions": "Login log file is not writable.", - "logout": "Log out", - "topbar.error.class.definition": "Missing topbar definition for class:", - "dashboard": "Hallintapaneeli", - "dashboard.index.pages.title": "Sivut", - "dashboard.index.pages.edit": "Muokkaa", - "dashboard.index.pages.add": "Lisää", - "dashboard.index.site.title": "Sivuston URL-osoite", - "dashboard.index.account.title": "Käyttäjätilisi", - "dashboard.index.account.edit": "Muokkaa", - "dashboard.index.metatags.title": "Sivuston asetukset", - "dashboard.index.metatags.edit": "Muokkaa", - "dashboard.index.history.title": "Viimeisimmät päivityksesi", - "dashboard.index.history.text": "Viimeksi muokkaamasi sivut listataan tässä jotta löydät ne jatkossa helpommin.", - "dashboard.index.license.title": "Kirby license", - "dashboard.index.license.text": "It seems you are running Kirby on a public server without a valid license!\n\nPlease, support Kirby and (link: {buy} text: buy a license now)\n\nIf you already have a license key, just add it to your config file: (link: {docs} text: site/config/config.php)", - "metatags": "Sivuston asetukset", - "metatags.info": "Kirby info", - "metatags.license": "Kirby license", - "metatags.version.toolkit": "Toolkit version", - "metatags.version.kirby": "Kirby version", - "metatags.version.panel": "Panel version", - "metatags.back": "Takaisin hallintapaneeliin", - "metatags.files": "Site files", - "site.delete.error": "The site cannot be deleted", - "pages.show.settings": "Sivun asetukset", - "pages.show.preview": "Esikatselu", - "pages.show.template": "Sivupohja", - "pages.show.changeurl": "Vaihda URL-osoite", - "pages.show.invisible": "Status: invisible", - "pages.show.visible": "Status: visible", - "pages.show.changes.text": "You have unsaved changes!", - "pages.show.changes.button": "Discard", - "pages.show.delete": "Poista tämä sivu", - "pages.show.subpages.title": "Sivut", - "pages.show.subpages.edit": "Muokkaa", - "pages.show.subpages.add": "Lisää", - "pages.show.subpages.empty": "Tälle sivulle ei ole lisätty alasivuja", - "pages.show.files.title": "Tiedostot", - "pages.show.files.edit": "Muokkaa", - "pages.show.files.add": "Lisää", - "pages.show.files.empty": "Tälle sivulle ei ole lisätty tiedostoja", - "pages.show.error.permissions.title": "Sivun muokkaamista ei ole sallittu", - "pages.show.error.permissions.text": "Ole hyvä ja tarkista kansion /content ja sen alla olevien tiedostojen kirjoitusoikeudet.", - "pages.show.error.permissions.retry": "Yritä uudelleen", - "pages.show.error.notitle.title": "Tässä pohjassa ei ole nimikenttää", - "pages.show.error.notitle.text": "Ole hyvä ja lisää ensin nimikenttä", - "pages.show.error.notitle.retry": "Yritä uudelleen", - "pages.show.error.form": "Ole hyvä ja täytä kaikki kentät oikein.", - "pages.add.title.label": "Lisää uusi sivu", - "pages.add.title.placeholder": "Nimi", - "pages.add.url.label": "URL-osoite", - "pages.add.url.enter": "(kirjoita osoite)", - "pages.add.url.close": "Sulje", - "pages.add.url.help": "Sallitut merkit: pienet kirjaimet a-z, 0-9 sekä väliviivat", - "pages.add.template.label": "Sivupohja", - "pages.add.error.create": "The page could not be created", - "pages.add.error.title": "Otsikko puuttuu", - "pages.add.error.template": "Sivupohjaa ei ole asetettu", - "pages.add.error.max.headline": "Uusia sivuja ei voi enää luoda", - "pages.add.error.max.text": "Nykyiselle sivulle ei voi luoda enempää alasivuja", - "pages.url.uid.label": "URL-pääte", - "pages.url.uid.label.option": "Luo nimen perusteella", - "pages.url.error.exists": "Olemassaolevalla sivulla on jo sama URL-pääte", - "pages.url.error.move": "Päätettä ei voitu muuttaa", - "pages.url.error.rights": "You cannot change the URL of this page", - "pages.template.select.label": "Sivupohja", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Position", - "pages.toggle.invisible": "invisible", - "pages.toggle.publish": "Do you really want to change the status of this page to **visible?**", - "pages.toggle.hide": "Do you really want to change the status of this page to **invisible?**", - "pages.toggle.error.error": "The status of the error page cannot be changed", - "pages.delete.headline": "Haluatko varmasti poistaa sivun?", - "pages.delete.error.home.headline": "Aloitussivua ei voi poistaa", - "pages.delete.error.home.text": "Sivuston aloitussivun poistaminen ei ole mahdollista.", - "pages.delete.error.error.headline": "Virhesivua ei voi poistaa", - "pages.delete.error.error.text": "Virhesivun poistaminen ei ole mahdollista.", - "pages.delete.error.children.headline": "Sivua ei voida poistaa", - "pages.delete.error.children.text": "Tällä sivulla on alasivuja, jotka pitää poistaa ennen kuin itse sivu voidaan poistaa.", - "pages.delete.error.blocked.headline": "Sivua ei voida poistaa", - "pages.delete.error.blocked.text": "Tämä sivu on suojattu eikä sitä voida poistaa.", - "pages.search.help": "Hae sivuja osoitteen perusteella. Voit selata hakutuloksia nuolinäppäimillä ylös tai alas, ja painamalla ENTER siirryt valitulle sivulle.", - "pages.search.noresults": "Hakutermeillä ei löytynyt tuloksia.", - "pages.error.missing": "Sivua ei löytynyt", - "subpages": "Sivut", - "subpages.index.headline": "Alasivut sivulla", - "subpages.index.back": "Takaisin", - "subpages.index.add": "Lisää uusi sivu", - "subpages.index.add.first.text": "Tälle sivulle ei ole vielä lisätty alasivuja", - "subpages.index.add.first.button": "Lisää alasivu", - "subpages.index.visible": "Näkyvät sivut", - "subpages.index.visible.help": "Raahaa piilotetut sivut tähän jotta voit tehdä niistä näkyviä tai muuttaa niiden järjestystä.", - "subpages.index.invisible": "Piilotetut sivut", - "subpages.index.invisible.help": "Raahaa näkyvät sivut tähän niin voit tehdä niistä piilotettuja.", - "subpages.add.error": "This page is not allowed to have subpages", - "subpages.add.error.more": "This page cannot have any more subpages", - "subpages.error.missing": "Sivua ei löytynyt", - "files": "Tiedostot", - "files.index.headline": "Tiedostot sivulla", - "files.index.back": "Takaisin", - "files.index.upload": "Lisää uusi tiedosto", - "files.index.upload.first.text": "Tälle sivulle ei ole lisätty tiedostoja", - "files.index.upload.first.button": "Lisää tiedosto", - "files.index.edit": "Muokkaa", - "files.index.delete": "Poista", - "files.index.error.disabled": "The page is not allowed to have any files", - "files.add.error.max": "The maximum number of files for the current page has been reached.", - "files.add.error.extension.missing": "You cannot upload files without extension", - "files.add.error.extension.forbidden": "Forbidden file extension", - "files.add.error.mime.forbidden": "Forbidden mime type", - "files.add.error.htaccess": "htaccess files cannot be uploaded", - "files.add.error.invisible": "Invisible files cannot be uploaded", - "files.add.blueprint.type.error": "Page only allows:", - "files.add.blueprint.size.error": "Page only allows file size of", - "files.show.name.label": "Tiedostonimi", - "files.show.info.label": "Tyyppi / Koko / Mitat", - "files.show.link.label": "Julkinen linkki", - "files.show.open": "Näytä/lisää tiedosto", - "files.show.back": "Takaisin", - "files.show.replace": "Korvaa", - "files.show.delete": "Poista", - "files.show.error.rename": "Tiedostoa ei voitu nimetä uudelleen", - "files.show.error.form": "Ole hyvä ja täytä kaikki kentät oikein", - "files.upload.drop": "Raahaa tiedostot tähän…", - "files.upload.click": "…tai valitse tiedosto", - "files.replace.drop": "Raahaa tiedosto tähän…", - "files.replace.click": "…tai valitse uusi tiedosto", - "files.replace.error.type": "Uuden ja korvattavan tiedoston tulee olla samaa tyyppiä", - "files.delete.headline": "Haluatko varmasti poistaa tiedoston?", - "files.error.missing.page": "Sivua ei löytynyt", - "files.error.missing.file": "Tiedostoa ei löytynyt", - "users": "Käyttäjät", - "users.index.headline": "Kaikki käyttäjät", - "users.index.add": "Lisää uusi käyttäjä", - "users.index.edit": "Muokkaa", - "users.index.delete": "Poista", - "users.form.username.label": "Käyttäjätunnus", - "users.form.username.placeholder": "Tunnuksesi", - "users.form.username.help": "Sallitut merkit: pienet kirjaimet a-z, 0-9 sekä väliviivat", - "users.form.username.readonly": "Tunnuksen muuttamista ei ole sallittu", - "users.form.firstname.label": "Etunimi", - "users.form.lastname.label": "Sukunimi", - "users.form.email.label": "Sähköposti", - "users.form.email.placeholder": "nimi@osoite.fi", - "users.form.password.label": "Salasana", - "users.form.password.confirm.label": "Salasana uudelleen", - "users.form.password.new.label": "Uusi salasana", - "users.form.password.new.confirm.label": "Uusi salasana uudelleen", - "users.form.password.new.help": "Jätä tyhjäksi jos et halua vaihtaa salasanaasi", - "users.form.language.label": "Kieli", - "users.form.role.label": "Käyttäjätaso", - "users.form.options.headline": "Tilinhallinta", - "users.form.options.message": "Lähetä sähköposti", - "users.form.options.delete": "Poista tili", - "users.form.avatar.headline": "Profiilikuva", - "users.form.avatar.upload": "Lisää profiilikuva", - "users.form.avatar.replace": "Vaihda profiilikuva", - "users.form.avatar.delete": "Poista profiilikuva", - "users.form.back": "Takaisin käyttäjähallintaan", - "users.form.error.password.confirm": "Varmista salasana", - "users.form.error.update": "Käyttäjätilin päivitys epäonnistui", - "users.form.error.update.rights": "You are not allowed to update this user", - "users.form.error.create": "Käyttäjätilin luominen epäonnistui", - "users.form.error.permissions.title": "Käyttäjähakemistoon ei voitu kirjoittaa", - "users.form.error.permissions.text": "Ole hyvä ja varmista että /site/accounts on olemassa ja tarkista sen kirjoitusoikeudet.", - "users.delete.headline": "Haluatko varmsti poistaa käyttäjän?", - "users.delete.error": "Käyttäjää ei voitu poistaa", - "users.delete.error.permission": "You are not allowed to delete users", - "users.delete.error.permission.single": "You are not allowed to delete this user", - "users.delete.error.lastadmin": "You cannot delete the last admin", - "users.avatar.drop": "Raahaa profiilikuva tähän…", - "users.avatar.click": "…tai valitse tiedosto", - "users.avatar.error.type": "Kuvien tulee olla JPG, PNG tai GIF muodossa", - "users.avatar.error.folder.headline": "Kansio avatar vaatii kirjoitusoikeudet", - "users.avatar.error.folder.text": "Profiilikuvan lisääminen edellyttää /assets/avatars kansion luomista ja kirjoitusoikeuksia.", - "users.avatar.error.permission": "You are not allowed to change the avatar", - "users.avatar.delete.error": "Profiilikuvaa ei voitu poistaa", - "users.avatar.delete.error.permission": "You are not allowed to delete the avatar of this user", - "users.avatar.delete.success": "Profiilikuva poistettiin", - "users.avatar.missing": "This user has no avatar", - "users.error.missing": "Käyttäjää ei löytynyt", - "user.error.lastadmin": "You are the only admin. This cannot be changed.", - "form.error.missing": "The form cannot be found", - "form.construct.error.invalid": "Invalid form construction method", - "fields.required": "Pakollinen", - "fields.date.label": "Päivämäärä", - "fields.date.months": [ - "Tammikuu", - "Helmikuu", - "Maaliskuu", - "Huhtikuu", - "Toukokuu", - "Kesäkuu", - "Heinäkuu", - "Elokuu", - "Syyskuu", - "Lokakuu", - "Marraskuu", - "Joulukuu" - ], - "fields.date.weekdays": [ - "Sunnuntai", - "Maanantai", - "Tiistai", - "Keskiviikko", - "Torstai", - "Perjantai", - "Lauantai" - ], - "fields.date.weekdays.short": [ - "Su", - "Ma", - "Ti", - "Ke", - "To", - "Pe", - "La" - ], - "fields.email.label": "Sähköposti", - "fields.email.placeholder": "nimi@osoite.fi", - "fields.number.label": "Numero", - "fields.number.placeholder": "#", - "fields.page.label": "Sivu", - "fields.page.placeholder": "polku/sivulle", - "fields.password.label": "Salasana", - "fields.structure.add": "Lisää", - "fields.structure.add.first": "Lisää ensimmäinen kirjoitus", - "fields.structure.empty": "Ei kirjoituksia toistaiseksi.", - "fields.structure.entry.error": "The item could not be found", - "fields.structure.cancel": "Peruuta", - "fields.structure.save": "Tallenna", - "fields.structure.edit": "Muokkaa", - "fields.structure.delete": "Poista", - "fields.structure.delete.label": "Do you really want to delete this entry?", - "fields.tags.label": "Avainsanat", - "fields.tel.label": "Puhelin", - "fields.textarea.buttons.bold.label": "Lihavointi", - "fields.textarea.buttons.bold.text": "Lihavointi", - "fields.textarea.buttons.italic.label": "Kursivointi", - "fields.textarea.buttons.italic.text": "Kursivointi", - "fields.textarea.buttons.link.label": "Linkki", - "fields.textarea.buttons.email.label": "Sähköposti", - "fields.textarea.buttons.image.label": "Kuva", - "fields.textarea.buttons.file.label": "Tiedosto", - "fields.toggle.yes": "Kyllä", - "fields.toggle.no": "Ei", - "fields.toggle.on": "Päällä", - "fields.toggle.off": "Pois päältä", - "fields.error.missing.controller": "The field controller file is missing", - "fields.error.missing.class": "The field controller class is missing", - "fields.error.route.invalid": "Invalid field route", - "fields.error.extended": "The field cannot be extended", - "editor.link.url.label": "Lisää URL-osoite", - "editor.link.text.label": "Linkin teksti", - "editor.link.text.help": "Linkin teksti on valinnainen", - "editor.email.address.label": "Lisää sähköpostiosoite", - "editor.email.address.placeholder": "nimi@osoite.fi", - "editor.email.text.label": "Linkin testi", - "editor.email.text.help": "Linkin teksti on valinnainen", - "editor.file.empty": "Sivulle ei ole lisätty tiedostoja", - "editor.image.empty": "Sivulle ei ole lisätty kuvia", - "autocomplete.method.error": "Invalid autocomplete method", - "blueprints.error.default.missing": "Missing default blueprint", - "error": "Virhe", - "error.headline": "Virhe" -} \ No newline at end of file diff --git a/panel/app/translations/fi/package.json b/panel/app/translations/fi/package.json deleted file mode 100644 index 609698d..0000000 --- a/panel/app/translations/fi/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Suomi", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/fr/core.json b/panel/app/translations/fr/core.json deleted file mode 100644 index 75930d1..0000000 --- a/panel/app/translations/fr/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Annuler", - "add": "Ajouter", - "addit": "Ajouter et éditer", - "save": "Enregistrer", - "saved": "Enregistré !", - "change": "Modifier", - "delete": "Supprimer", - "insert": "Insérer", - "ok": "Ok", - "routes.error.invalid": "URL du Panel incorrecte", - "controller.error.invalid": "Contrôleur incorrect", - "controller.error.action": "Action incorrecte", - "view.error.invalid": "Vue incorrecte : ", - "options.show": "Afficher les options", - "options.hide": "Masquer les options", - "installation": "Installation", - "installation.check.headline": "Installation de Kirby Panel", - "installation.check.text": "Durant l’installation, Kirby a rencontré les problèmes suivants…", - "installation.check.retry": "Essayer de nouveau", - "installation.check.error": "Des problèmes on été rencontrés !", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "Le répertoire “/site/accounts” n’est pas accessible en écriture", - "installation.check.error.avatars": "Le répertoire “/assets/avatars” n’est pas accessible en écriture", - "installation.check.error.blueprints": "Veuillez ajouter un répertoire “/site/blueprints”", - "installation.check.error.content": "Le répertoire “/content”, les sous-répertoires et les fichiers qu’il contient doivent être accessibles en écriture.", - "installation.check.error.thumbs": "Le répertoire “thumbs/” doit être accessible en écriture.", - "installation.signup.username.label": "Créer votre premier compte utilisateur", - "installation.signup.username.placeholder": "Nom d’utilisateur", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@exemple.com", - "installation.signup.password.label": "Mot de passe", - "installation.signup.language.label": "Langue", - "installation.signup.button": "Créer votre compte", - "login": "Connexion", - "login.welcome": "Veuillez vous identifier avec votre nouveau compte", - "login.username.label": "Identifiant", - "login.password.label": "Mot de passe", - "login.error": "Identifiant ou mot de passe incorrect", - "login.button": "Connexion", - "login.log.error.permissions": "Le journal de connexion n’est pas accessible en écriture.", - "logout": "Déconnexion", - "topbar.error.class.definition": "Définition de topbar manquante pour la classe : ", - "dashboard": "Tableau de bord", - "dashboard.index.pages.title": "Pages", - "dashboard.index.pages.edit": "Modifier", - "dashboard.index.pages.add": "Ajouter", - "dashboard.index.site.title": "URL de votre site", - "dashboard.index.account.title": "Votre profil", - "dashboard.index.account.edit": "Modifier", - "dashboard.index.metatags.title": "Paramètres du site", - "dashboard.index.metatags.edit": "Modifier", - "dashboard.index.history.title": "Modifications récentes", - "dashboard.index.history.text": "Vos modifications les plus récentes seront affichées ici afin de les retrouver plus aisément.", - "dashboard.index.license.title": "Licence de Kirby", - "dashboard.index.license.text": "Il semblerait que vous utilisiez Kirby sans licence valide sur un serveur public !\n\nMerci de soutenir Kirby en (link: {buy} text: achetant une licence maintenant)\n\nSi vous avez déjà une licence, ajoutez-là simplement à votre fichier de configuration : (link: {docs} text: site/config/config.php)", - "metatags": "Paramètres du site", - "metatags.info": "Informations de Kirby", - "metatags.license": "License de Kirby", - "metatags.version.toolkit": "Version du Toolkit", - "metatags.version.kirby": "Version de Kirby", - "metatags.version.panel": "Version du Panel", - "metatags.back": "Retour au tableau de bord", - "metatags.files": "Fichiers du site", - "site.delete.error": "Le site ne peut être supprimé", - "pages.show.settings": "Options de la page", - "pages.show.preview": "Prévisualiser", - "pages.show.template": "Modèle de page", - "pages.show.changeurl": "Modifier l’URL", - "pages.show.invisible": "Statut : invisible", - "pages.show.visible": "Statut : visible", - "pages.show.changes.text": "Vous avez des modifications non enregistrées !", - "pages.show.changes.button": "Les supprimer", - "pages.show.delete": "Supprimer cette page", - "pages.show.subpages.title": "Pages", - "pages.show.subpages.edit": "Modifier", - "pages.show.subpages.add": "Ajouter", - "pages.show.subpages.empty": "Cette page n’a aucune page secondaire", - "pages.show.files.title": "Fichiers", - "pages.show.files.edit": "Modifier", - "pages.show.files.add": "Ajouter", - "pages.show.files.empty": "Cette page n’a aucun fichier attaché", - "pages.show.error.permissions.title": "La page n’est pas accessible en écriture", - "pages.show.error.permissions.text": "Merci de vérifier les permissions pour le répertoire “/content” et ses fichiers.", - "pages.show.error.permissions.retry": "Essayer de nouveau", - "pages.show.error.notitle.title": "Ce blueprint n’a pas de champs “title”", - "pages.show.error.notitle.text": "Veuillez ajouter un champs “title” et essayer de nouveau", - "pages.show.error.notitle.retry": "Essayer de nouveau", - "pages.show.error.form": "Merci de remplir correctement l’ensemble des champs", - "pages.add.title.label": "Ajouter une nouvelle page", - "pages.add.title.placeholder": "Titre", - "pages.add.url.label": "Identifiant pour l’URL de la page", - "pages.add.url.enter": "(saisir votre titre)", - "pages.add.url.close": "Fermer", - "pages.add.url.help": "Format : minuscules a-z, chiffres 0-9 et tiret simple", - "pages.add.template.label": "Modèle de page", - "pages.add.error.create": "La page n'a pu être créée", - "pages.add.error.title": "Le titre est manquant", - "pages.add.error.template": "Le template est manquant", - "pages.add.error.max.headline": "La création de nouvelles pages secondaires n’est pas autorisé pour cette page", - "pages.add.error.max.text": "Le nombre maximum de sous-pages a été atteint pour cette page.", - "pages.url.uid.label": "Identifiant de l’URL", - "pages.url.uid.label.option": "Créer à partir du titre", - "pages.url.error.exists": "Une page du même nom existe déjà", - "pages.url.error.move": "L’identifiant de l’URL n’a pu être changé", - "pages.url.error.rights": "Vous ne pouvez pas modifier l’URL de cette page", - "pages.template.select.label": "Modèle de page", - "pages.template.warning.text": "Les champs suivants seront modifiés si vous changez de modèle de page", - "pages.template.warning.removed": "Champs supprimés", - "pages.template.warning.replaced": "Champs remplacés", - "pages.template.warning.added": "Champs ajoutés", - "pages.template.error": "Le modèle de cette page ne peut être changé", - "pages.toggle.position": "Position", - "pages.toggle.invisible": "invisible", - "pages.toggle.publish": "Voulez-vous vraiment modifier le statut de cette page en **visible**?", - "pages.toggle.hide": "Voulez-vous vraiment modifier le statut de cette page en **invisible**?", - "pages.toggle.error.error": "Le statut de la page d'erreur ne peut pas être modifié", - "pages.delete.headline": "Voulez-vous vraiment supprimer définitivement cette page ?", - "pages.delete.error.home.headline": "La page d’accueil ne peut être supprimée", - "pages.delete.error.home.text": "Vous essayez de supprimer la page d’accueil. Ce n’est pas possible car cela entraînerait des effets indésirables.", - "pages.delete.error.error.headline": "La page d’erreur ne peut être supprimée", - "pages.delete.error.error.text": "Vous essayez de supprimer la page d’erreur. Ce n’est pas possible car cela aurait des effets indésirables.", - "pages.delete.error.children.headline": "La page ne peut être supprimée", - "pages.delete.error.children.text": "Cette page contient des pages secondaires. Veuillez supprimer les pages associées au préalable.", - "pages.delete.error.blocked.headline": "La page ne peut être supprimée", - "pages.delete.error.blocked.text": "Cette page est verrouillée et ne peut être supprimée.", - "pages.search.help": "Rechercher des pages par URL. Naviguer entre les résultats avec les flèches « haut » et « bas » du clavier, puis appuyer sur la touche « Entrée » pour aller à la page sélectionnée.", - "pages.search.noresults": "Il n’y a pas de résultat à votre recherche. Veuillez essayer de nouveau avec une URL différente.", - "pages.error.missing": "La page n’a pu être trouvée", - "subpages": "Pages", - "subpages.index.headline": "Pages dans", - "subpages.index.back": "Retour", - "subpages.index.add": "Ajouter une nouvelle page", - "subpages.index.add.first.text": "Cette page n’a pas encore de page secondaire", - "subpages.index.add.first.button": "Ajouter une première page", - "subpages.index.visible": "Pages visibles", - "subpages.index.visible.help": "Glisser une page invisible ici pour la classer/la rendre visible.", - "subpages.index.invisible": "Pages invisibles", - "subpages.index.invisible.help": "Glisser une page ici pour la rendre invisible.", - "subpages.add.error": "Cette page ne peut contenir de sous-page", - "subpages.add.error.more": "Cette page ne peut plus avoir de sous-page supplémentaire", - "subpages.error.missing": "La page n’a pu être trouvée", - "files": "Fichiers", - "files.index.headline": "Fichiers pour la page :", - "files.index.back": "Retour", - "files.index.upload": "Ajouter un fichier", - "files.index.upload.first.text": "Cette page n’a pas encore de fichier attaché", - "files.index.upload.first.button": "Ajouter un premier fichier", - "files.index.edit": "Modifier", - "files.index.delete": "Supprimer", - "files.index.error.disabled": "La page ne peut contenir de page secondaire", - "files.add.error.max": "Le nombre maximum de fichiers de cette page a été atteint.", - "files.add.error.extension.missing": "Vous ne pouvez transférer de fichier sans extension", - "files.add.error.extension.forbidden": "Extension de fichier interdite", - "files.add.error.mime.forbidden": "Ce type MIME est interdit", - "files.add.error.htaccess": "Les fichiers htaccess ne peuvent être transférés", - "files.add.error.invisible": "Les fichiers invisibles ne peuvent être transférés", - "files.add.blueprint.type.error": "La page n’autorise que :", - "files.add.blueprint.size.error": "La page n’autorise qu’un poids de fichier de", - "files.show.name.label": "Nom du fichier", - "files.show.info.label": "Type / Poids / Dimensions", - "files.show.link.label": "Lien public", - "files.show.open": "Afficher/télécharger le fichier", - "files.show.back": "Retour", - "files.show.replace": "Remplacer", - "files.show.delete": "Supprimer", - "files.show.error.rename": "Le fichier n’a pu être renommé", - "files.show.error.form": "Merci de remplir correctement chaque champ du formulaire", - "files.upload.drop": "Glisser un fichier ici…", - "files.upload.click": "…ou cliquer pour le transférer depuis votre ordinateur", - "files.replace.drop": "Glisser un fichier ici…", - "files.replace.click": "…ou cliquer pour le remplacer", - "files.replace.error.type": "Le fichier transféré doit être du même type", - "files.delete.headline": "Voulez-vous vraiment supprimer ce fichier ?", - "files.error.missing.page": "La page n’a pu être trouvée", - "files.error.missing.file": "Le fichier n’a pu être trouvé", - "users": "Utilisateurs", - "users.index.headline": "Tous les utilisateurs", - "users.index.add": "Ajouter un utilisateur", - "users.index.edit": "Modifier", - "users.index.delete": "Supprimer", - "users.form.username.label": "Nom d’utilisateur", - "users.form.username.placeholder": "Votre nom d’utilisateur", - "users.form.username.help": "Caractères autorisés : minuscules a-z, chiffres 0-9 et tirets simple", - "users.form.username.readonly": "Le nom d’utilisateur ne peut être modifié", - "users.form.firstname.label": "Prénom", - "users.form.lastname.label": "Nom", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@exemple.com", - "users.form.password.label": "Mot de passe", - "users.form.password.confirm.label": "Confirmer votre mot de passe", - "users.form.password.new.label": "Nouveau mot de passe", - "users.form.password.new.confirm.label": "Confirmer le nouveau mot de passe", - "users.form.password.new.help": "Laisser vide pour conserver votre mot de passe actuel", - "users.form.language.label": "Langue", - "users.form.role.label": "Rôle", - "users.form.options.headline": "Options du compte", - "users.form.options.message": "Envoyer un email", - "users.form.options.delete": "Supprimer le compte", - "users.form.avatar.headline": "Image du profil", - "users.form.avatar.upload": "Ajouter une image de profil", - "users.form.avatar.replace": "Remplacer l’image du profil", - "users.form.avatar.delete": "Supprimer l’image du profil", - "users.form.back": "Retour au compte", - "users.form.error.password.confirm": "Veuillez confirmer le mot de passe", - "users.form.error.update": "Le compte utilisateur ne peut être mis à jour", - "users.form.error.update.rights": "Vous n’êtes pas autorisé à mettre à jour cet utilisateur", - "users.form.error.create": "Le compte utilisateur n’a pu être créé", - "users.form.error.permissions.title": "Le répertoire des comptes n’est pas accessible en écriture", - "users.form.error.permissions.text": "Vérifiez que le répertoire “/site/accounts” existe et est accessible en écriture.", - "users.delete.headline": "Voulez-vous vraiment supprimer ce compte ?", - "users.delete.error": "Le compte utilisateur n’a pu être supprimé", - "users.delete.error.permission": "Vous n’êtes pas autorisé à supprimer des utilisateurs", - "users.delete.error.permission.single": "Vous n’êtes pas autorisé à supprimer cet utilisateur", - "users.delete.error.lastadmin": "Vous ne pouvez supprimer le dernier “admin”", - "users.avatar.drop": "Glisser ici un fichier image…", - "users.avatar.click": "…ou cliquer pour le transférer depuis votre ordinateur", - "users.avatar.error.type": "Vous pouvez uniquement transférer des fichiers JPG, PNG et GIF", - "users.avatar.error.folder.headline": "Le répertoire des avatars n’est pas accessible en écriture", - "users.avatar.error.folder.text": "Veuillez créer le répertoire /assets/avatars/ et en autoriser l'écriture pour pouvoir charger une image de profil.", - "users.avatar.error.permission": "Vous n’êtes pas autorisé à modifier l’avatar", - "users.avatar.delete.error": "L’image du profil n’a pu être supprimée", - "users.avatar.delete.error.permission": "Vous n’êtes pas autorisé à modifier l’avatar de cet utilisateur", - "users.avatar.delete.success": "L’image du profil a été supprimée", - "users.avatar.missing": "Cet utilisateur n’a pas d'avatar", - "users.error.missing": "Aucun compte utilisateur à ce nom n’a été trouvé", - "user.error.lastadmin": "Vous êtes le seul admin. Ceci ne peut être modifié.", - "form.error.missing": "Le formulaire n'a pu être trouvé", - "form.construct.error.invalid": "Méthode de construction de formulaire incorrecte", - "fields.required": "Requis", - "fields.date.label": "Date", - "fields.date.months": [ - "Janvier", - "Février", - "Mars", - "Avril", - "Mai", - "Juin", - "Juillet", - "Août", - "Septembre", - "Octobre", - "Novembre", - "Décembre" - ], - "fields.date.weekdays": [ - "Dimanche", - "Lundi", - "Mardi", - "Mercredi", - "Jeudi", - "Vendredi", - "Samedi" - ], - "fields.date.weekdays.short": [ - "Dim", - "Lun", - "Mar", - "Mer", - "Jeu", - "Ven", - "Sam" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@exemple.com", - "fields.number.label": "Numéro", - "fields.number.placeholder": "N°", - "fields.page.label": "Page", - "fields.page.placeholder": "chemin/vers/la/page", - "fields.password.label": "Mot de passe", - "fields.structure.add": "Ajouter", - "fields.structure.add.first": "Créer la première entrée", - "fields.structure.empty": "Aucune entrée pour le moment.", - "fields.structure.entry.error": "L’élément n’a pu être trouvé", - "fields.structure.cancel": "Annuler", - "fields.structure.save": "Valider", - "fields.structure.edit": "Modifier", - "fields.structure.delete": "Supprimer", - "fields.structure.delete.label": "Voulez-vous vraiment supprimer cette entrée ?", - "fields.tags.label": "Tags", - "fields.tel.label": "Téléphone", - "fields.textarea.buttons.bold.label": "Gras", - "fields.textarea.buttons.bold.text": "Texte en gras", - "fields.textarea.buttons.italic.label": "Italique", - "fields.textarea.buttons.italic.text": "Texte en italique", - "fields.textarea.buttons.link.label": "Lien", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Image", - "fields.textarea.buttons.file.label": "Fichier", - "fields.toggle.yes": "Oui", - "fields.toggle.no": "Non", - "fields.toggle.on": "Activé", - "fields.toggle.off": "Désactivé", - "fields.error.missing.controller": "Le fichier du contrôleur de champ est manquant", - "fields.error.missing.class": "La classe du contrôleur de champ est manquante", - "fields.error.route.invalid": "Routage du champ incorrect", - "fields.error.extended": "Le champ ne peut être étendu", - "editor.link.url.label": "Insérer une URL", - "editor.link.text.label": "Texte du lien", - "editor.link.text.help": "Le texte du lien est optionnel", - "editor.email.address.label": "Insérer une adresse email", - "editor.email.address.placeholder": "mail@exemple.com", - "editor.email.text.label": "Texte du lien", - "editor.email.text.help": "Le texte du lien est optionnel", - "editor.file.empty": "Cette page n’a aucun fichier attaché", - "editor.image.empty": "Cette page n’a aucune image attachée", - "autocomplete.method.error": "Méthode d’auto-complétion incorrecte", - "blueprints.error.default.missing": "Blueprint par défaut manquant", - "error": "Erreur", - "error.headline": "Erreur" -} \ No newline at end of file diff --git a/panel/app/translations/fr/package.json b/panel/app/translations/fr/package.json deleted file mode 100644 index 39ea6ab..0000000 --- a/panel/app/translations/fr/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Français", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/hu/core.json b/panel/app/translations/hu/core.json deleted file mode 100644 index 5924566..0000000 --- a/panel/app/translations/hu/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Mégsem", - "add": "Hozzáad", - "addit": "Hozzáad és szerkeszt", - "save": "Mentés", - "saved": "Mentve!", - "change": "Módosítás", - "delete": "Törlés", - "insert": "Beilleszt", - "ok": "Ok", - "routes.error.invalid": "Érvénytelen Panel URL", - "controller.error.invalid": "Érvénytelen vezérlő", - "controller.error.action": "Érvénytelen művelet", - "view.error.invalid": "Érvénytelen nézet:", - "options.show": "Beállítások mutatása", - "options.hide": "Beállítások elrejtése", - "installation": "Telepítés", - "installation.check.headline": "Kirby Panel telepítés", - "installation.check.text": "Kirby az alábbi problémával találkozott…", - "installation.check.retry": "Újból", - "installation.check.error": "Van néhány probléma!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts nem írható", - "installation.check.error.avatars": "/assets/avatars nem írható", - "installation.check.error.blueprints": "Kérlek hozd létre a site/blueprints mappát", - "installation.check.error.content": "A content mappa és az összes tartalmazott mappának és fájlnak írhatónak kell lennie.", - "installation.check.error.thumbs": "A thumbs mappának írhatónak kell lennie.", - "installation.signup.username.label": "Első fiók létrehozása", - "installation.signup.username.placeholder": "Felhasználónév", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@példa.hu", - "installation.signup.password.label": "Jelszó", - "installation.signup.language.label": "Nyelv", - "installation.signup.button": "Fiókod létrehozása", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Felhasználónév", - "login.password.label": "Jelszó", - "login.error": "Érvénytelen felhasználónév vagy jelszó", - "login.button": "Log in", - "login.log.error.permissions": "A bejelentkezési logfájl nem írható", - "logout": "Log out", - "topbar.error.class.definition": "Ez az osztály nincs definiálva: ", - "dashboard": "Vezérlőközpont", - "dashboard.index.pages.title": "Oldalak", - "dashboard.index.pages.edit": "Oldal szerkesztése", - "dashboard.index.pages.add": "Új oldal", - "dashboard.index.site.title": "Honlapod URL-je", - "dashboard.index.account.title": "Fiókod", - "dashboard.index.account.edit": "Szerkesztés", - "dashboard.index.metatags.title": "Metatagok", - "dashboard.index.metatags.edit": "Szerkesztés", - "dashboard.index.history.title": "Legutóbbi frissítések", - "dashboard.index.history.text": "Az általad legutóbb módosított oldalakat találod itt, hogy könnyebben megtaláld újból.", - "dashboard.index.license.title": "Kirby licenc", - "dashboard.index.license.text": "Úgy tűnik a Kirby egy publikus szerveren fut érvényes licensz nélkül.\n\nKérlek támogasd a Kirby-t és (link: {buy} text: vásárold meg a licenszet most)\n\nHa már rendelkezel licensz kulccsal, csak add hozzá a konfig fájlodhoz: (link: {docs} text: site/config/config.php)", - "metatags": "Metatagok", - "metatags.info": "Kirby infó", - "metatags.license": "Kirby licenc", - "metatags.version.toolkit": "Toolkit verzió", - "metatags.version.kirby": "Kirby verzió", - "metatags.version.panel": "Panel verzió", - "metatags.back": "Vissza a vezerlőközpontba", - "metatags.files": "A weboldalhoz tartozó fájlok", - "site.delete.error": "A weboldal nem törölhető", - "pages.show.settings": "Oldal beállítások", - "pages.show.preview": "Előnézet megnyitása", - "pages.show.template": "Sablon", - "pages.show.changeurl": "URL változtatása", - "pages.show.invisible": "Állapot: rejtett", - "pages.show.visible": "Állapot: látható", - "pages.show.changes.text": "Nem mentett változtatások vannak!", - "pages.show.changes.button": "Visszavonás", - "pages.show.delete": "Oldal törlése", - "pages.show.subpages.title": "Aloldalak", - "pages.show.subpages.edit": "Aloldal szerkesztése", - "pages.show.subpages.add": "Új aloldal", - "pages.show.subpages.empty": "Az oldalhoz nem tartoznak aloldalak", - "pages.show.files.title": "Fájlok", - "pages.show.files.edit": "Fájl szerkesztése", - "pages.show.files.add": "Új hozzáadása", - "pages.show.files.empty": "Az oldalhoz nem tartoznak fájlok", - "pages.show.error.permissions.title": "Az oldal nem írható", - "pages.show.error.permissions.text": "Kérlek ellenőrizd a content mappa és a fájlok jogosultságát.", - "pages.show.error.permissions.retry": "Újból", - "pages.show.error.notitle.title": "Ennek a blueprintnek nincs cím mezője", - "pages.show.error.notitle.text": "Töltsd ki a cím mezőt és próbálkozz újból", - "pages.show.error.notitle.retry": "Újból", - "pages.show.error.form": "Kérlek minden mezőt tölts ki", - "pages.add.title.label": "Új aloldal hozzáadása", - "pages.add.title.placeholder": "Cím", - "pages.add.url.label": "URL név", - "pages.add.url.enter": "(add meg a címet)", - "pages.add.url.close": "Bezár", - "pages.add.url.help": "Formátum: kisbetűs a-z, 0-9 és kötőjel", - "pages.add.template.label": "Sablon", - "pages.add.error.create": "Az oldal nem hozható létre", - "pages.add.error.title": "Hiányzik a cím", - "pages.add.error.template": "A sablon hiányzik", - "pages.add.error.max.headline": "Új oldal látrehozása nem engedélyezett", - "pages.add.error.max.text": "Elérted a maximálisan létrehozható aloldalak számát.", - "pages.url.uid.label": "URL név", - "pages.url.uid.label.option": "Létrehozás címből", - "pages.url.error.exists": "Van már egy másik oldal ezzel az URL-lel", - "pages.url.error.move": "Az URL-t nem sikerült megváltoztatni", - "pages.url.error.rights": "Ennek az oldalnak nem tudod megváltoztatni az URL-jét", - "pages.template.select.label": "Sablon", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Elhelyezkedés", - "pages.toggle.invisible": "rejtett", - "pages.toggle.publish": "Biztos megváltoztatod az oldal állapotát erre: **látható**?", - "pages.toggle.hide": "Biztos megváltoztatod az oldal állapotát erre: **rejtett**?", - "pages.toggle.error.error": "A hibaoldal állapota nem módosítható", - "pages.delete.headline": "Biztos vagy benne, hogy törlöd az oldalt?", - "pages.delete.error.home.headline": "A főoldal nem törölhető", - "pages.delete.error.home.text": "Te a főoldalt próbálod törölni. Ez nem lehetséges és beláthatatlan következményei lennének.", - "pages.delete.error.error.headline": "A hiba oldal nem törölhető", - "pages.delete.error.error.text": "Te a hiba oldalt próbálod törölni. Ez nem lehetséges és beláthatatlan következményei lennének.", - "pages.delete.error.children.headline": "Az oldal nem törölhető", - "pages.delete.error.children.text": "Az oldalnak vannak aloldalai és nem törölhető.Előbb töröld az összes aloldalt.", - "pages.delete.error.blocked.headline": "Az oldal nem törölhető", - "pages.delete.error.blocked.text": "Ez az oldal zárolt és nem törölhető.", - "pages.search.help": "Keresés URL szerint.Navigálhatsz a fel és le nyilakkal és az enter-rel ugorhatsz a kiválasztott oldalhoz.", - "pages.search.noresults": "Amire kerestél, nincs találat. Kérlek próbáld meg egy másik URL-lel.", - "pages.error.missing": "Az oldal nem található", - "subpages": "Aloldalak", - "subpages.index.headline": "Aloldalak kezelése ennél:", - "subpages.index.back": "Vissza", - "subpages.index.add": "Új aloldal", - "subpages.index.add.first.text": "Ennek az oldalnak még nincs aloldala", - "subpages.index.add.first.button": "Az első aloldal hozzáadása", - "subpages.index.visible": "Látható aloldalak", - "subpages.index.visible.help": "Fogd meg jobbról az oldalt és rendezd vagy tedd láthatóvá.", - "subpages.index.invisible": "Láthatatlan aloldalak", - "subpages.index.invisible.help": "Fogd meg balról az oldalt és rendezd vagy tedd láthatatlanná.", - "subpages.add.error": "Ennek az oldalnak nem lehetnek aloldalai", - "subpages.add.error.more": "Ennek az oldalnak nem lehet több aloldala", - "subpages.error.missing": "Az oldal nem található", - "files": "Fájlok", - "files.index.headline": "Fájlkezelés ennél:", - "files.index.back": "Vissza", - "files.index.upload": "Új fájl feltöltése", - "files.index.upload.first.text": "Ennél az oldalnál még nincs fájl feltöltve", - "files.index.upload.first.button": "Töltsd fel az első fájlt", - "files.index.edit": "Szerkeszt", - "files.index.delete": "Töröl", - "files.index.error.disabled": "Ehhez az oldalhoz nem tartozhatnak fájlok", - "files.add.error.max": "Ehhez az oldalhoz nem tölthető fel a jelenleginél több fájl", - "files.add.error.extension.missing": "Kiterjesztés nélküli fájl nem tölthető fel", - "files.add.error.extension.forbidden": "Tiltott kiterjesztésű fájl", - "files.add.error.mime.forbidden": "Tiltott mime-típus", - "files.add.error.htaccess": "A htaccess fájlt nem lehet feltölteni", - "files.add.error.invisible": "Láthatatlan fájlok nem tölthetők fel", - "files.add.blueprint.type.error": "Az oldal az alábbiakat engedélyezi:", - "files.add.blueprint.size.error": "Az oldal által engedélyezett legnagyobb fájlméret", - "files.show.name.label": "Fájlnév", - "files.show.info.label": "Típus / fájlméret / méretek", - "files.show.link.label": "Publikus link", - "files.show.open": "Fájl megtekintése/letöltése", - "files.show.back": "Vissza", - "files.show.replace": "Cserél", - "files.show.delete": "Töröl", - "files.show.error.rename": "A fájl nem nevezhető át", - "files.show.error.form": "Kérlek minden mezőt tölts ki", - "files.upload.drop": "Dobd a fájlokat ide…", - "files.upload.click": "…vagy kattints ide a feltöltéshez", - "files.replace.drop": "Dobd a fájlt ide…", - "files.replace.click": "…vagy kattints ide a cseréhez", - "files.replace.error.type": "A feltöltött fájlnak azonos a típusa", - "files.delete.headline": "Biztos törölni akarod ezt a fájlt?", - "files.error.missing.page": "Az oldal nem található", - "files.error.missing.file": "A fájl nem található", - "users": "Felhasználók", - "users.index.headline": "Összes felhasználó", - "users.index.add": "Új felhasználó", - "users.index.edit": "szerkeszt", - "users.index.delete": "töröl", - "users.form.username.label": "Felhasználónév", - "users.form.username.placeholder": "Felhasználóneved", - "users.form.username.help": "Engedélyezett karakterek: kisbetűs a-z, 0-9 és kötőjel", - "users.form.username.readonly": "A felhasználónév nem változtatható meg", - "users.form.firstname.label": "Keresztnév", - "users.form.lastname.label": "Vezetéknév", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@pálda.hu", - "users.form.password.label": "Jelszó", - "users.form.password.confirm.label": "Jelszó megerősítése", - "users.form.password.new.label": "Új jelszó", - "users.form.password.new.confirm.label": "Az új jelszó megerősítése", - "users.form.password.new.help": "Hagyd üresen, ha a jelenlegi jelszót meg akarod tartani", - "users.form.language.label": "Nyelv", - "users.form.role.label": "Role", - "users.form.options.headline": "Fiók beállítások", - "users.form.options.message": "Email küldése", - "users.form.options.delete": "Fiók törlése", - "users.form.avatar.headline": "Profil kép", - "users.form.avatar.upload": "Profil kép feltöltése", - "users.form.avatar.replace": "Profil kép cseréje", - "users.form.avatar.delete": "Profil kép törlése", - "users.form.back": "Vissza a felhasználókhoz", - "users.form.error.password.confirm": "Kérlek erősítsd meg a jelszót", - "users.form.error.update": "A felhasználó nem frissíthető", - "users.form.error.update.rights": "Nincs jogosultságod a felhasználó módosításához", - "users.form.error.create": "A felhasználó nem hozható létre", - "users.form.error.permissions.title": "A account mappa nem írható", - "users.form.error.permissions.text": "Kérlek ellenőrizd, hogy a /site/accounts mappa létezik és írható.", - "users.delete.headline": "Biztos törlöd ezt a felhasználót?", - "users.delete.error": "A felhasználó nem törölhető", - "users.delete.error.permission": "Nincs jogosultságod felhasználók törléséhez", - "users.delete.error.permission.single": "Nincs jogosultságod törölni ezt a felhasználót", - "users.delete.error.lastadmin": "Nem törölheted az egyetlen adminisztrátort", - "users.avatar.drop": "Dobd a profil képet ide…", - "users.avatar.click": "…vagy kattints ide a feltöltéshez", - "users.avatar.error.type": "Csak JPG, PNG és GIF fájl tölthető fel", - "users.avatar.error.folder.headline": "Az avatar mappa nem írható", - "users.avatar.error.folder.text": "Kérlek hozd létre a /assets/avatars mappát és tedd írhatóvá a profil képek feltöltéséhez.", - "users.avatar.error.permission": "Nincs jogosultságod megváltoztatni a profilképet", - "users.avatar.delete.error": "A profil kép nem törölhető", - "users.avatar.delete.error.permission": "Nincs jogosultságod megváloztatni ennek a felhasználónak a profilképét", - "users.avatar.delete.success": "A profil kép törölve", - "users.avatar.missing": "Ennek a felhasználónak nincs profilképe", - "users.error.missing": "A felhasználó nem található", - "user.error.lastadmin": "Te vagy az egyetlen adminisztrátor. Ez a beállítás nem módosítható.", - "form.error.missing": "Az űrlap nem található", - "form.construct.error.invalid": "Érvénytelen űrlapfelépítés", - "fields.required": "Kötelező", - "fields.date.label": "Dátum", - "fields.date.months": [ - "január", - "február", - "március", - "április", - "május", - "június", - "július", - "augusztus", - "szeptember", - "október", - "november", - "december" - ], - "fields.date.weekdays": [ - "vasárnap", - "hétfő", - "kedd", - "szerda", - "csütörtök", - "péntek", - "szombat" - ], - "fields.date.weekdays.short": [ - "va", - "hé", - "ke", - "sze", - "csü", - "pé", - "szo" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@példa.hu", - "fields.number.label": "Szám", - "fields.number.placeholder": "#", - "fields.page.label": "Oldal", - "fields.page.placeholder": "az/oldal/elérése", - "fields.password.label": "Jelszó", - "fields.structure.add": "Új", - "fields.structure.add.first": "Első bejegyzés hozzáadása", - "fields.structure.empty": "Nincs még bejegyzés", - "fields.structure.entry.error": "Az elem nem található", - "fields.structure.cancel": "Mégse", - "fields.structure.save": "Mentés", - "fields.structure.edit": "Szerkeszt", - "fields.structure.delete": "Törlés", - "fields.structure.delete.label": "Biztos törölni szeretnéd ezt a bejegyzést?", - "fields.tags.label": "Címkék", - "fields.tel.label": "Telefon", - "fields.textarea.buttons.bold.label": "Félkövér szöveg", - "fields.textarea.buttons.bold.text": "Félkövér szöveg", - "fields.textarea.buttons.italic.label": "Dölt szöveg", - "fields.textarea.buttons.italic.text": "Dölt szöveg", - "fields.textarea.buttons.link.label": "Link", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Kép", - "fields.textarea.buttons.file.label": "Fájl", - "fields.toggle.yes": "Igen", - "fields.toggle.no": "Nem", - "fields.toggle.on": "Be", - "fields.toggle.off": "Ki", - "fields.error.missing.controller": "A mezőszabályozó fájl nincs meg", - "fields.error.missing.class": "A mezőszabályozó osztály hiányzik", - "fields.error.route.invalid": "A mező elérési útvonala érvénytelen", - "fields.error.extended": "Ez a mező nem terjeszthető ki", - "editor.link.url.label": "URL beillesztése", - "editor.link.text.label": "Link szöveg", - "editor.link.text.help": "A link szövege nem kötelező", - "editor.email.address.label": "Email cím beillesztése", - "editor.email.address.placeholder": "mail@példa.hu", - "editor.email.text.label": "Link szöveg", - "editor.email.text.help": "A link szövege nem kötelező", - "editor.file.empty": "Az oldalnak nincsenek fájljai", - "editor.image.empty": "Az oldalnak nincsenek képei", - "autocomplete.method.error": "Érvénytelen auto-kiegészítés metódus", - "blueprints.error.default.missing": "Hiányzó alapértelmezett blueprint", - "error": "Hiba", - "error.headline": "Hiba" -} \ No newline at end of file diff --git a/panel/app/translations/hu/package.json b/panel/app/translations/hu/package.json deleted file mode 100644 index d99d05e..0000000 --- a/panel/app/translations/hu/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Hungarian", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/id/core.json b/panel/app/translations/id/core.json deleted file mode 100644 index 1a87bc5..0000000 --- a/panel/app/translations/id/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Batal", - "add": "Tambah", - "addit": "Tambah & Sunting", - "save": "Simpan", - "saved": "Telah disimpan!", - "change": "Change", - "delete": "Hapus", - "insert": "Sisip", - "ok": "Ok", - "routes.error.invalid": "Invalid Panel URL", - "controller.error.invalid": "Invalid controller", - "controller.error.action": "Invalid action", - "view.error.invalid": "Invalid view:", - "options.show": "Tunjukan pilihan", - "options.hide": "Sembunyikan pilihan", - "installation": "Instalasi", - "installation.check.headline": "Instalasi Kirby Panel", - "installation.check.text": "Kirby menemukan beberapa masalah selagi menginstalasi…", - "installation.check.retry": "Coba lagi", - "installation.check.error": "Ada beberapa masalah!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts tidak bisa diakses", - "installation.check.error.avatars": "/assets/avatars tidak bisa diakses", - "installation.check.error.blueprints": "Tolong tambahkan folder /site/blueprints", - "installation.check.error.content": "The content folder and all contained files and folders must be writable.", - "installation.check.error.thumbs": "The thumbs folder must be writable.", - "installation.signup.username.label": "Buatlah akun pertama anda", - "installation.signup.username.placeholder": "Nama pengguna", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "email@contohemail.com", - "installation.signup.password.label": "Kata sandi", - "installation.signup.language.label": "Bahasa", - "installation.signup.button": "Buatlah akun anda", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Nama pengguna", - "login.password.label": "Kata sandi", - "login.error": "Kata sandi atau username anda tidak terdaftar", - "login.button": "Log in", - "login.log.error.permissions": "Berkas log masuk tidak bisa disunting", - "logout": "Log out", - "topbar.error.class.definition": "Missing topbar definition for class:", - "dashboard": "Dashboard", - "dashboard.index.pages.title": "Halaman", - "dashboard.index.pages.edit": "Sunting", - "dashboard.index.pages.add": "Tambah", - "dashboard.index.site.title": "URL situs anda", - "dashboard.index.account.title": "Akun anda", - "dashboard.index.account.edit": "Sunting", - "dashboard.index.metatags.title": "Variabel situs", - "dashboard.index.metatags.edit": "Sunting", - "dashboard.index.history.title": "Update terakhir anda", - "dashboard.index.history.text": "Halaman terakhir yang anda ubah akan ditampilkan di sini supaya mudah untuk menemukannya lagi.", - "dashboard.index.license.title": "Lisensi Kirby", - "dashboard.index.license.text": "It seems you are running Kirby on a public server without a valid license!\n\nPlease, support Kirby and (link: {buy} text: buy a license now)\n\nIf you already have a license key, just add it to your config file: (link: {docs} text: site/config/config.php)", - "metatags": "Variabel situs", - "metatags.info": "Info Kirby", - "metatags.license": "Lisensi Kirby", - "metatags.version.toolkit": "Versi Toolkit", - "metatags.version.kirby": "Versi Kirby", - "metatags.version.panel": "Versi Panel", - "metatags.back": "Kembali ke dashboard", - "metatags.files": "Berkas situs", - "site.delete.error": "Situs tidak bisa dihapus", - "pages.show.settings": "Pengaturan halaman", - "pages.show.preview": "Buka pratinjau", - "pages.show.template": "Template", - "pages.show.changeurl": "Ganti URL", - "pages.show.invisible": "Status: tak terlihat", - "pages.show.visible": "Status: terlihat", - "pages.show.changes.text": "You have unsaved changes!", - "pages.show.changes.button": "Discard", - "pages.show.delete": "Hapus halaman ini", - "pages.show.subpages.title": "Halaman", - "pages.show.subpages.edit": "Sunting", - "pages.show.subpages.add": "Tambah", - "pages.show.subpages.empty": "Halaman ini tidak memiliki sub-halaman", - "pages.show.files.title": "Berkas", - "pages.show.files.edit": "Sunting", - "pages.show.files.add": "Tambah", - "pages.show.files.empty": "Halaman ini tidak memiliki berkas", - "pages.show.error.permissions.title": "Halaman ini tidak bisa disunting", - "pages.show.error.permissions.text": "Tolong periksa hak akses untuk file dan folder.", - "pages.show.error.permissions.retry": "Coba lagi", - "pages.show.error.notitle.title": "Blueprint ini tidak memiliki bidang untuk 'title'", - "pages.show.error.notitle.text": "Tolong tambahkan bidang untuk 'title' dan coba lagi", - "pages.show.error.notitle.retry": "Coba lagi", - "pages.show.error.form": "Tolong isi semua bidang dengan benar", - "pages.add.title.label": "Tambah halaman baru", - "pages.add.title.placeholder": "Judul", - "pages.add.url.label": "URL-lampiran", - "pages.add.url.enter": "(masukkan judul anda)", - "pages.add.url.close": "Tutup", - "pages.add.url.help": "Format: huruf kecil a-z, 0-9 dan regular dashes", - "pages.add.template.label": "Template", - "pages.add.error.create": "Halaman tidak dapat dibuat", - "pages.add.error.title": "Judul tidak ditemukan", - "pages.add.error.template": "Template tidak ditemukan", - "pages.add.error.max.headline": "Halaman baru tidak diperbolehkan", - "pages.add.error.max.text": "Jumlah maksimum sub-halaman telah tercapai.", - "pages.url.uid.label": "URL-lampiran", - "pages.url.uid.label.option": "Buat dari judul", - "pages.url.error.exists": "Halaman dengan lampiran yang sama sudah ada", - "pages.url.error.move": "Lampiran tidak bisa diubah", - "pages.url.error.rights": "You cannot change the URL of this page", - "pages.template.select.label": "Template", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Posisi", - "pages.toggle.invisible": "Status: tak terlihat", - "pages.toggle.publish": "Apakah anda benar-benar mau mengganti status halaman ini menjadi **visible?**", - "pages.toggle.hide": "Do you really want to change the status of this page to **invisible?**", - "pages.toggle.error.error": "The status of the error page cannot be changed", - "pages.delete.headline": "Apakah anda benar-benar mau menghapus halaman ini?", - "pages.delete.error.home.headline": "Beranda tidak bisa dihapus", - "pages.delete.error.home.text": "Anda sedang mencoba menghapus beranda. Hal ini tidak mungkin dan akan menyebabkan efek yang tidak diinginkan.", - "pages.delete.error.error.headline": "Halaman error tidak bisa dihapus", - "pages.delete.error.error.text": "Anda sedang mencoba menghapus halaman error. Hal ini tidak mungkin dan akan menyebabkan efek yang tidak diinginkan.", - "pages.delete.error.children.headline": "Halaman ini tidak bisa dihapus", - "pages.delete.error.children.text": "Halaman ini memiliki sub-halaman dan tidak bisa dihapus. Tolong hapus sub-halaman terdahulu.", - "pages.delete.error.blocked.headline": "Halaman ini tidak bisa dihapus", - "pages.delete.error.blocked.text": "Halaman ini dikunci dan tidak bisa dihapus.", - "pages.search.help": "Cari halaman dengan URL. Navigasi hasil pencarian dengan tombol atas dan bawah kemudian tekan tombol enter untuk melompat ke halaman yang dipilih.", - "pages.search.noresults": "Tidak ada hasil pencarian untuk permintaan anda. Silakan coba lagi dengan URL yang berbeda.", - "pages.error.missing": "Halaman yang anda cari tidak bisa ditemukan.", - "subpages": "Halaman", - "subpages.index.headline": "Halaman yang ada didalam", - "subpages.index.back": "Kembali", - "subpages.index.add": "Tambah halaman baru", - "subpages.index.add.first.text": "Halaman ini belum memiliki sub-halaman", - "subpages.index.add.first.button": "Tambah halaman pertama", - "subpages.index.visible": "Halaman terlihat", - "subpages.index.visible.help": "Seretlah halaman tersembunyi ke sini untuk menyortir atau membuat halaman terlihat", - "subpages.index.invisible": "Halaman tersembunyi", - "subpages.index.invisible.help": "Seretlah halaman terlihat ke sini untuk menyortir atau membuat halaman tersembunyi.", - "subpages.add.error": "This page is not allowed to have subpages", - "subpages.add.error.more": "This page cannot have any more subpages", - "subpages.error.missing": "Halaman tidak bisa ditemukan", - "files": "Berkas", - "files.index.headline": "Berkas untuk", - "files.index.back": "Kembali", - "files.index.upload": "Unggah berkas baru", - "files.index.upload.first.text": "Halaman ini belum memiliki berkas", - "files.index.upload.first.button": "Unggah berkas pertama", - "files.index.edit": "Sunting", - "files.index.delete": "Hapus", - "files.index.error.disabled": "The page is not allowed to have any files", - "files.add.error.max": "The maximum number of files for the current page has been reached.", - "files.add.error.extension.missing": "You cannot upload files without extension", - "files.add.error.extension.forbidden": "Forbidden file extension", - "files.add.error.mime.forbidden": "Forbidden mime type", - "files.add.error.htaccess": "htaccess files cannot be uploaded", - "files.add.error.invisible": "Invisible files cannot be uploaded", - "files.add.blueprint.type.error": "Page only allows:", - "files.add.blueprint.size.error": "Page only allows file size of", - "files.show.name.label": "Nama berkas", - "files.show.info.label": "Tipe / Ukuran / Dimensi", - "files.show.link.label": "Link publik", - "files.show.open": "Tampilkan atau download file", - "files.show.back": "Kembali", - "files.show.replace": "Ganti", - "files.show.delete": "Hapus", - "files.show.error.rename": "Nama berkas tidak bisa diganti", - "files.show.error.form": "Tolong isi semua bidang dengan benar", - "files.upload.drop": "Drop file disini…", - "files.upload.click": "…atau tekan untuk meng-upload", - "files.replace.drop": "Drop file disini…", - "files.replace.click": "…atau tekan untuk mengganti", - "files.replace.error.type": "Berkas yang diunggah harus memiliki tipe yang sama.", - "files.delete.headline": "Apakah anda benar-benar mau menghapus file ini?", - "files.error.missing.page": "Halaman tidak bisa ditemukan", - "files.error.missing.file": "File tidak bisa ditemukan", - "users": "Pengguna", - "users.index.headline": "Semua pengguna", - "users.index.add": "Tambah pengguna baru", - "users.index.edit": "Sunting", - "users.index.delete": "Hapus", - "users.form.username.label": "Nama pengguna", - "users.form.username.placeholder": "Nama pengguna anda", - "users.form.username.help": "Karakter yang diperbolehkan: huruf kecil a-z, 0-9 dan strip", - "users.form.username.readonly": "Nama pengguna tidak bisa diganti", - "users.form.firstname.label": "Nama depan", - "users.form.lastname.label": "Nama keluarga", - "users.form.email.label": "Email", - "users.form.email.placeholder": "email@contohemail.com", - "users.form.password.label": "Kata sandi", - "users.form.password.confirm.label": "Konfirmasi kata sandi", - "users.form.password.new.label": "Kata sandi baru", - "users.form.password.new.confirm.label": "Konfirmasi kata sandi yang baru", - "users.form.password.new.help": "Biarkan kosong untuk menyimpan kata sandi yang sekarang", - "users.form.language.label": "Bahasa", - "users.form.role.label": "Peran", - "users.form.options.headline": "Opsi akun", - "users.form.options.message": "Kirim email", - "users.form.options.delete": "Hapus akun", - "users.form.avatar.headline": "Gambar profil", - "users.form.avatar.upload": "Unggah gambar profil", - "users.form.avatar.replace": "Ganti gambar profil", - "users.form.avatar.delete": "Hapus gambar profil", - "users.form.back": "Kembali ke pengguna", - "users.form.error.password.confirm": "Tolong konfirmasi kata sandi", - "users.form.error.update": "Pengguna tidak bisa di-update", - "users.form.error.update.rights": "You are not allowed to update this user", - "users.form.error.create": "Pengguna tidak bisa dibuat", - "users.form.error.permissions.title": "Folder 'account' tidak bisa diakses", - "users.form.error.permissions.text": "Tolong pastikan bahwa /site/accounts ada dan bisa diakses.", - "users.delete.headline": "Apakah anda benar-benar mau menghapus pengguna ini?", - "users.delete.error": "Pengguna ini tidak bisa dihapus", - "users.delete.error.permission": "You are not allowed to delete users", - "users.delete.error.permission.single": "You are not allowed to delete this user", - "users.delete.error.lastadmin": "You cannot delete the last admin", - "users.avatar.drop": "Drop profil foto disini…", - "users.avatar.click": "…or atau tekan untuk meng-upload", - "users.avatar.error.type": "Anda hanya bisa meng-upload file dengan tipe JPG, PNG dan GIF", - "users.avatar.error.folder.headline": "Folder avatar tidak bisa diakses", - "users.avatar.error.folder.text": "Tolong buat folder /assets/avatars dan berikan hak akses untuk mengupload profil foto.", - "users.avatar.error.permission": "You are not allowed to change the avatar", - "users.avatar.delete.error": "Profil fotonya tidak bisa dihapus", - "users.avatar.delete.error.permission": "You are not allowed to delete the avatar of this user", - "users.avatar.delete.success": "Profil fotonya telah dihapus", - "users.avatar.missing": "This user has no avatar", - "users.error.missing": "Pengguna tidak bisa ditemukan", - "user.error.lastadmin": "You are the only admin. This cannot be changed.", - "form.error.missing": "The form cannot be found", - "form.construct.error.invalid": "Invalid form construction method", - "fields.required": "Diperlukan", - "fields.date.label": "Tanggal", - "fields.date.months": [ - "Januari", - "Februari", - "Maret", - "April", - "Mei", - "Juni", - "Juli", - "Agustus", - "September", - "Oktober", - "November", - "Desember" - ], - "fields.date.weekdays": [ - "Minggu", - "Senin", - "Selasa", - "Rabu", - "Kamis", - "Jum'at", - "Sabtu" - ], - "fields.date.weekdays.short": [ - "Min", - "Sen", - "Sel", - "Rab", - "Kam", - "Jum", - "Sab" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@example.com", - "fields.number.label": "Nomor", - "fields.number.placeholder": "#", - "fields.page.label": "Halaman", - "fields.page.placeholder": "path/ke/halaman", - "fields.password.label": "Kata sandi", - "fields.structure.add": "Tambah", - "fields.structure.add.first": "Tambahkan entri pertama", - "fields.structure.empty": "Belum ada entri", - "fields.structure.entry.error": "The item could not be found", - "fields.structure.cancel": "Batal", - "fields.structure.save": "Simpan", - "fields.structure.edit": "Sunting", - "fields.structure.delete": "Hapus", - "fields.structure.delete.label": "Do you really want to delete this entry?", - "fields.tags.label": "Tags", - "fields.tel.label": "Telepon", - "fields.textarea.buttons.bold.label": "Teks tebal", - "fields.textarea.buttons.bold.text": "Teks tebal", - "fields.textarea.buttons.italic.label": "Teks miring", - "fields.textarea.buttons.italic.text": "Teks miring", - "fields.textarea.buttons.link.label": "Link", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Gambar", - "fields.textarea.buttons.file.label": "Berkas", - "fields.toggle.yes": "Ya", - "fields.toggle.no": "Tidak", - "fields.toggle.on": "On", - "fields.toggle.off": "Off", - "fields.error.missing.controller": "The field controller file is missing", - "fields.error.missing.class": "The field controller class is missing", - "fields.error.route.invalid": "Invalid field route", - "fields.error.extended": "The field cannot be extended", - "editor.link.url.label": "Masukkan URL", - "editor.link.text.label": "Link text", - "editor.link.text.help": "Link text opsional", - "editor.email.address.label": "Masukkan alamat email", - "editor.email.address.placeholder": "email@contohemail.com", - "editor.email.text.label": "Link text", - "editor.email.text.help": "Link text opsional", - "editor.file.empty": "Halaman ini tidak memiliki file", - "editor.image.empty": "Halaman ini tidak memiliki gambar", - "autocomplete.method.error": "Invalid autocomplete method", - "blueprints.error.default.missing": "Missing default blueprint", - "error": "Error", - "error.headline": "Error" -} \ No newline at end of file diff --git a/panel/app/translations/id/package.json b/panel/app/translations/id/package.json deleted file mode 100644 index 967ccfc..0000000 --- a/panel/app/translations/id/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Bahasa Indonesia", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/it/core.json b/panel/app/translations/it/core.json deleted file mode 100644 index 6857e61..0000000 --- a/panel/app/translations/it/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Annulla", - "add": "Aggiungi", - "addit": "Aggiungi e Modifica ", - "save": "Salva", - "saved": "Salvato!", - "change": "Cambia", - "delete": "Elimina", - "insert": "Inserisci", - "ok": "Ok", - "routes.error.invalid": "URL del Panel non valido", - "controller.error.invalid": "Controller non valido", - "controller.error.action": "Azione non valida", - "view.error.invalid": "Vista non valida", - "options.show": "Mostra opzioni", - "options.hide": "Nascondi opzioni", - "installation": "Installazione", - "installation.check.headline": "Installazione di Kirby Panel", - "installation.check.text": "Kirby ha riscontrato i seguenti problemi durante l'installazione…", - "installation.check.retry": "Riprova", - "installation.check.error": "Sono stati riscontrati dei problemi!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts non dispone dei permessi di scrittura", - "installation.check.error.avatars": "/assets/avatars non dispone dei permessi di scrittura", - "installation.check.error.blueprints": "Aggiungi la cartella /site/blueprints", - "installation.check.error.content": "La cartella /content e tutti i file e le cartelle in essa contenuti devono disporre dei permessi di scrittura.", - "installation.check.error.thumbs": "La cartella /thumbs deve disporre dei permessi di scrittura.", - "installation.signup.username.label": "Crea il tuo primo profilo", - "installation.signup.username.placeholder": "Nome utente", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@esempio.com", - "installation.signup.password.label": "Password", - "installation.signup.language.label": "Lingua", - "installation.signup.button": "Crea un nuovo profilo", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Username", - "login.password.label": "Password", - "login.error": "Username o password non validi", - "login.button": "Log in", - "login.log.error.permissions": "Il file di log degli accessi non è scrivibile.", - "logout": "Log out", - "topbar.error.class.definition": "Manca la definizione topbar per la classe:", - "dashboard": "Dashboard", - "dashboard.index.pages.title": "Pagine", - "dashboard.index.pages.edit": "Modifica", - "dashboard.index.pages.add": "Aggiungi", - "dashboard.index.site.title": "URL del sito", - "dashboard.index.account.title": "Il tuo account", - "dashboard.index.account.edit": "Modifica", - "dashboard.index.metatags.title": "Informazioni sul sito", - "dashboard.index.metatags.edit": "Modifica", - "dashboard.index.history.title": "Le tue ultime modifiche", - "dashboard.index.history.text": "Le ultime pagine modificate verranno mostrate qui per permetterti di ritrovarle più facilmente.", - "dashboard.index.license.title": "Licenza di Kirby", - "dashboard.index.license.text": "Sembra che stai usando Kirby su un server pubblico senza una licenza valida!\n\nPer favore, supporta Kirby (link: {buy} text: comprando subito una licenza)\n\nSe già possiedi una licenza, basta aggiungerla al tuo file di configurazione: (link: {docs} text: site/config/config.php)", - "metatags": "Informazioni sul sito", - "metatags.info": "Kirby info", - "metatags.license": "Licenza di Kirby", - "metatags.version.toolkit": "Versione del Toolkit", - "metatags.version.kirby": "Versione di Kirby", - "metatags.version.panel": "Versione del Panel", - "metatags.back": "Torna alla dashboard", - "metatags.files": "File del sito", - "site.delete.error": "Il sito non può essere rimosso", - "pages.show.settings": "Impostazioni della pagina", - "pages.show.preview": "Anteprima", - "pages.show.template": "Template", - "pages.show.changeurl": "Modifica URL", - "pages.show.invisible": "Status: invisibile", - "pages.show.visible": "Status: visibile", - "pages.show.changes.text": "Ci sono modifiche non salvate!", - "pages.show.changes.button": "Abbandona", - "pages.show.delete": "Elimina questa pagina", - "pages.show.subpages.title": "Pagine", - "pages.show.subpages.edit": "Modifica", - "pages.show.subpages.add": "Aggiungi", - "pages.show.subpages.empty": "Questa pagina non ha sottopagine", - "pages.show.files.title": "File", - "pages.show.files.edit": "Modifica", - "pages.show.files.add": "Aggiungi", - "pages.show.files.empty": "Questa pagina non ha file", - "pages.show.error.permissions.title": "Questa pagina non dispone dei permessi di scrittura", - "pages.show.error.permissions.text": "Verifica i permessi della cartella /content e di tutto il suo contenuto.", - "pages.show.error.permissions.retry": "Riprova", - "pages.show.error.notitle.title": "Nel modello non è previsto un campo per il titolo", - "pages.show.error.notitle.text": "Aggiungi un campo titolo e riprova", - "pages.show.error.notitle.retry": "Riprova", - "pages.show.error.form": "Compila tutti i campi correttamente", - "pages.add.title.label": "Aggiungi una nuova pagina", - "pages.add.title.placeholder": "Titolo", - "pages.add.url.label": "URL", - "pages.add.url.enter": "(inserisci un titolo)", - "pages.add.url.close": "Chiudi", - "pages.add.url.help": "Formato: minuscole a-z, 0-9 e trattini", - "pages.add.template.label": "Template", - "pages.add.error.create": "La pagina non può essere creata", - "pages.add.error.title": "Il titolo è vuoto", - "pages.add.error.template": "Il template non è stato trovato", - "pages.add.error.max.headline": "Non è consentita l'aggiunta di nuove pagine", - "pages.add.error.max.text": "Il numero massimo di sottopagine per questa pagina è stato raggiunto.", - "pages.url.uid.label": "URL", - "pages.url.uid.label.option": "Crea in base al titolo", - "pages.url.error.exists": "Esiste già una pagina con lo stesso URL", - "pages.url.error.move": "L'URL non può essere modificato", - "pages.url.error.rights": "Non puoi cambiare l'URL di questa pagina", - "pages.template.select.label": "Template", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Posizione", - "pages.toggle.invisible": "invisibile", - "pages.toggle.publish": "Vuoi veramente cambiare lo status della pagina a **visibile?**", - "pages.toggle.hide": "Vuoi veramente cambiare lo status della pagina a **invisibile?**", - "pages.toggle.error.error": "Lo status della pagina d'errore non può essere cambiato", - "pages.delete.headline": "Sei sicuro di voler eliminare questa pagina?", - "pages.delete.error.home.headline": "La pagina home non può essere eliminata", - "pages.delete.error.home.text": "Stai cercando di eliminare la pagina home. Quest'operazione non è possibile e potrebbe causare effetti indesiderati.", - "pages.delete.error.error.headline": "La pagina di errore non può essere eliminata", - "pages.delete.error.error.text": "Stai cercando di eliminare la pagina di errore. Quest'operazione non è possibile e potrebbe causare effetti indesiderati.", - "pages.delete.error.children.headline": "La pagina non può essere eliminata", - "pages.delete.error.children.text": "Questa pagina ha delle sottopagine e quindi non può essere eliminata. Elimina prima tutte le sottopagine.", - "pages.delete.error.blocked.headline": "La pagina non può essere eliminata", - "pages.delete.error.blocked.text": "Questa pagina è bloccata e non può essere eliminata.", - "pages.search.help": "Cerca le pagine indicando l'URL. Naviga tra i risultati della ricerca con i tasti freccia e premi invio per visualizzare la pagina selezionata.", - "pages.search.noresults": "La tua ricerca non ha dato risultati. Prova di nuovo con un URL differente.", - "pages.error.missing": "La pagina non è stata trovata", - "subpages": "Pagine", - "subpages.index.headline": "Pagine in", - "subpages.index.back": "Indietro", - "subpages.index.add": "Aggiungi nuova pagina", - "subpages.index.add.first.text": "Questa pagina non ha ancora sottopagine", - "subpages.index.add.first.button": "Aggiungi la prima pagina", - "subpages.index.visible": "Pagine visibili", - "subpages.index.visible.help": "Trascina qui una pagina nascosta per riordinarla/renderla visibile.", - "subpages.index.invisible": "Pagine nascoste", - "subpages.index.invisible.help": "Trascina qui una pagina visibile per nasconderla.", - "subpages.add.error": "A questa pagina non è consentito avere altre sottopagine", - "subpages.add.error.more": "Questa pagina non può avere altre sottopagine", - "subpages.error.missing": "La pagina non è stata trovata", - "files": "Files", - "files.index.headline": "Files associati a", - "files.index.back": "Indietro", - "files.index.upload": "Carica un nuovo file", - "files.index.upload.first.text": "Questa pagina non contiene file", - "files.index.upload.first.button": "Carica il primo file", - "files.index.edit": "Modifica", - "files.index.delete": "Elimina", - "files.index.error.disabled": "Alla pagina non è consentito avere nessun file", - "files.add.error.max": "Il numero massimo di file per l'utente corrente è stato raggiunto.", - "files.add.error.extension.missing": "Non puoi caricare file senza estensione", - "files.add.error.extension.forbidden": "Estensione non consentita", - "files.add.error.mime.forbidden": "Mime type non consentito", - "files.add.error.htaccess": "Il file htaccess non può essere caricato", - "files.add.error.invisible": "I file invisibili non possono essere caricati", - "files.add.blueprint.type.error": "La pagina consente solo:", - "files.add.blueprint.size.error": "La pagina permette una dimensione del file di", - "files.show.name.label": "Nome del file", - "files.show.info.label": "Tipo / Dimensione / Misure", - "files.show.link.label": "Link pubblico", - "files.show.open": "Mostra/scarica file", - "files.show.back": "Indietro", - "files.show.replace": "Sostituisci", - "files.show.delete": "Elimina", - "files.show.error.rename": "Non è stato possibile rinominare il file", - "files.show.error.form": "Compila tutti i campi correttamente", - "files.upload.drop": "Trascina un file qui…", - "files.upload.click": "…o clicca per caricarne uno", - "files.replace.drop": "Trascina un file qui…", - "files.replace.click": "…o clicca per caricarne uno", - "files.replace.error.type": "Il file caricato deve avere lo stesso formato", - "files.delete.headline": "Sei sicuro di voler eliminare questo file?", - "files.error.missing.page": "La pagina non è stata trovata", - "files.error.missing.file": "Il file non è stato trovato", - "users": "Utenti", - "users.index.headline": "Tutti gli utenti", - "users.index.add": "Aggiungi nuovo utente", - "users.index.edit": "Modifica", - "users.index.delete": "Elimina", - "users.form.username.label": "Nome utente", - "users.form.username.placeholder": "Il tuo nome utente", - "users.form.username.help": "Caratteri consentiti: minuscole a-z, 0-9 e trattini", - "users.form.username.readonly": "Il nome utente non può essere modificato", - "users.form.firstname.label": "Nome", - "users.form.lastname.label": "Cognome", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@esempio.com", - "users.form.password.label": "Password", - "users.form.password.confirm.label": "Conferma password", - "users.form.password.new.label": "Nuova password", - "users.form.password.new.confirm.label": "Conferma la nuova password", - "users.form.password.new.help": "Lasciare vuoto per mantenere la password corrente", - "users.form.language.label": "Lingua", - "users.form.role.label": "Ruolo", - "users.form.options.headline": "Opzioni account", - "users.form.options.message": "Invia email", - "users.form.options.delete": "Elimina account", - "users.form.avatar.headline": "Immagine del profilo", - "users.form.avatar.upload": "Carica immagine del profilo", - "users.form.avatar.replace": "Sostituisci immagine del profilo", - "users.form.avatar.delete": "Elimina immagine del profilo", - "users.form.back": "Torna agli utenti", - "users.form.error.password.confirm": "Conferma la password", - "users.form.error.update": "Il profilo dell'utente non può essere aggiornato", - "users.form.error.update.rights": "Non ti è permesso aggiornare questo utente", - "users.form.error.create": "Il profilo dell'utente non può essere creato", - "users.form.error.permissions.title": "La cartella degli account non dispone dei permessi di scrittura.", - "users.form.error.permissions.text": "Verifica che la cartella /site/accounts esista e disponga dei permessi di scrittura.", - "users.delete.headline": "Sei sicuro di voler eliminare questo utente?", - "users.delete.error": "L'utente non può essere eliminato", - "users.delete.error.permission": "Non ti è permesso eliminare gli utenti", - "users.delete.error.permission.single": "Non ti è permesso eliminare questo utente ", - "users.delete.error.lastadmin": "Non puoi eliminare l'ultimo amministratore", - "users.avatar.drop": "Trascina qui un'immagine per il profilo…", - "users.avatar.click": "…o clicca per caricarne una", - "users.avatar.error.type": "Puoi solo caricare files in formato JPG, PNG o GIF.", - "users.avatar.error.folder.headline": "La cartella delle immagini di profilo non ha i permessi di scrittura", - "users.avatar.error.folder.text": "Crea la cartella /assets/avatars e assegnale i permessi di scrittura per caricare le immagini dei profili.", - "users.avatar.error.permission": "Non ti è permesso di cambiare l'avatar", - "users.avatar.delete.error": "L'immagine del profilo non è potuta essere eliminata.", - "users.avatar.delete.error.permission": "Non ti è permesso di eliminare l'avatar di questo utente", - "users.avatar.delete.success": "L'immagine del profilo è stata eliminata", - "users.avatar.missing": "Questo utente non ha un avatar", - "users.error.missing": "L'utente non è stato trovato", - "user.error.lastadmin": "Tu sei l'unico amministratore. Questa voce non può essere cambiata.", - "form.error.missing": "Il form non esiste", - "form.construct.error.invalid": "Il metodo construction del form è invalido ", - "fields.required": "Campo obbligatorio", - "fields.date.label": "Data", - "fields.date.months": [ - "Gennaio", - "Febbraio", - "Marzo", - "Aprile", - "Maggio", - "Giugno", - "Luglio", - "Agosto", - "Settembre", - "Ottobre", - "Novembre", - "Dicembre" - ], - "fields.date.weekdays": [ - "Domenica", - "Lunedì", - "Martedì", - "Mercoledì", - "Giovedì", - "Venerdì", - "Sabato" - ], - "fields.date.weekdays.short": [ - "Do", - "Lu", - "Ma", - "Me", - "Gi", - "Ve", - "Sa" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@esempio.com", - "fields.number.label": "Numero", - "fields.number.placeholder": "#", - "fields.page.label": "Pagina", - "fields.page.placeholder": "percorso/alla/pagina", - "fields.password.label": "Password", - "fields.structure.add": "Aggiungi", - "fields.structure.add.first": "Aggiungi il primo elemento", - "fields.structure.empty": "Non ci sono ancora elementi.", - "fields.structure.entry.error": "L'elemento non esiste", - "fields.structure.cancel": "Annulla", - "fields.structure.save": "Salva", - "fields.structure.edit": "Modifica", - "fields.structure.delete": "Elimina", - "fields.structure.delete.label": "Vuoi veramente eliminare questo elemento?", - "fields.tags.label": "Tag", - "fields.tel.label": "Telefono", - "fields.textarea.buttons.bold.label": "Testo in grassetto", - "fields.textarea.buttons.bold.text": "Testo in grassetto", - "fields.textarea.buttons.italic.label": "Testo in corsivo", - "fields.textarea.buttons.italic.text": "Testo in corsivo", - "fields.textarea.buttons.link.label": "Link", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Immagine", - "fields.textarea.buttons.file.label": "File", - "fields.toggle.yes": "Sì", - "fields.toggle.no": "No", - "fields.toggle.on": "On", - "fields.toggle.off": "Off", - "fields.error.missing.controller": "Manca il file controller del campo", - "fields.error.missing.class": "Manca la classe controller del campo", - "fields.error.route.invalid": "Route del campo invalida", - "fields.error.extended": "Il campo non può essere esteso", - "editor.link.url.label": "Link", - "editor.link.text.label": "Testo del link", - "editor.link.text.help": "Il testo del link è opzionale", - "editor.email.address.label": "Email", - "editor.email.address.placeholder": "mail@esempio.com", - "editor.email.text.label": "Testo del link", - "editor.email.text.help": "Il testo del link è opzionale", - "editor.file.empty": "In questa pagina non ci sono files", - "editor.image.empty": "In questa pagina non ci sono immagini", - "autocomplete.method.error": "Metodo di autocompletamento invalido", - "blueprints.error.default.missing": "Manca il blueprint di default", - "error": "Errore", - "error.headline": "Errore" -} \ No newline at end of file diff --git a/panel/app/translations/it/package.json b/panel/app/translations/it/package.json deleted file mode 100644 index 89467f8..0000000 --- a/panel/app/translations/it/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Italiano", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/ja/core.json b/panel/app/translations/ja/core.json deleted file mode 100644 index 23aaa52..0000000 --- a/panel/app/translations/ja/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "キャンセル", - "add": "追加", - "addit": "Add & Edit", - "save": "保存", - "saved": "保存しました", - "change": "更新", - "delete": "削除", - "insert": "挿入", - "ok": "Ok", - "routes.error.invalid": "パネルのURLが間違っています。", - "controller.error.invalid": "不正な controlle です", - "controller.error.action": "不正な actio です", - "view.error.invalid": "不正な view です", - "options.show": "オプションを表示", - "options.hide": "オプションを隠す", - "installation": "インストール", - "installation.check.headline": "Kirby管理パネルのインストール", - "installation.check.text": "Kirbyのインストールプロセスで以下の問題が発生しました", - "installation.check.retry": "リトライ", - "installation.check.error": "次の項目を確認してください。", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts に書き込み権限がありません", - "installation.check.error.avatars": "/assets/avatars に書き込み権限がありません", - "installation.check.error.blueprints": "/site/blueprints フォルダがありません", - "installation.check.error.content": "content フォルダとその中のフォルダ/ファイルは全て書き込み権限を与えてください", - "installation.check.error.thumbs": "thumbs フォルダに書き込み権限がありません", - "installation.signup.username.label": "最初のアカウントを作成します", - "installation.signup.username.placeholder": "ユーザーID", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@example.com", - "installation.signup.password.label": "パスワード", - "installation.signup.language.label": "表示言語", - "installation.signup.button": "アカウントを作成", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "ユーザーID", - "login.password.label": "パスワード", - "login.error": "ユーザーID または パスワード が正しくありません", - "login.button": "Log in", - "login.log.error.permissions": "ログインログファイルに書き込み権限がありません", - "logout": "Log out", - "topbar.error.class.definition": "トップバーのクラス定義ファイルがありません", - "dashboard": "ダッシュボード", - "dashboard.index.pages.title": "ページ", - "dashboard.index.pages.edit": "編集", - "dashboard.index.pages.add": "作成", - "dashboard.index.site.title": "WebサイトURL", - "dashboard.index.account.title": "アカウント", - "dashboard.index.account.edit": "編集", - "dashboard.index.metatags.title": "サイト変数", - "dashboard.index.metatags.edit": "編集", - "dashboard.index.history.title": "最近編集したページ", - "dashboard.index.history.text": "最近編集したページの履歴がここに表示されます。", - "dashboard.index.license.title": "Kirbyのライセンス", - "dashboard.index.license.text": "現在 Kirby はライセンス登録なしにパブリックサーバーにインストールされています。\n\nPlease, support Kirby and (link: {buy} text: ライセンスの購入)により Kirby のサポートをお願いします。\n\nライセンスキーをお持ちでしたら設定ファイル((link: {docs} text: site/config/config.php))に記入してください。", - "metatags": "サイト変数", - "metatags.info": "Kirbyの情報", - "metatags.license": "Kirbyのライセンス", - "metatags.version.toolkit": "Toolkitのバージョン", - "metatags.version.kirby": "Kirbyのバージョン", - "metatags.version.panel": "管理パネルのバージョン", - "metatags.back": "ダッシュボードに戻る", - "metatags.files": "サイトファイル", - "site.delete.error": "サイトは削除できません", - "pages.show.settings": "ページアクション", - "pages.show.preview": "プレビュー", - "pages.show.template": "テンプレート", - "pages.show.changeurl": "ページ識別子(URL)", - "pages.show.invisible": "状態: 管理対象外", - "pages.show.visible": "状態: 管理対象", - "pages.show.changes.text": "保存されていない編集箇所があります!", - "pages.show.changes.button": "編集内容を破棄", - "pages.show.delete": "このページを削除", - "pages.show.subpages.title": "サブページ", - "pages.show.subpages.edit": "編集", - "pages.show.subpages.add": "作成", - "pages.show.subpages.empty": "サブページはありません", - "pages.show.files.title": "ファイル", - "pages.show.files.edit": "編集", - "pages.show.files.add": "アップロード", - "pages.show.files.empty": "ファイルはありません", - "pages.show.error.permissions.title": "書き込み権限がありません", - "pages.show.error.permissions.text": "content フォルダとその中のフォルダ/ファイルは全て書き込み権限を与えてください", - "pages.show.error.permissions.retry": "リトライ", - "pages.show.error.notitle.title": "定義ファイルに title フィールドが定義されていません", - "pages.show.error.notitle.text": "title フィールドを定義した上でリトライしてください", - "pages.show.error.notitle.retry": "リトライ", - "pages.show.error.form": "入力が正しくありません", - "pages.add.title.label": "新規ページ", - "pages.add.title.placeholder": "タイトル", - "pages.add.url.label": "ページ識別子(URL)", - "pages.add.url.enter": "(このページのURLに使用されます)", - "pages.add.url.close": "閉じる", - "pages.add.url.help": "使用可能な文字: 英数小文字 a-z, 0-9 と ハイフン ( - )", - "pages.add.template.label": "テンプレート", - "pages.add.error.create": "ページを作成できませんでした", - "pages.add.error.title": "タイトルが空欄です", - "pages.add.error.template": "テンプレートを指定してください", - "pages.add.error.max.headline": "ページを作成できません", - "pages.add.error.max.text": "上限に達しましたので、このページにはこれ以上サブページを作成できませんでした", - "pages.url.uid.label": "ページ識別子(URL)", - "pages.url.uid.label.option": "ページ名から生成", - "pages.url.error.exists": "同じページ識別子(URL)を持つページが既に存在しています", - "pages.url.error.move": "ページ識別子(URL)を変更できませんでした", - "pages.url.error.rights": "You cannot change the URL of this page", - "pages.template.select.label": "テンプレート", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "ページ順序", - "pages.toggle.invisible": "管理対象外", - "pages.toggle.publish": "Do you really want to change the status of this page to **visible?**", - "pages.toggle.hide": "Do you really want to change the status of this page to **invisible?**", - "pages.toggle.error.error": "The status of the error page cannot be changed", - "pages.delete.headline": "このページを削除してもよろしいですか?", - "pages.delete.error.home.headline": "The home page cannot be deleted", - "pages.delete.error.home.text": "You are trying to delete the home page. This is not possible and would lead to unwanted effects.", - "pages.delete.error.error.headline": "The error page cannot be deleted", - "pages.delete.error.error.text": "You are trying to delete the error page. This is not possible and would lead to unwanted effects.", - "pages.delete.error.children.headline": "The page cannot be deleted", - "pages.delete.error.children.text": "This page has subpages and cannot be deleted. Please delete all subpages first.", - "pages.delete.error.blocked.headline": "The page cannot be deleted", - "pages.delete.error.blocked.text": "This page is locked and cannot be deleted.", - "pages.search.help": "Search pages by URL. Navigate through search results with your up and down arrow keys and hit enter to jump to the selected page.", - "pages.search.noresults": "There are no search results for your query. Please try again with a different URL.", - "pages.error.missing": "The page could not be found", - "subpages": "ページ", - "subpages.index.headline": "ページの一覧:", - "subpages.index.back": "戻る", - "subpages.index.add": "新規ページ", - "subpages.index.add.first.text": "このページにはサブページがありません", - "subpages.index.add.first.button": "サブページを作成", - "subpages.index.visible": "管理対象のページ", - "subpages.index.visible.help": "管理対象外のページをここにドラッグアンドドロップで管理対象に設定されます。ソート順は設定ファイルに準じます。", - "subpages.index.invisible": "管理対象外のページ", - "subpages.index.invisible.help": "管理対象のページをここにドラッグアンドドロップで管理対象外に設定されます。ソート順はクリアされます。", - "subpages.add.error": "This page is not allowed to have subpages", - "subpages.add.error.more": "This page cannot have any more subpages", - "subpages.error.missing": "ページが見つかりませんでした", - "files": "ファイル", - "files.index.headline": "ファイルの一覧:", - "files.index.back": "戻る", - "files.index.upload": "ファイルのアップロード", - "files.index.upload.first.text": "このページにはファイルがありません", - "files.index.upload.first.button": "ファイルのアップロード", - "files.index.edit": "編集", - "files.index.delete": "削除", - "files.index.error.disabled": "The page is not allowed to have any files", - "files.add.error.max": "The maximum number of files for the current page has been reached.", - "files.add.error.extension.missing": "You cannot upload files without extension", - "files.add.error.extension.forbidden": "Forbidden file extension", - "files.add.error.mime.forbidden": "Forbidden mime type", - "files.add.error.htaccess": "htaccess files cannot be uploaded", - "files.add.error.invisible": "Invisible files cannot be uploaded", - "files.add.blueprint.type.error": "Page only allows:", - "files.add.blueprint.size.error": "Page only allows file size of", - "files.show.name.label": "ファイル名", - "files.show.info.label": "Type / Size / Dimensions", - "files.show.link.label": "Public link", - "files.show.open": "Show/download file", - "files.show.back": "Back", - "files.show.replace": "Replace", - "files.show.delete": "Delete", - "files.show.error.rename": "ファイル名を変更できませんでした", - "files.show.error.form": "入力が正しくありません", - "files.upload.drop": "ファイルをここにドロップ", - "files.upload.click": "もしくは、クリックしてアップロード", - "files.replace.drop": "ファイルをここにドロップ", - "files.replace.click": "もしくは、クリックして置き換え", - "files.replace.error.type": "元と同じ種類のファイルを選択してください", - "files.delete.headline": "このファイルを削除してもよろしいですか?", - "files.error.missing.page": "ページが見つかりませんでした", - "files.error.missing.file": "ファイルが見つかりませんでした", - "users": "ユーザー", - "users.index.headline": "ユーザーの一覧", - "users.index.add": "新規ユーザー", - "users.index.edit": "編集", - "users.index.delete": "削除", - "users.form.username.label": "ユーザーID", - "users.form.username.placeholder": "Your username", - "users.form.username.help": "使用可能な文字: 英数小文字 a-z, 0-9 と ハイフン ( - )", - "users.form.username.readonly": "ユーザーIDは変更できません", - "users.form.firstname.label": "姓", - "users.form.lastname.label": "名", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@example.com", - "users.form.password.label": "パスワード", - "users.form.password.confirm.label": "パスワードを再入力", - "users.form.password.new.label": "新しいパスワード", - "users.form.password.new.confirm.label": "新しいパスワードを再入力", - "users.form.password.new.help": "変更しない場合は入力しない", - "users.form.language.label": "表示言語", - "users.form.role.label": "権限", - "users.form.options.headline": "アカウントオプション", - "users.form.options.message": "Emailを送る", - "users.form.options.delete": "アカウントを削除", - "users.form.avatar.headline": "プロフィール用画像", - "users.form.avatar.upload": "画像のアップロード", - "users.form.avatar.replace": "画像の変更", - "users.form.avatar.delete": "画像の削除", - "users.form.back": "ユーザーの一覧に戻る", - "users.form.error.password.confirm": "パスワードを確認してください", - "users.form.error.update": "ユーザー情報は更新できませんでした", - "users.form.error.update.rights": "このユーザーの情報を編集する権限がありません", - "users.form.error.create": "新規ユーザーは作成できませんでした", - "users.form.error.permissions.title": "アカウント用のフォルダに書き込み権限がありません", - "users.form.error.permissions.text": "/site/accounts が存在し、書き込み権限があることを確認してください", - "users.delete.headline": "このユーザーを削除してもよろしいですか?", - "users.delete.error": "ユーザーを削除できませんでした", - "users.delete.error.permission": "ユーザーを削除する権限がありません", - "users.delete.error.permission.single": "このユーザーを削除する権限がありません", - "users.delete.error.lastadmin": "最後のAdminユーザーは削除できません", - "users.avatar.drop": "画像をここにドロップ", - "users.avatar.click": "もしくは、クリックしてアップロード", - "users.avatar.error.type": "JPG, PNG および GIF 形式のファイルのみアップロード可能です", - "users.avatar.error.folder.headline": "avatar フォルダに書き込み権限がありません", - "users.avatar.error.folder.text": "プロフィール用画像格納用に /assets/avatars フォルダを作成し、書き込み権限を与えてください", - "users.avatar.error.permission": "プロフィール用画像を変更する権限がありません", - "users.avatar.delete.error": "プロフィール用画像を削除できませんでした", - "users.avatar.delete.error.permission": "このユーザーのプロフィール用画像を削除する権限がありません", - "users.avatar.delete.success": "プロフィール用画像を削除しました", - "users.avatar.missing": "このユーザーはプロフィール用画像が設定されていません", - "users.error.missing": "ユーザーが見つかりませんでした", - "user.error.lastadmin": "現在あなたが唯一のAdminユーザーです。変更することはできません", - "form.error.missing": "The form cannot be found", - "form.construct.error.invalid": "Invalid form construction method", - "fields.required": "必須", - "fields.date.label": "Date", - "fields.date.months": [ - "1月", - "2月", - "3月", - "4月", - "5月", - "6月", - "7月", - "8月", - "9月", - "10月", - "11月", - "12月" - ], - "fields.date.weekdays": [ - "日曜日", - "月曜日", - "火曜日", - "水曜日", - "木曜日", - "金曜日", - "土曜日" - ], - "fields.date.weekdays.short": [ - "日", - "月", - "火", - "水", - "木", - "金", - "土" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@example.com", - "fields.number.label": "数値", - "fields.number.placeholder": "整数値", - "fields.page.label": "ページ", - "fields.page.placeholder": "path/to/page", - "fields.password.label": "パスワード", - "fields.structure.add": "作成", - "fields.structure.add.first": "最初のカードを作成してください。", - "fields.structure.empty": "カードがありません。", - "fields.structure.entry.error": "The item could not be found", - "fields.structure.cancel": "キャンセル", - "fields.structure.save": "保存", - "fields.structure.edit": "編集", - "fields.structure.delete": "削除", - "fields.structure.delete.label": "このカードを削除してもよろしいですか?", - "fields.tags.label": "タグ", - "fields.tel.label": "電話番号", - "fields.textarea.buttons.bold.label": "強調", - "fields.textarea.buttons.bold.text": "強調", - "fields.textarea.buttons.italic.label": "斜体", - "fields.textarea.buttons.italic.text": "斜体", - "fields.textarea.buttons.link.label": "リンク", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "画像", - "fields.textarea.buttons.file.label": "ファイル", - "fields.toggle.yes": "はい", - "fields.toggle.no": "いいえ", - "fields.toggle.on": "オン", - "fields.toggle.off": "オフ", - "fields.error.missing.controller": "The field controller file is missing", - "fields.error.missing.class": "The field controller class is missing", - "fields.error.route.invalid": "Invalid field route", - "fields.error.extended": "The field cannot be extended", - "editor.link.url.label": "URLを入力", - "editor.link.text.label": "リンクテキスト", - "editor.link.text.help": "リンクテキストは任意で設定可能です", - "editor.email.address.label": "Emailアドレスを入力してください", - "editor.email.address.placeholder": "mail@example.com", - "editor.email.text.label": "リンクテキスト", - "editor.email.text.help": "リンクテキストは任意で設定可能です", - "editor.file.empty": "'このページにはファイルがありません',", - "editor.image.empty": "'このページには画像がありません',", - "autocomplete.method.error": "オートコンプリートがエラーを起こしました", - "blueprints.error.default.missing": "デフォルトの定義ファイル(/site/blueprints/default.php)がありません", - "error": "エラー", - "error.headline": "エラー" -} \ No newline at end of file diff --git a/panel/app/translations/ja/package.json b/panel/app/translations/ja/package.json deleted file mode 100644 index 1c20e5e..0000000 --- a/panel/app/translations/ja/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Japanese", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/nb/core.json b/panel/app/translations/nb/core.json deleted file mode 100644 index c323d1e..0000000 --- a/panel/app/translations/nb/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Avbryt", - "add": "Legg til", - "addit": "Legg til og rediger", - "save": "Lagre", - "saved": "Lagret!", - "change": "Endre", - "delete": "Slett", - "insert": "Sett Inn", - "ok": "Ok", - "routes.error.invalid": "Ugylid Panel URL", - "controller.error.invalid": "Ugyldig kontroller", - "controller.error.action": "Ugyldig handling", - "view.error.invalid": "Ugyldig view:", - "options.show": "Vis alternativer", - "options.hide": "Skjul alternativer", - "installation": "Installasjon", - "installation.check.headline": "Kirby Panel Installasjon", - "installation.check.text": "Det oppsto problemer under installasjonen av Kirby…", - "installation.check.retry": "Prøv på nytt", - "installation.check.error": "Det er noen problemer!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts er ikke skrivbar", - "installation.check.error.avatars": "/assets/avatars er ikke skrivbar", - "installation.check.error.blueprints": "Vennligst legg til en /site/blueprints mappe", - "installation.check.error.content": "Mappen content og alt av innhold må være skrivbar.", - "installation.check.error.thumbs": "Mappen thumbs må være skrivbar.", - "installation.signup.username.label": "Lag din første konto", - "installation.signup.username.placeholder": "Brukernavn", - "installation.signup.email.label": "Epost", - "installation.signup.email.placeholder": "epost@eksempel.no", - "installation.signup.password.label": "Passord", - "installation.signup.language.label": "Språk", - "installation.signup.button": "Opprett konto", - "login": "Logg Inn", - "login.welcome": "Vennligst logg inn med din nye konto", - "login.username.label": "Brukernavn", - "login.password.label": "Passord", - "login.error": "Brukernavn eller passord er feil", - "login.button": "Logg Inn", - "login.log.error.permissions": "Logg inn loggfilen er ikke skrivbar.", - "logout": "Logg ut", - "topbar.error.class.definition": "Mangler topbar definisjon for klassen:", - "dashboard": "Dashboard", - "dashboard.index.pages.title": "Sider", - "dashboard.index.pages.edit": "Rediger", - "dashboard.index.pages.add": "Legg til", - "dashboard.index.site.title": "Din side's URL", - "dashboard.index.account.title": "Din konto", - "dashboard.index.account.edit": "Rediger", - "dashboard.index.metatags.title": "Nettsted variabler", - "dashboard.index.metatags.edit": "Rediger", - "dashboard.index.history.title": "Dine siste endringer", - "dashboard.index.history.text": "Dine siste endrede sider vil vises her for å gjøre det enkelt å finne dem igjen senere.", - "dashboard.index.license.title": "Kirby lisens", - "dashboard.index.license.text": "Det ser ut som om du kjører Kirby på en offentlig server uten en gyldig lisens!\n\nVær så snill, støtt Kirby og (link: {buy} text: kjøp en lisens nå)\n\nOm du allerede har en lisens nøkkel, legg den til i din konfigurasjons fil: (link {docs} text: site/config/config.php)", - "metatags": "Nettsted variabler", - "metatags.info": "Kirby informasjon", - "metatags.license": "Kirby lisens", - "metatags.version.toolkit": "Toolkit versjon", - "metatags.version.kirby": "Kirby versjon", - "metatags.version.panel": "Panel versjon", - "metatags.back": "Tilbake til dashboardet", - "metatags.files": "Sidefiler", - "site.delete.error": "Siden kan ikke slettes", - "pages.show.settings": "Sideinnstillinger", - "pages.show.preview": "Åpne forhåndsvisning", - "pages.show.template": "Mal", - "pages.show.changeurl": "Endre URL", - "pages.show.invisible": "Status: usynlig", - "pages.show.visible": "Status: synlig", - "pages.show.changes.text": "Du har ulagrede endringer!", - "pages.show.changes.button": "Forkast", - "pages.show.delete": "Slett denne siden", - "pages.show.subpages.title": "Sider", - "pages.show.subpages.edit": "Rediger", - "pages.show.subpages.add": "Legg til", - "pages.show.subpages.empty": "Denne siden har ingen undersider", - "pages.show.files.title": "Filer", - "pages.show.files.edit": "Rediger", - "pages.show.files.add": "Legg til", - "pages.show.files.empty": "Denne siden har ingen filer", - "pages.show.error.permissions.title": "Siden er ikke skrivbar", - "pages.show.error.permissions.text": "Vennligst sjekk rettigheten for content mappen og filer.", - "pages.show.error.permissions.retry": "Prøv på nytt", - "pages.show.error.notitle.title": "Blueprint har ikke tittelfelt", - "pages.show.error.notitle.text": "Vennligst legg til ett tittelfelt og prøv igjen", - "pages.show.error.notitle.retry": "Prøv igjen", - "pages.show.error.form": "Vennligst fyll inn alle feltene korrekt", - "pages.add.title.label": "Legg til en ny side", - "pages.add.title.placeholder": "Tittel", - "pages.add.url.label": "URL-appendiks", - "pages.add.url.enter": "(skriv inn din tittel)", - "pages.add.url.close": "Lukk", - "pages.add.url.help": "Format: små bokstaver a-z, 0-9 og vanlige bindestreker", - "pages.add.template.label": "Mal", - "pages.add.error.create": "Siden kunne ikke opprettes", - "pages.add.error.title": "Tittelen mangler", - "pages.add.error.template": "Malen mangler", - "pages.add.error.max.headline": "Ingen nye sider tillat", - "pages.add.error.max.text": "Maksimalt antall undersider for den gjeldende siden er nådd.", - "pages.url.uid.label": "URL-appendiks", - "pages.url.uid.label.option": "Opprett fra tittel", - "pages.url.error.exists": "En side med samme appendiks finnes allerede", - "pages.url.error.move": "Appendiks kunne ikke bli endret", - "pages.url.error.rights": "Du kan ikke endre URLen for denne siden", - "pages.template.select.label": "Mal", - "pages.template.warning.text": "Disse feltene vil endres når du endrer mal", - "pages.template.warning.removed": "Fjernet felt", - "pages.template.warning.replaced": "Erstattet felt", - "pages.template.warning.added": "Nye felt", - "pages.template.error": "Malen for denne siden kan ikke endres", - "pages.toggle.position": "Posisjon", - "pages.toggle.invisible": "usynlig", - "pages.toggle.publish": "Vil du virkelig endre statusen for denne siden til **synlig?**", - "pages.toggle.hide": "Vil du virkelig endre statusen for denne siden til **usynlig?**", - "pages.toggle.error.error": "Statusen for error siden kan ikke bli endret", - "pages.delete.headline": "Vil du virkelig slette denne siden?", - "pages.delete.error.home.headline": "Startsiden kan ikke slettes", - "pages.delete.error.home.text": "Du prøver å slette startsiden. Dette er ikke mulig og vil lede til uønskede effekter.", - "pages.delete.error.error.headline": "Feil siden kan ikke slette", - "pages.delete.error.error.text": "Du prøver å slette feil siden. Dette er ikke mulig og vil lede til uønskede effekter..", - "pages.delete.error.children.headline": "Denne siden kan ikke slette", - "pages.delete.error.children.text": "Denne siden har undersider og kan ikke bli slette. Vennligst slett alle undersider først.", - "pages.delete.error.blocked.headline": "Denne siden kan ikke slette", - "pages.delete.error.blocked.text": "Denne siden er låst og kan ikke slettes.", - "pages.search.help": "Søk sider med URL. Naviger gjennom søkeresultatene med opp og ned piltastene og trykk enter for å gå til den valgte siden", - "pages.search.noresults": "Det finnes ingen resultater for søket ditt. Vennligst prøv igjen med en annen nettadresse", - "pages.error.missing": "Siden kunne ikke bli funnet", - "subpages": "Sider", - "subpages.index.headline": "Sider i", - "subpages.index.back": "Tilbake", - "subpages.index.add": "Legg til en ny side", - "subpages.index.add.first.text": "Denne siden har ingen undersider ennå", - "subpages.index.add.first.button": "Legg til den første siden", - "subpages.index.visible": "Synlige sider", - "subpages.index.visible.help": "Dra usynlige sider her for å sortere dem/gjøre dem synlige.", - "subpages.index.invisible": "Usynlige sider", - "subpages.index.invisible.help": "Dra synlige sider her for å sortere dem/gjøre dem usynlige.", - "subpages.add.error": "Denne siden er ikke tillatt å ha undersider", - "subpages.add.error.more": "Denne siden kan ikke å ha flere undersider", - "subpages.error.missing": "Siden kunne ikke bli funnet", - "files": "Filer", - "files.index.headline": "Filer for", - "files.index.back": "Tilbake", - "files.index.upload": "Last opp en ny fil", - "files.index.upload.first.text": "Denne siden har ingen filer ennå", - "files.index.upload.first.button": "Last opp den første filen", - "files.index.edit": "Rediger", - "files.index.delete": "Slett", - "files.index.error.disabled": "Denne siden er ikke tillatt å ha filer", - "files.add.error.max": "Maksimalt antall filer for den gjeldende siden er nådd.", - "files.add.error.extension.missing": "Du kan ikke laste opp filer uten filtype", - "files.add.error.extension.forbidden": "Ugyldig filtype", - "files.add.error.mime.forbidden": "Ugyldig MIME-type", - "files.add.error.htaccess": "htaccess filer kan ikke bli lastet opp", - "files.add.error.invisible": "Usynlige filer kan ikke bli lastet opp", - "files.add.blueprint.type.error": "Siden godtar kun:", - "files.add.blueprint.size.error": "Siden tillater bare filstørrelsen:", - "files.show.name.label": "Filnavn", - "files.show.info.label": "Type / Størrelse / Dimensjoner", - "files.show.link.label": "Offentlig link", - "files.show.open": "Vis/last ned fil", - "files.show.back": "Tilbake", - "files.show.replace": "Erstatt", - "files.show.delete": "Slett", - "files.show.error.rename": "Filen kunne ikke endre navn", - "files.show.error.form": "Vennligst fyll inn alle feltene korrekt", - "files.upload.drop": "Slipp filene her…", - "files.upload.click": "…eller klikk for å laste opp", - "files.replace.drop": "Slipp en fil her…", - "files.replace.click": "…eller klikk for å erstatte", - "files.replace.error.type": "Den opplastede filen må ha samme filtype", - "files.delete.headline": "Vil du virkelig slette denne filen?", - "files.error.missing.page": "Siden kunne ikke bli funnet", - "files.error.missing.file": "Filen kunne ikke bli funnet", - "users": "Brukere", - "users.index.headline": "Alle brukere", - "users.index.add": "Legg til en ny bruker", - "users.index.edit": "Rediger", - "users.index.delete": "Slett", - "users.form.username.label": "Brukernavn", - "users.form.username.placeholder": "Ditt brukernavn", - "users.form.username.help": "Tillatte tegn: små bokstaver a-z, 0-9 og vanlige bindestreker", - "users.form.username.readonly": "Brukernavnet kan ikke endres", - "users.form.firstname.label": "Fornavn", - "users.form.lastname.label": "Etternavn", - "users.form.email.label": "Epost", - "users.form.email.placeholder": "epost@eksempel.no", - "users.form.password.label": "Passord", - "users.form.password.confirm.label": "Bekreft passord", - "users.form.password.new.label": "Nytt passord", - "users.form.password.new.confirm.label": "Bekreft det nye passordet", - "users.form.password.new.help": "La stå tomt for å beholde det gjeldende passord", - "users.form.language.label": "Språk", - "users.form.role.label": "Rolle", - "users.form.options.headline": "Kontoalternativer", - "users.form.options.message": "Send epost", - "users.form.options.delete": "Slett konto", - "users.form.avatar.headline": "Profil bilde", - "users.form.avatar.upload": "Last opp ett profil bilde", - "users.form.avatar.replace": "Erstatt profil bildet", - "users.form.avatar.delete": "Slett profil bildet", - "users.form.back": "Tilbake til brukere", - "users.form.error.password.confirm": "Vennligst bekreft passordet", - "users.form.error.update": "Brukeren kunne ikke bli oppdatert", - "users.form.error.update.rights": "Du er ikke tillat til å oppdatere denne brukeren", - "users.form.error.create": "Brukeren kunne ikke bli opprettes", - "users.form.error.permissions.title": "Account mappen er ikke skrivbar", - "users.form.error.permissions.text": "Vennligst kontroller at /site/accounts eksiterer og er skrivbar.", - "users.delete.headline": "Vil du virkelig slette denne konten?", - "users.delete.error": "Denne brukeren kunne ikke bli slettet", - "users.delete.error.permission": "Du er ikke tillat til å slette brukere", - "users.delete.error.permission.single": "Du er ikke tillat å slette denne brukeren", - "users.delete.error.lastadmin": "Du kan ikke slette den siste admin", - "users.avatar.drop": "Slipp profil bildet her…", - "users.avatar.click": "…eller klikk for å laste opp", - "users.avatar.error.type": "Du kan kun laste opp JPG, PNG og GIF filer", - "users.avatar.error.folder.headline": "Avatar mappen er ikke skrivbar", - "users.avatar.error.folder.text": "Vennligst opprett mappen /assets/avatars og kontroller att den er skrivbar for å laste opp profil bilder.", - "users.avatar.error.permission": "Du er ikke tillat til å endre avatar", - "users.avatar.delete.error": "Profil bildet kunne ikke bli slette", - "users.avatar.delete.error.permission": "Du er ikke tillat til å slette avataren til denne brukeren", - "users.avatar.delete.success": "Profil bildet har blitt slettet", - "users.avatar.missing": "Denne brukerer har ingen avatar", - "users.error.missing": "Brukeren kunne ikke bli funnet", - "user.error.lastadmin": "Du er den eneste administrator. Dette kan ikke endres.", - "form.error.missing": "Skjemaet kan ikke funnet", - "form.construct.error.invalid": "Ugyldig skjema byggemåte", - "fields.required": "Påkrevd", - "fields.date.label": "Dato", - "fields.date.months": [ - "Januar", - "Februar", - "Mars", - "April", - "Mai", - "Juni", - "July", - "August", - "September", - "Oktober", - "November", - "Desember" - ], - "fields.date.weekdays": [ - "Søndag", - "Mandag", - "Tirsdag", - "Onsdag", - "Torsdag", - "Fredag", - "Lørdag" - ], - "fields.date.weekdays.short": [ - "Søn", - "Man", - "Tir", - "Ons", - "Tor", - "Fre", - "Lør" - ], - "fields.email.label": "Epost", - "fields.email.placeholder": "epost@eksempel.no", - "fields.number.label": "Nummer", - "fields.number.placeholder": "#", - "fields.page.label": "Side", - "fields.page.placeholder": "sti/til/side", - "fields.password.label": "Passord", - "fields.structure.add": "Legg til", - "fields.structure.add.first": "Legg til den første oppføringen", - "fields.structure.empty": "Ingen oppføringer enda", - "fields.structure.entry.error": "Elementet kunne ikke bli funnet", - "fields.structure.cancel": "Avbryt", - "fields.structure.save": "Lagre", - "fields.structure.edit": "Rediger", - "fields.structure.delete": "Slett", - "fields.structure.delete.label": "Ønsker du virkelig å slette denne oppføringen?", - "fields.tags.label": "Tagger", - "fields.tel.label": "Mobil", - "fields.textarea.buttons.bold.label": "Tykk tekst", - "fields.textarea.buttons.bold.text": "Tykk tekst", - "fields.textarea.buttons.italic.label": "Kursiv tekst", - "fields.textarea.buttons.italic.text": "Kursiv tekst", - "fields.textarea.buttons.link.label": "Adresse", - "fields.textarea.buttons.email.label": "Epost", - "fields.textarea.buttons.image.label": "Bilde", - "fields.textarea.buttons.file.label": "Fil", - "fields.toggle.yes": "Ja", - "fields.toggle.no": "Nei", - "fields.toggle.on": "På", - "fields.toggle.off": "Av", - "fields.error.missing.controller": "Felt kontroller filen mangler", - "fields.error.missing.class": "Felt kontroller klassen mangler", - "fields.error.route.invalid": "Ugyldig felt rute", - "fields.error.extended": "Feltet kan ikke bli utvidet", - "editor.link.url.label": "Sett inn URL", - "editor.link.text.label": "Koblingstekst", - "editor.link.text.help": "Koblingstekst er valgfri", - "editor.email.address.label": "Sett inn epost adresse", - "editor.email.address.placeholder": "epost@eksempel.no", - "editor.email.text.label": "Koblingstekst", - "editor.email.text.help": "Koblingstekst er valgfri", - "editor.file.empty": "Denne siden har ingen filer", - "editor.image.empty": "Denne siden har ingen bilder", - "autocomplete.method.error": "Ugyldig autocomplete metode", - "blueprints.error.default.missing": "Mangler standard blåkopi", - "error": "Feil", - "error.headline": "Feil" -} \ No newline at end of file diff --git a/panel/app/translations/nb/package.json b/panel/app/translations/nb/package.json deleted file mode 100644 index 72ddcc6..0000000 --- a/panel/app/translations/nb/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Norsk Bokmål", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/nl/core.json b/panel/app/translations/nl/core.json deleted file mode 100644 index b713063..0000000 --- a/panel/app/translations/nl/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Annuleren", - "add": "Toevoegen", - "addit": "Toevoegen en bewerken", - "save": "Opslaan", - "saved": "Opgeslagen!", - "change": "Wijzig", - "delete": "Verwijder", - "insert": "Toevoegen", - "ok": "Ok", - "routes.error.invalid": "Ongeldige Panel URL", - "controller.error.invalid": "Ongeldige controller", - "controller.error.action": "Ongeldige actie", - "view.error.invalid": "Ongeldige view:", - "options.show": "Toon opties", - "options.hide": "Verberg opties", - "installation": "Installatie", - "installation.check.headline": "Kirby Panel installatie", - "installation.check.text": "Kirby vond de volgende fouten tijdens de installatie...", - "installation.check.retry": "Opnieuw proberen", - "installation.check.error": "Er zijn een aantal problemen!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts heeft geen schrijfrechten", - "installation.check.error.avatars": "/assets/avatars heeft geen schrijfrechten", - "installation.check.error.blueprints": "Voeg een /site/blueprints map toe", - "installation.check.error.content": "De contentmap en alle bestanden hierin moeten schrijfrechten hebben.", - "installation.check.error.thumbs": "De thumbs-map moet schrijfrechten hebben.", - "installation.signup.username.label": "Maak je eerste account", - "installation.signup.username.placeholder": "Gebruikersnaam", - "installation.signup.email.label": "E-mailadres", - "installation.signup.email.placeholder": "mail@voorbeeld.nl", - "installation.signup.password.label": "Wachtwoord", - "installation.signup.language.label": "Taal", - "installation.signup.button": "Maak account aan", - "login": "Inloggen", - "login.welcome": "Log in met je nieuwe account", - "login.username.label": "Gebruikersnaam", - "login.password.label": "Wachtwoord", - "login.error": "Ongeldige gebruikersnaam of wachtwoord", - "login.button": "Inloggen", - "login.log.error.permissions": "Login logbestand heeft geen schrijfrecht.", - "logout": "Uitloggen", - "topbar.error.class.definition": "Ontbrekende 'topbar definition' voor class:", - "dashboard": "Dashboard", - "dashboard.index.pages.title": "Pagina's", - "dashboard.index.pages.edit": "Wijzig", - "dashboard.index.pages.add": "Toevoegen", - "dashboard.index.site.title": "URL van je site", - "dashboard.index.account.title": "Jouw account", - "dashboard.index.account.edit": "Wijzig", - "dashboard.index.metatags.title": "Site-variabelen", - "dashboard.index.metatags.edit": "Wijzig", - "dashboard.index.history.title": "Jouw laatste updates", - "dashboard.index.history.text": "Pagina's die het laatst door jou zijn gewijzigd komen hier te staan, om ze weer makkelijk terug te kunnen vinden.", - "dashboard.index.license.title": "Kirby licentie", - "dashboard.index.license.text": "Het lijkt erop dat je Kirby gebruikt op een publieke server zonder een geldige licentie!\nOndersteun Kirby en (link: {buy} text: koop een licentie)\nAls je al een licentie code hebt, voeg deze dan toe aan je configuratie bestand: (link: {docs} text: site/config/config.php)", - "metatags": "Site-variabelen", - "metatags.info": "Kirby info", - "metatags.license": "Kirby licentie", - "metatags.version.toolkit": "Toolkit versie", - "metatags.version.kirby": "Kirby versie", - "metatags.version.panel": "Panel versie", - "metatags.back": "Terug naar het dashboard", - "metatags.files": "Site bestanden", - "site.delete.error": "De site kan niet worden verwijderd", - "pages.show.settings": "Pagina opties", - "pages.show.preview": "Open voorbeeld", - "pages.show.template": "Template", - "pages.show.changeurl": "Verander URL", - "pages.show.invisible": "Status: onzichtbaar", - "pages.show.visible": "Status: zichtbaar", - "pages.show.changes.text": "Je hebt wijzigingen die nog niet zijn opgeslagen!", - "pages.show.changes.button": "Annuleren", - "pages.show.delete": "Verwijder deze pagina", - "pages.show.subpages.title": "Pagina's", - "pages.show.subpages.edit": "Wijzig", - "pages.show.subpages.add": "Toevoegen", - "pages.show.subpages.empty": "Deze pagina heeft geen subpagina's", - "pages.show.files.title": "Bestanden", - "pages.show.files.edit": "Wijzig", - "pages.show.files.add": "Toevoegen", - "pages.show.files.empty": "Deze pagina heeft geen bestanden", - "pages.show.error.permissions.title": "Deze pagina is niet te bewerken", - "pages.show.error.permissions.text": "Controleer de rechten voor de content-map en alle bestanden in de map.", - "pages.show.error.permissions.retry": "Opnieuw proberen", - "pages.show.error.notitle.title": "De blueprint heeft geen \\`title\\`-veld", - "pages.show.error.notitle.text": "Voeg een \\`title\\` veld toe en probeer het opnieuw.", - "pages.show.error.notitle.retry": "Opnieuw proberen", - "pages.show.error.form": "Vul alle velden correct in", - "pages.add.title.label": "Voeg een nieuwe pagina toe", - "pages.add.title.placeholder": "Titel", - "pages.add.url.label": "URL-toevoeging", - "pages.add.url.enter": "(Voer een titel in)", - "pages.add.url.close": "Sluiten", - "pages.add.url.help": "Toegestaan: a-z (kleine letters) en standaard streepjes (-)", - "pages.add.template.label": "Template", - "pages.add.error.create": "De pagina kon niet worden aangemaakt", - "pages.add.error.title": "De titel ontbreekt", - "pages.add.error.template": "De template ontbreekt", - "pages.add.error.max.headline": "Geen nieuwe pagina's toegestaan", - "pages.add.error.max.text": "Je hebt het maximum aantal van subpagina's voor deze pagina bereikt.", - "pages.url.uid.label": "URL-toevoeging", - "pages.url.uid.label.option": "Maak op basis van titel", - "pages.url.error.exists": "Er bestaat al een pagina met deze URL-toevoeging", - "pages.url.error.move": "De URL-toevoeging kan niet worden gewijzigd", - "pages.url.error.rights": "Je kunt de URL van deze pagina niet wijzigen", - "pages.template.select.label": "Template", - "pages.template.warning.text": "De volgende velden veranderen, als je de template wijzigt.", - "pages.template.warning.removed": "Verwijderde velden", - "pages.template.warning.replaced": "Vervangen velden", - "pages.template.warning.added": "Toegevoegde velden", - "pages.template.error": "De template voor deze pagina kan niet worden gewijzigd", - "pages.toggle.position": "Positie", - "pages.toggle.invisible": "Onzichtbaar", - "pages.toggle.publish": "Wil je de status wijzigen naar **zichtbaar**?", - "pages.toggle.hide": "Wil je de status wijzigen naar **onzichtbaar**?", - "pages.toggle.error.error": "De status van de error-pagina kan niet gewijzigd worden", - "pages.delete.headline": "Weet je zeker dat je deze pagina wil verwijderen?", - "pages.delete.error.home.headline": "De homepage kan niet worden verwijderd", - "pages.delete.error.home.text": "Je probeert de homepage te verwijderen. Dit is niet mogelijk en zou kunnen leiden tot ongewenste resultaten.", - "pages.delete.error.error.headline": "De fout-pagina kan niet worden verwijderd", - "pages.delete.error.error.text": "Je probeert de fout-pagina te verwijderen. Dit is niet mogelijk en zou kunnen leiden tot ongewenste resultaten.", - "pages.delete.error.children.headline": "De pagina kan niet worden verwijderd", - "pages.delete.error.children.text": "Deze pagina heeft subpagina's en kan niet worden verwijderd. Verwijder eerst de subpagina's.", - "pages.delete.error.blocked.headline": "De pagina kan niet worden verwijderd", - "pages.delete.error.blocked.text": "Deze pagina is vergrendeld en kan niet worden verwijderd.", - "pages.search.help": "Zoek door pagina's op URL. Je kunt navigeren tussen de pagina's met je pijltjestoetsen. Met enter ga je naar de geselecteerde pagina.", - "pages.search.noresults": "Geen zoekresultaten. Probeer het opnieuw met een andere URL.", - "pages.error.missing": "De pagina kan niet worden gevonden", - "subpages": "Pagina's", - "subpages.index.headline": "Pagina's in", - "subpages.index.back": "Terug", - "subpages.index.add": "Nieuwe pagina toevoegen", - "subpages.index.add.first.text": "Deze pagina heeft nog geen subpagina's", - "subpages.index.add.first.button": "Voeg de eerste pagina toe", - "subpages.index.visible": "Zichtbare pagina's", - "subpages.index.visible.help": "Sleep onzichtbare pagina's hiernaartoe om ze zichtbaar te maken.", - "subpages.index.invisible": "Onzichtbare pagina's", - "subpages.index.invisible.help": "Sleep zichtbare pagina's hiernaartoe om ze onzichtbaar te maken.", - "subpages.add.error": "Deze pagina mag geen subpagina's bevatten", - "subpages.add.error.more": "Deze pagina kan niet meer subpagina's bevatten", - "subpages.error.missing": "De pagina kan niet worden gevonden", - "files": "Bestanden", - "files.index.headline": "Bestanden voor", - "files.index.back": "Terug", - "files.index.upload": "Upload een nieuw bestand", - "files.index.upload.first.text": "Deze pagina heeft nog geen bestanden", - "files.index.upload.first.button": "Upload het eerste bestand", - "files.index.edit": "Wijzgen", - "files.index.delete": "Verwijderen", - "files.index.error.disabled": "Deze pagina mag geen bestanden bevatten", - "files.add.error.max": "Het maximum aantal bestanden voor deze pagina is bereikt.", - "files.add.error.extension.missing": "Je kunt geen bestanden uploaden zonder bestandsextensie", - "files.add.error.extension.forbidden": "Bestandsextensie niet toegestaan", - "files.add.error.mime.forbidden": "Mime type niet toegestaan", - "files.add.error.htaccess": "htaccess bestanden kunnen niet geüpload worden", - "files.add.error.invisible": "Onzichtbare bestanden kunnen niet geüpload worden", - "files.add.blueprint.type.error": "Pagina laat alleen het volgende toe:", - "files.add.blueprint.size.error": "Pagina laat alleen bestanden toe met een maximum bestandsgrootte van", - "files.show.name.label": "Bestandsnaam", - "files.show.info.label": "Type / grootte / afmetingen", - "files.show.link.label": "Publieke link", - "files.show.open": "Bekijk/download bestand", - "files.show.back": "Terug", - "files.show.replace": "Vervangen", - "files.show.delete": "Verwijderen", - "files.show.error.rename": "Het bestand kan niet worden hernoemd", - "files.show.error.form": "Vul alle velden correct in", - "files.upload.drop": "Sleep bestanden hiernaartoe...", - "files.upload.click": "... of klik hier om bestanden te uploaden", - "files.replace.drop": "Sleep een bestand hiernaartoe...", - "files.replace.click": "... of klik hier om een bestand te uploaden", - "files.replace.error.type": "Het geüploade bestand moet van hetzelfde type zijn", - "files.delete.headline": "Wil je dit bestand verwijderen?", - "files.error.missing.page": "De pagina kan niet worden gevonden", - "files.error.missing.file": "Het bestand kan niet worden gevonden", - "users": "Users", - "users.index.headline": "Alle gebruikers", - "users.index.add": "Voeg een nieuwe gebruiker toe", - "users.index.edit": "Wijzigen", - "users.index.delete": "Verwijderen", - "users.form.username.label": "Gebruikersnaam", - "users.form.username.placeholder": "Jouw gebruikersnaam", - "users.form.username.help": "Toegestaan: a-z (kleine letters), 0-9 en streepjes (-)", - "users.form.username.readonly": "De gebruikersnaam kan niet worden gewijzigd", - "users.form.firstname.label": "Voornaam", - "users.form.lastname.label": "Achternaam", - "users.form.email.label": "E-mailadres", - "users.form.email.placeholder": "mail@voorbeeld.nl", - "users.form.password.label": "Wachtwoord", - "users.form.password.confirm.label": "Bevestig wachtwoord", - "users.form.password.new.label": "Nieuw wachtwoord", - "users.form.password.new.confirm.label": "Bevestig het nieuwe wachtwoord", - "users.form.password.new.help": "Laat leeg om je huidige wachtwoord te behouden", - "users.form.language.label": "Taal", - "users.form.role.label": "Rol", - "users.form.options.headline": "Account-opties", - "users.form.options.message": "E-mail versturen", - "users.form.options.delete": "Verwijder account", - "users.form.avatar.headline": "Avatar", - "users.form.avatar.upload": "Avatar uploaden", - "users.form.avatar.replace": "Avatar vervangen", - "users.form.avatar.delete": "Delete avatar", - "users.form.back": "Terug naar gebruikers", - "users.form.error.password.confirm": "Bevestig je wachtwoord", - "users.form.error.update": "De gebruiker kan niet worden gewijzigd", - "users.form.error.update.rights": "Je hebt niet voldoende rechten om deze gebruiker te wijzigen", - "users.form.error.create": "De gebruiker kan niet worden aangemaakt", - "users.form.error.permissions.title": "De 'accounts'-map heeft niet voldoende rechten.", - "users.form.error.permissions.text": "Zorg ervoor dat de map 'site/accounts' bestaat en schrijfrechten heeft.", - "users.delete.headline": "Wil je deze gebruiker verwijderen?", - "users.delete.error": "De gebruiker kan niet worden verwijderd", - "users.delete.error.permission": "Je hebt niet voldoende rechten om gebruikers te verwijderen", - "users.delete.error.permission.single": "Je hebt niet voldoende rechten om deze gebruiker te verwijderen", - "users.delete.error.lastadmin": "Je kan de laatste admin niet verwijderen", - "users.avatar.drop": "Sleep een profielfoto hiernaartoe...", - "users.avatar.click": "... of klik hier om afbeelding te selecteren", - "users.avatar.error.type": "Je kunt alleen .jpg, .png en .gif bestanden uploaden", - "users.avatar.error.folder.headline": "De avatar-map heeft geen schrijfrechten.", - "users.avatar.error.folder.text": "Zorg ervoor dat de map /assets/avatars bestaat en schrijfrechten heeft om avatars te uploaden.", - "users.avatar.error.permission": "Je hebt niet voldoende rechtsen om deze avatar te wijzigen", - "users.avatar.delete.error": "De avatar kan niet worden verwijderd", - "users.avatar.delete.error.permission": "Je hebt niet voldoende rechten om de avatar van deze gebruiker te verwijderen", - "users.avatar.delete.success": "De avatar is verwijderd", - "users.avatar.missing": "Deze gebruiker heeft geen avatar", - "users.error.missing": "De gebruiker kan niet worden gevonden", - "user.error.lastadmin": "Jij bent de enige admin. Dit kan niet gewijzigd worden.", - "form.error.missing": "Het formulier kon niet gevonden worden.", - "form.construct.error.invalid": "Ongeldige formulier construction method", - "fields.required": "Verplicht", - "fields.date.label": "Datum", - "fields.date.months": [ - "januari", - "februari", - "maart", - "april", - "mei", - "juni", - "juli", - "augustus", - "september", - "oktober", - "november", - "december" - ], - "fields.date.weekdays": [ - "Zondag", - "Maandag", - "Dinsdag", - "Woensdag", - "Donderdag", - "Vrijdag", - "Zaterdag" - ], - "fields.date.weekdays.short": [ - "Zo", - "Ma", - "Di", - "Wo", - "Do", - "Vr", - "Za" - ], - "fields.email.label": "E-mailadres", - "fields.email.placeholder": "mail@voorbeeld.nl", - "fields.number.label": "Nummer", - "fields.number.placeholder": "#", - "fields.page.label": "Pagina", - "fields.page.placeholder": "pad/naar/pagina", - "fields.password.label": "Wachtwoord", - "fields.structure.add": "Toevoegen", - "fields.structure.add.first": "Voeg het eerste item toe", - "fields.structure.empty": "Nog geen items.", - "fields.structure.entry.error": "Item kon niet gevonden worden", - "fields.structure.cancel": "Annuleren", - "fields.structure.save": "Ok", - "fields.structure.edit": "Wijzigen", - "fields.structure.delete": "Verwijderen", - "fields.structure.delete.label": "Wil je deze entry verwijderen?", - "fields.tags.label": "Tags", - "fields.tel.label": "Telefoon", - "fields.textarea.buttons.bold.label": "Dikgedrukte tekst", - "fields.textarea.buttons.bold.text": "Dikgedrukte tekst", - "fields.textarea.buttons.italic.label": "Cursieve tekst", - "fields.textarea.buttons.italic.text": "Cursieve tekst", - "fields.textarea.buttons.link.label": "Link", - "fields.textarea.buttons.email.label": "E-mailadres", - "fields.textarea.buttons.image.label": "Afbeelding", - "fields.textarea.buttons.file.label": "Bestand", - "fields.toggle.yes": "Ja", - "fields.toggle.no": "Nee", - "fields.toggle.on": "Aan", - "fields.toggle.off": "Uit", - "fields.error.missing.controller": "De 'field controller' file ontbreekt", - "fields.error.missing.class": "De 'field controller' class ontbreekt", - "fields.error.route.invalid": "Ongeldige field route", - "fields.error.extended": "Het veld kan niet worden uitgebreid", - "editor.link.url.label": "URL invoegen", - "editor.link.text.label": "Link-tekst", - "editor.link.text.help": "De link-tekst is niet verplicht", - "editor.email.address.label": "E-mailadres invoegen", - "editor.email.address.placeholder": "mail@voorbeeld.nl", - "editor.email.text.label": "Link-tekst", - "editor.email.text.help": "De link-tekst is niet verplicht", - "editor.file.empty": "Deze pagina heeft geen bestanden", - "editor.image.empty": "Deze pagina heeft geen afbeeldingen", - "autocomplete.method.error": "Ongeldige autocomplete methode", - "blueprints.error.default.missing": "Default blueprint ontbreekt", - "error": "Foutmelding", - "error.headline": "Foutmelding" -} \ No newline at end of file diff --git a/panel/app/translations/nl/package.json b/panel/app/translations/nl/package.json deleted file mode 100644 index 2b99314..0000000 --- a/panel/app/translations/nl/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Nederlands", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/pl/core.json b/panel/app/translations/pl/core.json deleted file mode 100644 index 804a70b..0000000 --- a/panel/app/translations/pl/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Anuluj", - "add": "Dodaj", - "addit": "Dodaj i Edytuj", - "save": "Zapisz", - "saved": "Zapisano!", - "change": "Zmień", - "delete": "Usuń", - "insert": "Wstaw", - "ok": "Ok", - "routes.error.invalid": "Niewłaściwy adres URL panelu", - "controller.error.invalid": "Niewłaściwy kontroler", - "controller.error.action": "Niewłaściwa akcja", - "view.error.invalid": "Niewłaściwy widok:", - "options.show": "Pokaż opcje", - "options.hide": "Ukryj opcje", - "installation": "Instalacja", - "installation.check.headline": "Instalacja panelu Kirby", - "installation.check.text": "Kirby napotkał następujące problemy podczas instalacji…", - "installation.check.retry": "Ponów próbę", - "installation.check.error": "Wystąpiły jakieś problemy!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts nie ma praw do zapisu", - "installation.check.error.avatars": "/assets/avatars nie ma praw do zapisu", - "installation.check.error.blueprints": "Proszę dodać folder /site/blueprints", - "installation.check.error.content": "Folder content oraz wszystkie foldery i pliki wewnątrz muszą mieć ustawione prawa do zapisu.", - "installation.check.error.thumbs": "Folder thumbs musi mieć ustawione prawa do zapisu.", - "installation.signup.username.label": "Utwórz swoje pierwsze konto.", - "installation.signup.username.placeholder": "Nazwa użytkownika", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@example.com", - "installation.signup.password.label": "Hasło", - "installation.signup.language.label": "Język", - "installation.signup.button": "Utwórz konto", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Nazwa użytkownika", - "login.password.label": "Hasło", - "login.error": "Niepoprawna nazwa użytkownika lub hasło", - "login.button": "Log in", - "login.log.error.permissions": "Plik dziennika logowania nie ma ustawionych praw do zapisu.", - "logout": "Log out", - "topbar.error.class.definition": "Missing topbar definition for class:", - "dashboard": "Panel administracyjny", - "dashboard.index.pages.title": "Strony", - "dashboard.index.pages.edit": "Edytuj", - "dashboard.index.pages.add": "Dodaj", - "dashboard.index.site.title": "Adres URL Twojej strony", - "dashboard.index.account.title": "Twoje konto", - "dashboard.index.account.edit": "Edytuj", - "dashboard.index.metatags.title": "Metadane strony", - "dashboard.index.metatags.edit": "Edytuj", - "dashboard.index.history.title": "Twoje ostatnie modyfikacje", - "dashboard.index.history.text": "Twoje ostatnio zmodyfikowane strony będą wyświetlane tutaj, aby łatwo je było odnaleźć ponownie później.", - "dashboard.index.license.title": "Licencja Kirby", - "dashboard.index.license.text": "Wygląda na to, że korzystasz z Kirby na publicznym serwerze bez ważnej licencji!\nProszę, wesprzyj Kirby i (link: {buy} text: kup licencję teraz).\nJeżeli już posiadasz klucz licencyjny, po prostu dodaj go do pliku konfiguracyjnego: (link: {docs} text: site/config/config.php)", - "metatags": "Ustawienia serwisu", - "metatags.info": "Informacje nt. Kirby", - "metatags.license": "Licencja Kirby", - "metatags.version.toolkit": "Wersja toolkitu", - "metatags.version.kirby": "Wersja Kirby", - "metatags.version.panel": "Wersja panelu", - "metatags.back": "Powróć do panelu administracyjnego", - "metatags.files": "Pliki strony", - "site.delete.error": "Strona nie może zostać usunięta", - "pages.show.settings": "Ustawienia strony", - "pages.show.preview": "Otwórz podgląd", - "pages.show.template": "Szablon", - "pages.show.changeurl": "Zmień URL", - "pages.show.invisible": "Status: niewidzialna", - "pages.show.visible": "Status: widoczna", - "pages.show.changes.text": "Masz niezapisane zmiany!", - "pages.show.changes.button": "Odrzuć", - "pages.show.delete": "Usuń tę stronę", - "pages.show.subpages.title": "Strony", - "pages.show.subpages.edit": "Edytuj", - "pages.show.subpages.add": "Dodaj", - "pages.show.subpages.empty": "Ta strona nie posiada podstron", - "pages.show.files.title": "Pliki", - "pages.show.files.edit": "Edytuj", - "pages.show.files.add": "Dodaj", - "pages.show.files.empty": "Ta strona nie posiada plików", - "pages.show.error.permissions.title": "Nie ma uprawnień do zapisu dla tej strony", - "pages.show.error.permissions.text": "Sprawdź uprawnienia dla folderu content i plików znajdujących się w tym folderze.", - "pages.show.error.permissions.retry": "Spróbuj ponownie", - "pages.show.error.notitle.title": "Szablon tej strony nie posiada pola tytułu", - "pages.show.error.notitle.text": "Dodaj pole tytułu i spróbuj ponownie", - "pages.show.error.notitle.retry": "Spróbuj ponownie", - "pages.show.error.form": "Wypełnij wszystkie pola poprawnie", - "pages.add.title.label": "Dodaj nową stronę", - "pages.add.title.placeholder": "Tytuł", - "pages.add.url.label": "apendyks URL", - "pages.add.url.enter": "(wprowadź tytuł)", - "pages.add.url.close": "Zamknij", - "pages.add.url.help": "Formatowanie: małe litery a-z, 0-9 i myślnik", - "pages.add.template.label": "Szablon", - "pages.add.error.create": "Strona nie może zostać utworzona", - "pages.add.error.title": "Brakuje tytułu", - "pages.add.error.template": "Brakuje szablonu", - "pages.add.error.max.headline": "Nie można dodać nowej strony", - "pages.add.error.max.text": "Maksymalna liczba podstron dla tej strony została już osiągnięta.", - "pages.url.uid.label": "apendyks URL", - "pages.url.uid.label.option": "Utwórz na podstawie tytułu", - "pages.url.error.exists": "Strona z takim apendyksem już istnieje", - "pages.url.error.move": "Apendyks nie mógł zostać zmieniony", - "pages.url.error.rights": "Nie możesz zmienić adres URL tej strony", - "pages.template.select.label": "Szablon", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Pozycja", - "pages.toggle.invisible": "niewidoczny", - "pages.toggle.publish": "Czy na pewno chcesz zmienić status strony na **widoczna**", - "pages.toggle.hide": "Czy na pewno chcesz zmienić status strony na **niewidzialna**", - "pages.toggle.error.error": "Status dla strony błędu nie może zostać zmieniony", - "pages.delete.headline": "Czy na pewno chcesz usunąć tę stronę?", - "pages.delete.error.home.headline": "Strona główna nie może zostać usunięta", - "pages.delete.error.home.text": "Próbujesz skasować stronę główną. To nie jest możliwe i prowadziłoby do niepożądanych skutków.", - "pages.delete.error.error.headline": "Strona błędu nie może zostać usunięta", - "pages.delete.error.error.text": "Próbujesz skasować stronę błędu. To nie jest możliwe i prowadziłoby do niepożądanych skutków.", - "pages.delete.error.children.headline": "Ta strona nie może zostać usunięta", - "pages.delete.error.children.text": "Ta strona posiada podstrony i nie może zostać skasowana. Usuń najpierw wszystkie podstrony.", - "pages.delete.error.blocked.headline": "Ta strona nie może zostać usunięta", - "pages.delete.error.blocked.text": "Ta strona jest zablokowana i nie może zostać usunięta.", - "pages.search.help": "Przeszukaj strony według URL. Nawiguj po wynikach wyszukiwania strzałkami góra/dół i naciśnij enter, by przejść do wybranej strony.", - "pages.search.noresults": "Brak wyników wyszukiwania dla zapytania. Spróbuj ponownie z innym adresem URL.", - "pages.error.missing": "Strona nie została odnaleziona", - "subpages": "Strony", - "subpages.index.headline": "Strony w", - "subpages.index.back": "Wróć", - "subpages.index.add": "Dodaj nową stronę", - "subpages.index.add.first.text": "Ta strona nie posiada jeszcze żadnych podstron", - "subpages.index.add.first.button": "Dodaj pierwszą stronę", - "subpages.index.visible": "Widzialne strony", - "subpages.index.visible.help": "Przeciągnij tutaj niewidzialne strony, by zmienić kolejność/sprawić, żeby były widzialne.", - "subpages.index.invisible": "Niewidzialne strony", - "subpages.index.invisible.help": "Przeciągnij tutaj widzialne strony, aby sprawić, żeby były niewidzialne.", - "subpages.add.error": "Ta strona nie może mieć podstron", - "subpages.add.error.more": "Ta strona nie może mieć więcej podstron", - "subpages.error.missing": "Strona nie została odnaleziona", - "files": "Pliki", - "files.index.headline": "Pliki dla", - "files.index.back": "Wróć", - "files.index.upload": "Dodaj nowy plik", - "files.index.upload.first.text": "Ta strona nie posiada jeszcze żadnych plików", - "files.index.upload.first.button": "Dodaj pierwszy plik", - "files.index.edit": "Edytuj", - "files.index.delete": "Usuń", - "files.index.error.disabled": "Strona nie może mieć żadnych plików", - "files.add.error.max": "Maksymalna liczba plików dla bieżącej stronie został osiągnięty.", - "files.add.error.extension.missing": "Nie można przesyłać plików bez rozszerzenia", - "files.add.error.extension.forbidden": "Zabronione rozszerzenie pliku", - "files.add.error.mime.forbidden": "Zabroniony typ MIME", - "files.add.error.htaccess": "Plik htaccess nie może być przesłany", - "files.add.error.invisible": "Pliki ukryte nie mogą być przesłane", - "files.add.blueprint.type.error": "Strona zezwala tylko na:", - "files.add.blueprint.size.error": "Strona zezwala tylko na pliki o rozmiarze", - "files.show.name.label": "Nazwa pliku", - "files.show.info.label": "Typ / Rozmiar / Wymiary", - "files.show.link.label": "Publiczny link", - "files.show.open": "Pokaż/pobierz plik", - "files.show.back": "Wróć", - "files.show.replace": "Zamień", - "files.show.delete": "Usuń", - "files.show.error.rename": "Nazwa pliku nie mogła zostać zmieniona", - "files.show.error.form": "Wypełnij poprawnie wszystkie pola", - "files.upload.drop": "Upuść pliki tutaj", - "files.upload.click": "…lub kliknij, aby załadować", - "files.replace.drop": "Upuść plik tutaj…", - "files.replace.click": "…lub kliknij, aby zastąpić", - "files.replace.error.type": "Przesłany plik musi być plikiem tego samego typu", - "files.delete.headline": "Czy na pewno chcesz usunąć ten plik?", - "files.error.missing.page": "Strona nie została odnaleziona", - "files.error.missing.file": "Plik nie został odnaleziony", - "users": "Użytkownicy", - "users.index.headline": "Wszyscy użytkownicy", - "users.index.add": "Dodaj nowego użytkownika", - "users.index.edit": "Edytuj", - "users.index.delete": "Usuń", - "users.form.username.label": "Nazwa użytkownika", - "users.form.username.placeholder": "Twoja nazwa użytkownika", - "users.form.username.help": "Dozwolone znaki: małe litery a-z, 0-9 i myślnik", - "users.form.username.readonly": "Nazwa użytkownika nie może zostać zmieniona", - "users.form.firstname.label": "Imię", - "users.form.lastname.label": "Nazwisko", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@example.com", - "users.form.password.label": "Hasło", - "users.form.password.confirm.label": "Potwierdź hasło", - "users.form.password.new.label": "Nowe hasło", - "users.form.password.new.confirm.label": "Potwierdź nowe hasło", - "users.form.password.new.help": "Pozostaw puste, aby zachować bieżące hasło", - "users.form.language.label": "Język", - "users.form.role.label": "Rola", - "users.form.options.headline": "Opcje konta", - "users.form.options.message": "Wyślij email", - "users.form.options.delete": "Usuń konto", - "users.form.avatar.headline": "Zdjęcie profilowe", - "users.form.avatar.upload": "Dodaj zdjęcie profilowe", - "users.form.avatar.replace": "Zmień zdjęcie profilowe", - "users.form.avatar.delete": "Usuń zdjęcie profilowe", - "users.form.back": "Wróć do użytkowników", - "users.form.error.password.confirm": "Potwierdź hasło", - "users.form.error.update": "Użytkownik nie mógł zostać zaktualizowany", - "users.form.error.update.rights": "Nie masz uprawnień do aktualizacji tego użytkownika", - "users.form.error.create": "Użytkownik nie mógł zostać utworzony", - "users.form.error.permissions.title": "Folder account nie ma praw do zapisu", - "users.form.error.permissions.text": "Upewnij się, że folder /site/accounts istnieje i posiada prawa do zapisu.", - "users.delete.headline": "Czy na pewno chcesz usunąć tego użytkownika?", - "users.delete.error": "Użytkownik nie mógł zostać usunięty", - "users.delete.error.permission": "Nie masz uprawnień do usuwania użytkowników", - "users.delete.error.permission.single": "Nie masz uprawnień do usunięcia tego użytkownika", - "users.delete.error.lastadmin": "Nie możesz usunąć jedynego administratora", - "users.avatar.drop": "Upuść zdjęcie profilowe tutaj…", - "users.avatar.click": "…lub kliknij, aby załadować", - "users.avatar.error.type": "Możesz wgrać tylko pliki JPG, PNG i GIF", - "users.avatar.error.folder.headline": "Folder avatar nie ma praw do zapisu", - "users.avatar.error.folder.text": "Utwórz folder /assets/avatars i nadaj mu prawa do zapisu, by móc dodawać zdjęcia profilowe.", - "users.avatar.error.permission": "Nie masz uprawnień, aby zmienić awatar", - "users.avatar.delete.error": "Zdjęcie profilowe nie mogło zostać usunięte", - "users.avatar.delete.error.permission": "Nie masz uprawnień, aby usunąć awatar użytkownika", - "users.avatar.delete.success": "Zdjęcie profilowe zostało usunięte", - "users.avatar.missing": "Ten użytkownik nie ma awataru", - "users.error.missing": "Użytkownik nie został odnaleziony", - "user.error.lastadmin": "Jesteś jedynym administratorem. To ustawienie nie może zostać zmienione.", - "form.error.missing": "Formularz nie może zostać odnaleziony", - "form.construct.error.invalid": "Nieprawidłowa metoda budowy formularza", - "fields.required": "Wymagane", - "fields.date.label": "Data", - "fields.date.months": [ - "Styczeń", - "Luty", - "Marzec", - "Kwiecień", - "Maj", - "Czerwiec", - "Lipiec", - "Sierpień", - "Wrzesień", - "Październik", - "Listopad", - "Grudzień" - ], - "fields.date.weekdays": [ - "Niedziela", - "Poniedziałek", - "Wtorek", - "Środa", - "Czwartek", - "Piątek", - "Sobota" - ], - "fields.date.weekdays.short": [ - "Nd", - "Pn", - "Wt", - "Śr", - "Czw", - "Pt", - "Sb" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@example.com", - "fields.number.label": "Numer", - "fields.number.placeholder": "nr", - "fields.page.label": "Strona", - "fields.page.placeholder": "ścieżka/do/strony", - "fields.password.label": "Hasło", - "fields.structure.add": "Dodaj", - "fields.structure.add.first": "Dodaj pierwszy wpis", - "fields.structure.empty": "Nie ma jeszcze żadnych wpisów.", - "fields.structure.entry.error": "Element nie mógł zostać odnaleziony", - "fields.structure.cancel": "Anuluj", - "fields.structure.save": "Zapisz", - "fields.structure.edit": "Edytuj", - "fields.structure.delete": "Usuń", - "fields.structure.delete.label": "Czy na pewno chcesz usunąć ten wpis?", - "fields.tags.label": "Tagi", - "fields.tel.label": "Telefon", - "fields.textarea.buttons.bold.label": "Pogrubiony tekst", - "fields.textarea.buttons.bold.text": "Pogrubiony tekst", - "fields.textarea.buttons.italic.label": "Kursywa", - "fields.textarea.buttons.italic.text": "Kursywa", - "fields.textarea.buttons.link.label": "Link", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Obrazek", - "fields.textarea.buttons.file.label": "Plik", - "fields.toggle.yes": "Tak", - "fields.toggle.no": "Nie", - "fields.toggle.on": "Włącz", - "fields.toggle.off": "Wyłącz", - "fields.error.missing.controller": "Brak pliku field controller", - "fields.error.missing.class": "Brak klasy field controller", - "fields.error.route.invalid": "Invalid field route", - "fields.error.extended": "Pole nie może zostać rozszerzone", - "editor.link.url.label": "Wstaw URL", - "editor.link.text.label": "Tekst linku", - "editor.link.text.help": "Tekst linku jest opcjonalny", - "editor.email.address.label": "Wstaw adres email", - "editor.email.address.placeholder": "mail@example.com", - "editor.email.text.label": "Tekst linku", - "editor.email.text.help": "Tekst linku jest opcjonalny", - "editor.file.empty": "Ta strona nie ma plików", - "editor.image.empty": "Ta strona nie ma obrazków", - "autocomplete.method.error": "Nieprawidłowa metoda autouzupełniania", - "blueprints.error.default.missing": "Brak domyślnego szablonu", - "error": "Błąd", - "error.headline": "Błąd" -} \ No newline at end of file diff --git a/panel/app/translations/pl/package.json b/panel/app/translations/pl/package.json deleted file mode 100644 index d30e51f..0000000 --- a/panel/app/translations/pl/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Polski", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/pt_BR/core.json b/panel/app/translations/pt_BR/core.json deleted file mode 100644 index e674f45..0000000 --- a/panel/app/translations/pt_BR/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Cancelar", - "add": "Adicionar", - "addit": "Adicionar & Editar", - "save": "Salvar", - "saved": "Salvo!", - "change": "Alterar", - "delete": "Deletar", - "insert": "Inserir", - "ok": "Ok", - "routes.error.invalid": "URL do Painel inválida", - "controller.error.invalid": "Controller inválido", - "controller.error.action": "Ação inválida", - "view.error.invalid": "View inválida: ", - "options.show": "Exibir opções", - "options.hide": "Ocultar opções", - "installation": "Instalação", - "installation.check.headline": "Instalação do Painel Kirby", - "installation.check.text": "Kirby encontrou os seguintes problemas durante a instalação…", - "installation.check.retry": "Tentar novamente", - "installation.check.error": "Temos problemas!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts não tem permissão de escrita", - "installation.check.error.avatars": "/assets/avatars não tem permissão de escrita", - "installation.check.error.blueprints": "Por favor, adicione uma pasta /site/blueprints", - "installation.check.error.content": "A pasta \"content\" e todas subpastas e arquivos devem ter permissão de escrita.", - "installation.check.error.thumbs": "A pasta \"thumbs\" deve ter permissão de escrita.", - "installation.signup.username.label": "Crie sua primeira conta", - "installation.signup.username.placeholder": "Usuário", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@exemplo.com", - "installation.signup.password.label": "Senha", - "installation.signup.language.label": "Idioma", - "installation.signup.button": "Crie sua conta", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Usuário", - "login.password.label": "Senha", - "login.error": "Usuário ou senha inválido", - "login.button": "Log in", - "login.log.error.permissions": "O arquivo de log do login não tem permissão de escrita ", - "logout": "Log out", - "topbar.error.class.definition": "Definição \"topbar\" não existe para classe: ", - "dashboard": "Painel", - "dashboard.index.pages.title": "Páginas", - "dashboard.index.pages.edit": "Editar", - "dashboard.index.pages.add": "Adicionar", - "dashboard.index.site.title": "URL do seu site", - "dashboard.index.account.title": "Sua conta", - "dashboard.index.account.edit": "Editar", - "dashboard.index.metatags.title": "Variáveis do site", - "dashboard.index.metatags.edit": "Editar", - "dashboard.index.history.title": "Atualizações recentes", - "dashboard.index.history.text": "Últimas páginas modificadas serão exibidas aquí para facilitar seu acesso futuro.", - "dashboard.index.license.title": "Licença do Kirby", - "dashboard.index.license.text": "Parece que você está rodando o Kirby em um servidor público sem uma licença válida!\n\nPor favor, apoie o Kirby (link: {buy} text: comprando uma licença agora)\n\nCaso possua uma licença, basta adiciona-la ao seu arquivo config: (link: {docs} text: site/config/config.php)", - "metatags": "Variáveis do site", - "metatags.info": "Informações do Kirby", - "metatags.license": "Licença do Kirby ", - "metatags.version.toolkit": "Versão do Toolkit", - "metatags.version.kirby": "Versão do Kirby", - "metatags.version.panel": "Versão do Painel", - "metatags.back": "Voltar ao Painel", - "metatags.files": "Arquivos do site", - "site.delete.error": "Este site não pode ser deletado", - "pages.show.settings": "Configurações de página", - "pages.show.preview": "Abrir preview", - "pages.show.template": "Template", - "pages.show.changeurl": "Mudar URL", - "pages.show.invisible": "Status: invisível", - "pages.show.visible": "Status: visível", - "pages.show.changes.text": "Você possui alterações não salvas!", - "pages.show.changes.button": "Descartar", - "pages.show.delete": "Deletar esta página", - "pages.show.subpages.title": "Páginas", - "pages.show.subpages.edit": "Editar", - "pages.show.subpages.add": "Adicionar", - "pages.show.subpages.empty": "Esta página não contém subpáginas", - "pages.show.files.title": "Arquivos", - "pages.show.files.edit": "Editar", - "pages.show.files.add": "Adicionar", - "pages.show.files.empty": "Esta página não contém arquivos", - "pages.show.error.permissions.title": "Esta página não tem permissão de escrita", - "pages.show.error.permissions.text": "Favor conferir as permissões da pasta \"content\" e todos seus arquivos", - "pages.show.error.permissions.retry": "Tentar novamente", - "pages.show.error.notitle.title": "O blueprint não possui um campo \"title\"", - "pages.show.error.notitle.text": "Favor adicionar um campo \"title\" e tentar novamente", - "pages.show.error.notitle.retry": "Tentar novamente", - "pages.show.error.form": "Favor preencher todos campos corretamente", - "pages.add.title.label": "Adicionar página", - "pages.add.title.placeholder": "Título", - "pages.add.url.label": "URL-apêndice", - "pages.add.url.enter": "(digite um título)", - "pages.add.url.close": "Fechar", - "pages.add.url.help": "Formato: a-z minúsculas, 0-9 e hífens", - "pages.add.template.label": "Template", - "pages.add.error.create": "A página não pode ser criada", - "pages.add.error.title": "Falta o título", - "pages.add.error.template": "Falta o template", - "pages.add.error.max.headline": "Não se permite novas páginas", - "pages.add.error.max.text": "Número máximo de subpáginas para a página atual foi atingido.", - "pages.url.uid.label": "URL-apêndice", - "pages.url.uid.label.option": "Criar a partir do título", - "pages.url.error.exists": "Uma página com mesmo apêndice já existe", - "pages.url.error.move": "O apêndice não pôde ser alterado", - "pages.url.error.rights": "Você não pode alterar a URL desta página", - "pages.template.select.label": "Template", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Posição", - "pages.toggle.invisible": "Invisível", - "pages.toggle.publish": "Quer mesmo mudar o status desta página para **visível?**", - "pages.toggle.hide": "Quer mesmo mudar o status desta página para **invisível?**", - "pages.toggle.error.error": "O status da página de erro não pode ser alterado", - "pages.delete.headline": "Quer mesmo deletar esta página?", - "pages.delete.error.home.headline": "A página \"home\" não pode ser deletada", - "pages.delete.error.home.text": "Você está tentando deletar a página \"home\". O que não é possível e podería causar efeitos indesejados.", - "pages.delete.error.error.headline": "A página \"error\" não pode ser deletada", - "pages.delete.error.error.text": "Você está tentando deletar a página \"error\". O que não é possível e podería causar efeitos indesejados.", - "pages.delete.error.children.headline": "A página não pode ser deletada", - "pages.delete.error.children.text": "Esta página contém subpáginas e não pode ser deletada. Favor deletar todas subpáginas antes.", - "pages.delete.error.blocked.headline": "A página não pode ser deletada", - "pages.delete.error.blocked.text": "A página está bloqueada e não pode ser deletada.", - "pages.search.help": "Procurar páginas por URL. Navegue pelos resultados usando as teclas \"acima\" e \"abaixo\" e pressione \"enter\" para saltar à página selecionada.", - "pages.search.noresults": "Busca sem resultados. Favor tentar novamente com outra URL.", - "pages.error.missing": "Página não encontrada", - "subpages": "Páginas", - "subpages.index.headline": "Páginas em", - "subpages.index.back": "Voltar", - "subpages.index.add": "Adicionar nova página", - "subpages.index.add.first.text": "Página ainda sem subpáginas", - "subpages.index.add.first.button": "Adicione a primeira página", - "subpages.index.visible": "Páginas visíveis", - "subpages.index.visible.help": "Arraste as páginas invisíveis aquí para ordenar/torna-las visíveis.", - "subpages.index.invisible": "Páginas invisíveis", - "subpages.index.invisible.help": "Arraste as páginas visíveis aquí para desordenar/torna-las invisíveis", - "subpages.add.error": "Esta página não pode ter sub-páginas ", - "subpages.add.error.more": "Esta página não pode ter mais sub-páginas ", - "subpages.error.missing": "Página não encontrada", - "files": "Arquivos", - "files.index.headline": "Arquivos para", - "files.index.back": "Voltar", - "files.index.upload": "Subir novo arquivo", - "files.index.upload.first.text": "Página ainda sem arquivos", - "files.index.upload.first.button": "Suba o primeiro arquivo", - "files.index.edit": "Editar", - "files.index.delete": "Deletar", - "files.index.error.disabled": "Esta página não pode ter nenhum arquivo", - "files.add.error.max": "O numero máximo de arquivos desta página foi atingido.", - "files.add.error.extension.missing": "Você não pode subir arquivos sem extensão ", - "files.add.error.extension.forbidden": "Extensão de arquivo não permitida", - "files.add.error.mime.forbidden": "\"mime type\" não permitido", - "files.add.error.htaccess": "Arquivos \"htaccess\" não podem ser subidos", - "files.add.error.invisible": "Arquivos invisíveis não podem ser subidos", - "files.add.blueprint.type.error": "Esta página permite apenas: ", - "files.add.blueprint.size.error": "Esta página permite arquivos com tamanho de ", - "files.show.name.label": "Nome do arquivo", - "files.show.info.label": "Tipo / Tamanho / Dimensões", - "files.show.link.label": "Link público", - "files.show.open": "Exibir/baixar arquivo", - "files.show.back": "Voltar", - "files.show.replace": "Substituir", - "files.show.delete": "Deletar", - "files.show.error.rename": "O arquivo não pode ser renomeado", - "files.show.error.form": "Favor preencher todos campos corretamente", - "files.upload.drop": "Arraste os arquivos aquí…", - "files.upload.click": "…ou clique para subir", - "files.replace.drop": "Arraste o arquivo aquí…", - "files.replace.click": "…ou clique para substituir", - "files.replace.error.type": "O arquivo subido deve ser do mesmo tipo", - "files.delete.headline": "Quer mesmo deletar este arquivo?", - "files.error.missing.page": "Página não encontrada", - "files.error.missing.file": "Arquivo não encontrado", - "users": "Usuários", - "users.index.headline": "Todos usuários", - "users.index.add": "Adicionar novo usuário", - "users.index.edit": "Editar", - "users.index.delete": "Deletar", - "users.form.username.label": "Usuário", - "users.form.username.placeholder": "Seu nome de usuário", - "users.form.username.help": "Caracteres permitidos: a-z mininúsculas, 0-9 e hífens", - "users.form.username.readonly": "O nome de usuário nao pode ser alterado", - "users.form.firstname.label": "Primeiro nome", - "users.form.lastname.label": "Último nome", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@exemplo.com", - "users.form.password.label": "Senha", - "users.form.password.confirm.label": "Confimar senha", - "users.form.password.new.label": "Nova senha", - "users.form.password.new.confirm.label": "Confirmar nova senha", - "users.form.password.new.help": "Deixe em branco para manter a senha atual", - "users.form.language.label": "Idioma", - "users.form.role.label": "Papel", - "users.form.options.headline": "Opções de conta", - "users.form.options.message": "Enviar email", - "users.form.options.delete": "Deletar conta", - "users.form.avatar.headline": "Foto do perfil", - "users.form.avatar.upload": "Subir foto do perfil", - "users.form.avatar.replace": "Substituir foto do perfil", - "users.form.avatar.delete": "Deletar foto do perfil", - "users.form.back": "Voltar para usuários", - "users.form.error.password.confirm": "Favor confirmar a senha", - "users.form.error.update": "O usuário não pode ser atualizado", - "users.form.error.update.rights": "Você não tem permissão para atualizar este usuário", - "users.form.error.create": "O usuário não pode ser criado", - "users.form.error.permissions.title": "A pasta \"account\" não tem permissão de escrita", - "users.form.error.permissions.text": "Favor se certificar que /site/accounts existe e possui permissão de escrita.", - "users.delete.headline": "Quer mesmo deletar este usuário?", - "users.delete.error": "Este usuário nao pode ser deletado", - "users.delete.error.permission": "Você não tem permissão para deletar usuários", - "users.delete.error.permission.single": "Você não tem permissão para deletar este usuário ", - "users.delete.error.lastadmin": "Você não pode deletar o último usuário administrador ", - "users.avatar.drop": "Arraste a foto do perfil aquí…", - "users.avatar.click": "…ou clique para subir", - "users.avatar.error.type": "Você pode subir somente arquivos JPG, PNG and GIF", - "users.avatar.error.folder.headline": "A pasta \"avatar\" não tem permissão de escrita", - "users.avatar.error.folder.text": "Favor criar a pasta /assets/avatars e permita que seja escrita para subir fotos do perfil.", - "users.avatar.error.permission": "Você não pode alterar o avatar", - "users.avatar.delete.error": "A foto do perfil não pode ser deletada", - "users.avatar.delete.error.permission": "Você não tem permissão para deletar o avatar deste usuário", - "users.avatar.delete.success": "A foto do perfil foi deletada", - "users.avatar.missing": "Este usuário não possui avatar", - "users.error.missing": "Usuário não encontrado", - "user.error.lastadmin": "Você é o único administrador. Isto não pode ser alterado.", - "form.error.missing": "O formulário não foi encontrado ", - "form.construct.error.invalid": "Método inválido de construção de formulário ", - "fields.required": "Requerido", - "fields.date.label": "Data", - "fields.date.months": [ - "Janeiro", - "Fevereiro", - "Março", - "Abril", - "Maio", - "Junho", - "Julho", - "Agosto", - "Setembro", - "Outubro", - "Novembro", - "Dezembro" - ], - "fields.date.weekdays": [ - "Domingo", - "Segunda", - "Terça", - "Quarta", - "Quinta", - "Sexta", - "Sábado" - ], - "fields.date.weekdays.short": [ - "Dom", - "Seg", - "Ter", - "Qua", - "Qui", - "Sex", - "Sáb" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@exemplo.com", - "fields.number.label": "Número", - "fields.number.placeholder": "#", - "fields.page.label": "Página", - "fields.page.placeholder": "caminho/da/pagina", - "fields.password.label": "Senha", - "fields.structure.add": "Adicionar", - "fields.structure.add.first": "Adicionar primeira entrada", - "fields.structure.empty": "Sem entradas ainda.", - "fields.structure.entry.error": "Item não encontrado ", - "fields.structure.cancel": "Cancelar", - "fields.structure.save": "Salvar", - "fields.structure.edit": "Editar", - "fields.structure.delete": "Deletar", - "fields.structure.delete.label": "Quer mesmo deletar esta entrada?", - "fields.tags.label": "Tags", - "fields.tel.label": "Fone", - "fields.textarea.buttons.bold.label": "Texto negrito", - "fields.textarea.buttons.bold.text": "Texto negrito", - "fields.textarea.buttons.italic.label": "Texto itálico", - "fields.textarea.buttons.italic.text": "Texto itálico", - "fields.textarea.buttons.link.label": "Link", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Imagem", - "fields.textarea.buttons.file.label": "Arquivo", - "fields.toggle.yes": "Sim", - "fields.toggle.no": "Não", - "fields.toggle.on": "Ligado", - "fields.toggle.off": "Desligado", - "fields.error.missing.controller": "O arquivo do \"field controller\" não foi encontrado ", - "fields.error.missing.class": "A classe do \"field controller\" não foi encontrada ", - "fields.error.route.invalid": "\"field route\" inválida ", - "fields.error.extended": "O \"field\" não pode ser extendido ", - "editor.link.url.label": "Inserir URL", - "editor.link.text.label": "Texto do link", - "editor.link.text.help": "O texto do link é opcional", - "editor.email.address.label": "Inserir endereço de email", - "editor.email.address.placeholder": "mail@exemplo.com", - "editor.email.text.label": "Texto do link", - "editor.email.text.help": "O texto do link é opcional", - "editor.file.empty": "Esta página não tem arquivos", - "editor.image.empty": "Esta página não tem imagens", - "autocomplete.method.error": "Método de auto-completar inválido", - "blueprints.error.default.missing": "Blueprint \"default\" não encontrada ", - "error": "Erro", - "error.headline": "Erro" -} \ No newline at end of file diff --git a/panel/app/translations/pt_BR/package.json b/panel/app/translations/pt_BR/package.json deleted file mode 100644 index 885ba0c..0000000 --- a/panel/app/translations/pt_BR/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Português (Brasileiro)‎", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/pt_PT/core.json b/panel/app/translations/pt_PT/core.json deleted file mode 100644 index 891471d..0000000 --- a/panel/app/translations/pt_PT/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Cancelar", - "add": "Adicionar", - "addit": "Adicionar e editar", - "save": "Gravar", - "saved": "Gravado!", - "change": "Mudar", - "delete": "Apagar", - "insert": "Inserir", - "ok": "Ok", - "routes.error.invalid": "URL de panel inválida", - "controller.error.invalid": "Controlador inválido", - "controller.error.action": "Ação inválida", - "view.error.invalid": "Vista inválida:", - "options.show": "Exibir opções", - "options.hide": "Ocultar opções", - "installation": "Instalação", - "installation.check.headline": "Instalação do Painel Kirby", - "installation.check.text": "Kirby encontrou os seguintes problemas durante a instalação…", - "installation.check.retry": "Tenta novamente", - "installation.check.error": "Temos problemas!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts não tem permissão de escrita", - "installation.check.error.avatars": "/assets/avatars não tem permissão de escrita", - "installation.check.error.blueprints": "Por favor, adiciona uma pasta /site/blueprints", - "installation.check.error.content": "A pasta \"content\" e todas as subpastas e ficheiros devem ter permissão de escrita.", - "installation.check.error.thumbs": "A pasta \"thumbs\" deve ter permissão de escrita.", - "installation.signup.username.label": "Cria a tua primeira conta", - "installation.signup.username.placeholder": "Utilizador", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@exemplo.com", - "installation.signup.password.label": "Palavra-passe", - "installation.signup.language.label": "Idioma", - "installation.signup.button": "Cria a tua conta", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Utilizador", - "login.password.label": "Palavra-passe", - "login.error": "Utilizador ou Palavra-passe inválida", - "login.button": "Log in", - "login.log.error.permissions": "Ficheiro de log do login não é descritível.", - "logout": "Log out", - "topbar.error.class.definition": "Falta a definição topbar da classe:", - "dashboard": "Painel", - "dashboard.index.pages.title": "Páginas", - "dashboard.index.pages.edit": "Editar", - "dashboard.index.pages.add": "Adicionar", - "dashboard.index.site.title": "URL do teu site", - "dashboard.index.account.title": "A tua conta", - "dashboard.index.account.edit": "Editar", - "dashboard.index.metatags.title": "Variáveis do site", - "dashboard.index.metatags.edit": "Editar", - "dashboard.index.history.title": "Atualizações recentes", - "dashboard.index.history.text": "As últimas páginas modificadas por ti serão exibidas aqui para facilitar a sua consulta no futuro.", - "dashboard.index.license.title": "Licença Kirby", - "dashboard.index.license.text": "Aparentemente estas a executar Kirby num servidor público sem licença válida!\n\nPor favor apoia Kirby e (link: {compra} text: adquira agóra uma licença)\n\nSe já adquiriste uma licença, simplesmente adiciona-a ao teu ficheiro de configuração: (link: {docs} text: site/config/config.php)", - "metatags": "Variáveis do site", - "metatags.info": "Informação Kirby", - "metatags.license": "Licença Kirby", - "metatags.version.toolkit": "Versão toolkit", - "metatags.version.kirby": "Versão Kirby", - "metatags.version.panel": "Versão panel", - "metatags.back": "Voltar ao Painel", - "metatags.files": "Ficheiros do site", - "site.delete.error": "A site não pode ser apagada", - "pages.show.settings": "Configurações de página", - "pages.show.preview": "Abrir preview", - "pages.show.template": "Template", - "pages.show.changeurl": "Mudar URL", - "pages.show.invisible": "Estatuto: invisível", - "pages.show.visible": "Estatuto: visível", - "pages.show.changes.text": "Tens alteraçoes ainda não gravadas!", - "pages.show.changes.button": "Descartar", - "pages.show.delete": "Apagar esta página", - "pages.show.subpages.title": "Páginas", - "pages.show.subpages.edit": "Editar", - "pages.show.subpages.add": "Adicionar", - "pages.show.subpages.empty": "Esta página não contém subpáginas", - "pages.show.files.title": "Ficheiros", - "pages.show.files.edit": "Editar", - "pages.show.files.add": "Adicionar", - "pages.show.files.empty": "Esta página não contém ficheiros", - "pages.show.error.permissions.title": "Esta página não tem permissão de escrita", - "pages.show.error.permissions.text": "Por favor confere as permissões da pasta \"content\" e todos seus ficheiros", - "pages.show.error.permissions.retry": "Tentar novamente", - "pages.show.error.notitle.title": "O blueprint não possui um campo \"title\"", - "pages.show.error.notitle.text": "Por favor adiciona um campo \"title\" e tenta novamente", - "pages.show.error.notitle.retry": "Tenta novamente", - "pages.show.error.form": "Por favor preenche todos os campos corretamente", - "pages.add.title.label": "Adicionar página", - "pages.add.title.placeholder": "Título", - "pages.add.url.label": "URL-apêndice", - "pages.add.url.enter": "(introduz um título)", - "pages.add.url.close": "Fechar", - "pages.add.url.help": "Formato: a-z minúsculas, 0-9 e hífens", - "pages.add.template.label": "Template", - "pages.add.error.create": "Não foi possível criar a página", - "pages.add.error.title": "Falta o título", - "pages.add.error.template": "Falta o template", - "pages.add.error.max.headline": "Não são permitidas novas páginas", - "pages.add.error.max.text": "Número máximo de subpáginas para a página atual foi atingido.", - "pages.url.uid.label": "URL-apêndice", - "pages.url.uid.label.option": "Criar a partir do título", - "pages.url.error.exists": "Já existe uma página com mesmo apêndice", - "pages.url.error.move": "O apêndice não pôde ser alterado", - "pages.url.error.rights": "Não é possível mudar o URL desta página", - "pages.template.select.label": "Template", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Posição", - "pages.toggle.invisible": "Invisível", - "pages.toggle.publish": "Queres mesmo alterar o estatuto desta página para **visível**?", - "pages.toggle.hide": "Queres mesmo alterar o estatuto desta página para **invisível**?", - "pages.toggle.error.error": "O estatuto da pagina erro não pode ser alterado", - "pages.delete.headline": "Queres mesmo apagar esta página?", - "pages.delete.error.home.headline": "A página \"home\" não pode ser apagada", - "pages.delete.error.home.text": "Estás a tentar apagar a página \"home\". O que não é possível e poderia causar efeitos indesejados.", - "pages.delete.error.error.headline": "A página \"error\" não pode ser apagada", - "pages.delete.error.error.text": "Estás a tentar apagar a página \"error\". O que não é possível e poderia causar efeitos indesejados.", - "pages.delete.error.children.headline": "A página não pode ser apagada", - "pages.delete.error.children.text": "Esta página contém subpáginas e não pode ser apagada. Por favor apaga todas as subpáginas antes.", - "pages.delete.error.blocked.headline": "A página não pode ser apagada", - "pages.delete.error.blocked.text": "A página está bloqueada e não pode ser apagada.", - "pages.search.help": "Procurar páginas por URL. Navega pelos resultados usando as teclas \"cima\" e \"baixo\" e pressiona \"enter\" para saltar para a página selecionada.", - "pages.search.noresults": "Pesquisa sem resultados. Por favor tenta novamente com outra URL.", - "pages.error.missing": "Página não encontrada", - "subpages": "Páginas", - "subpages.index.headline": "Páginas em", - "subpages.index.back": "Voltar", - "subpages.index.add": "Adicionar nova página", - "subpages.index.add.first.text": "Página ainda sem subpáginas", - "subpages.index.add.first.button": "Adiciona a primeira página", - "subpages.index.visible": "Páginas visíveis", - "subpages.index.visible.help": "Arrasta as páginas invisíveis aqui para ordenar/torna-las visíveis.", - "subpages.index.invisible": "Páginas invisíveis", - "subpages.index.invisible.help": "Arrasta as páginas visíveis aqui para desordenar/torna-las invisíveis", - "subpages.add.error": "Página sem permissão de ter paginas inferiores", - "subpages.add.error.more": "Esta página não pode ter mais paginas inferiores", - "subpages.error.missing": "Página não encontrada", - "files": "Ficheiros", - "files.index.headline": "Ficheiros para", - "files.index.back": "Voltar", - "files.index.upload": "Faz upload dum novo ficheiro", - "files.index.upload.first.text": "Página ainda sem ficheiros", - "files.index.upload.first.button": "Faz upload do primeiro ficheiro", - "files.index.edit": "Editar", - "files.index.delete": "Apagar", - "files.index.error.disabled": "Página sem permissão de ter ficheiros", - "files.add.error.max": "O máximo de ficheiros foi atingido para esta página.", - "files.add.error.extension.missing": "Não podes fazer upload sem extensão", - "files.add.error.extension.forbidden": "Extensão proibida", - "files.add.error.mime.forbidden": "Tipo mime proibido", - "files.add.error.htaccess": "Não se pode fazer upload de ficheiros htaccess", - "files.add.error.invisible": "Não se pode fazer upload de ficheiros invisíveis", - "files.add.blueprint.type.error": "Pagina apenas permite:", - "files.add.blueprint.size.error": "A pagina apenas permite tamanho de", - "files.show.name.label": "Nome do ficheiro", - "files.show.info.label": "Tipo / Tamanho / Dimensões", - "files.show.link.label": "Link público", - "files.show.open": "Exibir/Download ficheiro", - "files.show.back": "Voltar", - "files.show.replace": "Substituir", - "files.show.delete": "Apagar", - "files.show.error.rename": "O ficheiro não pode ser renomeado", - "files.show.error.form": "Por favor preenche os todos campos corretamente", - "files.upload.drop": "Arrasta os ficheiros para aqui…", - "files.upload.click": "…ou clica para fazer upload", - "files.replace.drop": "Arrasta o ficheiros para aqui…", - "files.replace.click": "…ou clica para substituir", - "files.replace.error.type": "O ficheiro que fizeste upload deve ser do mesmo tipo", - "files.delete.headline": "Queres mesmo apagar este ficheiro?", - "files.error.missing.page": "Página não encontrada", - "files.error.missing.file": "Ficheiro não encontrado", - "users": "Utilizadores", - "users.index.headline": "Todos os utilizadores", - "users.index.add": "Adicionar novo utilizador", - "users.index.edit": "Editar", - "users.index.delete": "Apagar", - "users.form.username.label": "Utilizador", - "users.form.username.placeholder": "Nome do utilizador", - "users.form.username.help": "Caracteres permitidos: a-z mininúsculas, 0-9 e hífens", - "users.form.username.readonly": "O nome de utilizador nao pode ser alterado", - "users.form.firstname.label": "Primeiro nome", - "users.form.lastname.label": "Último nome", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@exemplo.com", - "users.form.password.label": "Palavra-passe", - "users.form.password.confirm.label": "Confima a Palavra-passe", - "users.form.password.new.label": "Nova Palavra-passe", - "users.form.password.new.confirm.label": "Confirma a nova Palavra-passe", - "users.form.password.new.help": "Deixa em branco para manter a Palavra-passe atual", - "users.form.language.label": "Idioma", - "users.form.role.label": "Role", - "users.form.options.headline": "Opções de conta", - "users.form.options.message": "Enviar email", - "users.form.options.delete": "Apagar conta", - "users.form.avatar.headline": "Foto do perfil", - "users.form.avatar.upload": "Upload foto do perfil", - "users.form.avatar.replace": "Substituir foto do perfil", - "users.form.avatar.delete": "Apagar foto do perfil", - "users.form.back": "Voltar para utilizadores", - "users.form.error.password.confirm": "Por favor confirmar a Palavra-passe", - "users.form.error.update": "O utilizador não pode ser atualizado", - "users.form.error.update.rights": "Sem autorização para fazeres update a este utilizador", - "users.form.error.create": "O utilizador não pode ser criado", - "users.form.error.permissions.title": "O folder \"account\" não tem permissão de escrita", - "users.form.error.permissions.text": "Por favor certifica-te que /site/accounts existe e possui permissão de escrita.", - "users.delete.headline": "Queres mesmo apagar este utilizador?", - "users.delete.error": "Este utilizador nao pode ser apagado", - "users.delete.error.permission": "Não tens autorização para apagar utilizadores", - "users.delete.error.permission.single": "Não tens autorização para apagar este utilizador", - "users.delete.error.lastadmin": "Não é possivel apagar o ultimo admin", - "users.avatar.drop": "Arrasta a foto do perfil aqui…", - "users.avatar.click": "…ou clica para fazer upload", - "users.avatar.error.type": "Apenas podes fazer upload de ficheiros JPG, PNG and GIF", - "users.avatar.error.folder.headline": "O folder \"avatar\" não tem permissão de escrita", - "users.avatar.error.folder.text": "Por favor cria o folder /assets/avatars e garante que tem permissão de escrita para poder fazer upload de fotos de perfil.", - "users.avatar.error.permission": "Não tens autorização para mudar o avatar", - "users.avatar.delete.error": "A foto do perfil não pode ser apagada", - "users.avatar.delete.error.permission": "Não tens autorização para apagar o avatar deste utilizador", - "users.avatar.delete.success": "A foto do perfil foi apagada", - "users.avatar.missing": "Este utilizador não tem avatar", - "users.error.missing": "Utilizador não encontrado", - "user.error.lastadmin": "Só es admin. Isto não pode ser mudado.", - "form.error.missing": "Não foi possível encontrar o formulário", - "form.construct.error.invalid": "Método inválido de construção do formulário", - "fields.required": "Obrigatório", - "fields.date.label": "Data", - "fields.date.months": [ - "Janeiro", - "Fevereiro", - "Março", - "Abril", - "Maio", - "Junho", - "Julho", - "Agosto", - "Setembro", - "Outubro", - "Novembro", - "Dezembro" - ], - "fields.date.weekdays": [ - "Domingo", - "Segunda", - "Terça", - "Quarta", - "Quinta", - "Sexta", - "Sábado" - ], - "fields.date.weekdays.short": [ - "Dom", - "Seg", - "Ter", - "Qua", - "Qui", - "Sex", - "Sáb" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@exemplo.com", - "fields.number.label": "Número", - "fields.number.placeholder": "#", - "fields.page.label": "Página", - "fields.page.placeholder": "caminho/da/pagina", - "fields.password.label": "Palavra-passe", - "fields.structure.add": "Adicionar", - "fields.structure.add.first": "Adicionar primeira entrada", - "fields.structure.empty": "Sem entradas ainda.", - "fields.structure.entry.error": "O item não foi encontrado", - "fields.structure.cancel": "Cancelar", - "fields.structure.save": "Gravar", - "fields.structure.edit": "Editar", - "fields.structure.delete": "Apagar", - "fields.structure.delete.label": "Queres mesmo apagar esta entrada?", - "fields.tags.label": "Tags", - "fields.tel.label": "Fone", - "fields.textarea.buttons.bold.label": "Texto negrito", - "fields.textarea.buttons.bold.text": "Texto negrito", - "fields.textarea.buttons.italic.label": "Texto itálico", - "fields.textarea.buttons.italic.text": "Texto itálico", - "fields.textarea.buttons.link.label": "Link", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Imagem", - "fields.textarea.buttons.file.label": "Ficheiro", - "fields.toggle.yes": "Sim", - "fields.toggle.no": "Não", - "fields.toggle.on": "Ligado", - "fields.toggle.off": "Desligado", - "fields.error.missing.controller": "Falta o ficheiro do controlador de campo ", - "fields.error.missing.class": "Falta a classe do controlador de campo", - "fields.error.route.invalid": "Rota de campo inválida", - "fields.error.extended": "Não é possível extender o campo", - "editor.link.url.label": "Inserir URL", - "editor.link.text.label": "Texto do link", - "editor.link.text.help": "O texto do link é opcional", - "editor.email.address.label": "Inserir endereço de email", - "editor.email.address.placeholder": "mail@exemplo.com", - "editor.email.text.label": "Texto do link", - "editor.email.text.help": "O texto do link é opcional", - "editor.file.empty": "Esta página não tem ficheiros", - "editor.image.empty": "Esta página não tem imagens", - "autocomplete.method.error": "Método inválido de auto-contemplação", - "blueprints.error.default.missing": "Falta do blueprint padrão", - "error": "Erro", - "error.headline": "Erro" -} \ No newline at end of file diff --git a/panel/app/translations/pt_PT/package.json b/panel/app/translations/pt_PT/package.json deleted file mode 100644 index 733fd36..0000000 --- a/panel/app/translations/pt_PT/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Português (Portugal)", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/ro/core.json b/panel/app/translations/ro/core.json deleted file mode 100644 index f783c75..0000000 --- a/panel/app/translations/ro/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Renunţă", - "add": "Adaugă", - "addit": "Add & Edit", - "save": "Salvează", - "saved": "Salvat!", - "change": "Modifică", - "delete": "Şterge", - "insert": "Inserează", - "ok": "Ok", - "routes.error.invalid": "Invalid Panel URL", - "controller.error.invalid": "Invalid controller", - "controller.error.action": "Invalid action", - "view.error.invalid": "Invalid view:", - "options.show": "Arată opţiunile", - "options.hide": "Ascunde opţiunile", - "installation": "Instalare", - "installation.check.headline": "Instalarea panoului de administrare", - "installation.check.text": "Sistemul a întâmpinat următoarele probleme în timpul instalării:", - "installation.check.retry": "Ignoră", - "installation.check.error": "Sunt câteva probleme!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "Directorul /site/accounts nu are permisiuni de scriere.", - "installation.check.error.avatars": "Directorul /assets/avatars nu are permisiuni de scriere.", - "installation.check.error.blueprints": "Creează te rog directorul /site/blueprints!", - "installation.check.error.content": "Directorul /content şi conţinutul lui trebuie să aibă permisiuni de scriere.", - "installation.check.error.thumbs": "Directorul /thumbs trebuie să aibă permisiuni de scriere.", - "installation.signup.username.label": "Creează primul cont de utilizator!", - "installation.signup.username.placeholder": "Nume utilizator", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "email@exemplu.com", - "installation.signup.password.label": "Parola", - "installation.signup.language.label": "Limba", - "installation.signup.button": "Creează contul", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Nume utilizator", - "login.password.label": "Parola", - "login.error": "Nume de utilizator greşit, sau parolă invalidă.", - "login.button": "Log in", - "login.log.error.permissions": "Login log file is not writable.", - "logout": "Log out", - "topbar.error.class.definition": "Missing topbar definition for class:", - "dashboard": "Panoul de control", - "dashboard.index.pages.title": "Pagini", - "dashboard.index.pages.edit": "Editează", - "dashboard.index.pages.add": "Adaugă", - "dashboard.index.site.title": "Adresa URL a saitului", - "dashboard.index.account.title": "Contul tău", - "dashboard.index.account.edit": "Editează", - "dashboard.index.metatags.title": "Variabile sait", - "dashboard.index.metatags.edit": "Editează", - "dashboard.index.history.title": "Ultimele pagini modificate", - "dashboard.index.history.text": "Paginile modificate recent vor fi afişate aici pentru a putea fi găsite uşor mai târziu.", - "dashboard.index.license.title": "Licenţa Kirby", - "dashboard.index.license.text": "It seems you are running Kirby on a public server without a valid license!\n\nPlease, support Kirby and (link: {buy} text: buy a license now)\n\nIf you already have a license key, just add it to your config file: (link: {docs} text: site/config/config.php)", - "metatags": "Variabile sait", - "metatags.info": "Info Kirby", - "metatags.license": "Licenţa Kirby", - "metatags.version.toolkit": "Versiune Toolkit", - "metatags.version.kirby": "Versiune Kirby", - "metatags.version.panel": "Versiune Panel", - "metatags.back": "Înapoi la panoul de control", - "metatags.files": "Fişiere sait", - "site.delete.error": "The site cannot be deleted", - "pages.show.settings": "Setări pagină", - "pages.show.preview": "Previzualizare", - "pages.show.template": "Tip pagină", - "pages.show.changeurl": "Modifică URL", - "pages.show.invisible": "Status: invizibilă", - "pages.show.visible": "Status: vizibilă", - "pages.show.changes.text": "Există modificări nesalvate!", - "pages.show.changes.button": "Renunţă", - "pages.show.delete": "Şterge această pagină", - "pages.show.subpages.title": "Pagini", - "pages.show.subpages.edit": "Editează", - "pages.show.subpages.add": "Adaugă", - "pages.show.subpages.empty": "Această pagină nu are subpagini.", - "pages.show.files.title": "Fişiere", - "pages.show.files.edit": "Editează", - "pages.show.files.add": "Adaugă", - "pages.show.files.empty": "Această pagină nu conţine fişiere", - "pages.show.error.permissions.title": "Pagina nu are permisiuni de scriere.", - "pages.show.error.permissions.text": "Verifică permisiunile directorului /content si a conţinutului său.", - "pages.show.error.permissions.retry": "Ignoră", - "pages.show.error.notitle.title": "Şablonul nu conţine un câmp pentru titlu.", - "pages.show.error.notitle.text": "Adaugă câmpul pentru titlu în şablon şi incearcă din nou.", - "pages.show.error.notitle.retry": "Ignoră", - "pages.show.error.form": "Completează corect toate câmpurile, te rog!", - "pages.add.title.label": "Adaugă o pagina nouă", - "pages.add.title.placeholder": "Titlu", - "pages.add.url.label": "Terminaţia URL", - "pages.add.url.enter": "(completează titlul)", - "pages.add.url.close": "Închide", - "pages.add.url.help": "Caractere permise: litere mici de la a la z, cifre şi cratime.", - "pages.add.template.label": "Tip pagină", - "pages.add.error.create": "The page could not be created", - "pages.add.error.title": "Lipseşte titlul", - "pages.add.error.template": "Nu a fost selectat tipul paginii!", - "pages.add.error.max.headline": "Nu sunt permise pagini noi!", - "pages.add.error.max.text": "A fost atins numărul maxim de subpagini pentru pagina aceasta.", - "pages.url.uid.label": "Terminaţia URL", - "pages.url.uid.label.option": "Foloseşte titlul", - "pages.url.error.exists": "Există deja o pagină cu aceeaşi terminaţie URL!", - "pages.url.error.move": "Terminaţia URL nu poate fi modificată!", - "pages.url.error.rights": "You cannot change the URL of this page", - "pages.template.select.label": "Tip pagină", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Position", - "pages.toggle.invisible": "invisible", - "pages.toggle.publish": "Sigur vrei sa faci **vizibilă** această pagină?", - "pages.toggle.hide": "Sigur vrei sa faci **invizibilă** această pagină?", - "pages.toggle.error.error": "The status of the error page cannot be changed", - "pages.delete.headline": "Sigur vrei sa ştergi această pagină?", - "pages.delete.error.home.headline": "Pagina principală nu poate fi ştearsă!", - "pages.delete.error.home.text": "Ai încercat să ştergi pagina principală a saitului. Acest lucru nu e posibil pentru că ar apărea efecte nedorite.", - "pages.delete.error.error.headline": "Pagina de eroare nu poate fi ştearsă!", - "pages.delete.error.error.text": "Ai încercat să ştergi pagina de eroare a saitului. Acest lucru nu e posibil pentru că ar apărea efecte nedorite.", - "pages.delete.error.children.headline": "Pagina nu poate fi ştearsă!", - "pages.delete.error.children.text": "Această pagină conţine subpagini şi nu poate fi ştearsă. Şterge te rog subpaginile mai întâi.", - "pages.delete.error.blocked.headline": "Pagina nu poate fi ştearsă!", - "pages.delete.error.blocked.text": "Această pagină este blocată şi nu poate fi ştearsă.", - "pages.search.help": "Caută pagini în funcţie de URL. Navighează printre rezultatele afişate cu ajutorul săgeţilor de pe tastatură şi apasă Enter pentru a accesa pagina căutată.", - "pages.search.noresults": "Nu există rezultate pentru căutarea făcută. Încearcă din nou folosind un URL diferit.", - "pages.error.missing": "Pagina nu poate fi găsită!", - "subpages": "Pagini", - "subpages.index.headline": "Subpagini", - "subpages.index.back": "Înapoi", - "subpages.index.add": "Adaugă o pagină nouă", - "subpages.index.add.first.text": "Această pagină nu conţine încă subpagini.", - "subpages.index.add.first.button": "Adaugă o primă subpagină", - "subpages.index.visible": "Pagini vizibile", - "subpages.index.visible.help": "Trage aici pagini pentru a le face vizibile.", - "subpages.index.invisible": "Pagini invizibile", - "subpages.index.invisible.help": "Trage aici pagini pentru a le face invizibile.", - "subpages.add.error": "This page is not allowed to have subpages", - "subpages.add.error.more": "This page cannot have any more subpages", - "subpages.error.missing": "Pagina nu a putut fi găsită!", - "files": "Fişiere", - "files.index.headline": "Fişiere", - "files.index.back": "Înapoi", - "files.index.upload": "Încarcă un nou fişier", - "files.index.upload.first.text": "Această pagină nu conţine încă niciun fişier.", - "files.index.upload.first.button": "Încarcă un prim fişier", - "files.index.edit": "Editează", - "files.index.delete": "Şterge", - "files.index.error.disabled": "The page is not allowed to have any files", - "files.add.error.max": "The maximum number of files for the current page has been reached.", - "files.add.error.extension.missing": "You cannot upload files without extension", - "files.add.error.extension.forbidden": "Forbidden file extension", - "files.add.error.mime.forbidden": "Forbidden mime type", - "files.add.error.htaccess": "htaccess files cannot be uploaded", - "files.add.error.invisible": "Invisible files cannot be uploaded", - "files.add.blueprint.type.error": "Page only allows:", - "files.add.blueprint.size.error": "Page only allows file size of", - "files.show.name.label": "Nume fişier", - "files.show.info.label": "Tip / Mărime / Dimensiuni", - "files.show.link.label": "Calea către imagine", - "files.show.open": "Afişează / descarcă fişierul", - "files.show.back": "Înapoi", - "files.show.replace": "Înlocuieşte", - "files.show.delete": "Şterge", - "files.show.error.rename": "Fişierul nu a putut fi redenumit!", - "files.show.error.form": "Completează toate câmpurile corect, te rog!", - "files.upload.drop": "Trage fişiere aici…", - "files.upload.click": "…sau click pentru a le încărca", - "files.replace.drop": "Trage un fişier aici…", - "files.replace.click": "…sau click pentru a-l înlocui", - "files.replace.error.type": "Fişierul încărcat trebuie să fie de acelaşi tip!", - "files.delete.headline": "Sigur vrei să ştergi acest fişier?", - "files.error.missing.page": "Pagina nu a putut fi găsită!", - "files.error.missing.file": "Fişierul nu a putut fi găsit!", - "users": "Utilizatori", - "users.index.headline": "Toţi utilizatorii", - "users.index.add": "Adaugă un utilizator nou", - "users.index.edit": "Editează", - "users.index.delete": "Şterge", - "users.form.username.label": "Nume utilizator", - "users.form.username.placeholder": "Numele tău de utilizator", - "users.form.username.help": "Caractere permise: litere mici de la a la z, cifre şi cratime.", - "users.form.username.readonly": "Numele de utilizator nu poate fi schimbat!", - "users.form.firstname.label": "Prenume", - "users.form.lastname.label": "Nume", - "users.form.email.label": "Email", - "users.form.email.placeholder": "email@exemplu.com", - "users.form.password.label": "Parola", - "users.form.password.confirm.label": "Confirmare parolă", - "users.form.password.new.label": "Parolă nouă", - "users.form.password.new.confirm.label": "Confirmarea parolei noi", - "users.form.password.new.help": "Lasă necompletat pentru a păstra parola curentă.", - "users.form.language.label": "Limba", - "users.form.role.label": "Rol", - "users.form.options.headline": "Opţiuni cont", - "users.form.options.message": "Trimite email", - "users.form.options.delete": "Şterge contul", - "users.form.avatar.headline": "Poza de profil", - "users.form.avatar.upload": "Încarcă o poză de profil", - "users.form.avatar.replace": "Înlocuieşte poza de profil", - "users.form.avatar.delete": "Şterge poza de profil", - "users.form.back": "Înapoi la utilizatori", - "users.form.error.password.confirm": "Confirmă parola, te rog!", - "users.form.error.update": "Contul de utilizator nu a putut fi actualizat!", - "users.form.error.update.rights": "You are not allowed to update this user", - "users.form.error.create": "Contul de utilizator nu a putut fi creat!", - "users.form.error.permissions.title": "Directorul /site/accounts nu are permisiuni de scriere.", - "users.form.error.permissions.text": "Verifică dacă directorul /site/accounts există şi are permisiuni de scriere.", - "users.delete.headline": "Sigur vrei să ştergi acest cont de utilizator?", - "users.delete.error": "Contul de utilizator nu a putut fi şters!", - "users.delete.error.permission": "You are not allowed to delete users", - "users.delete.error.permission.single": "You are not allowed to delete this user", - "users.delete.error.lastadmin": "You cannot delete the last admin", - "users.avatar.drop": "Trage o poză de profil aici…", - "users.avatar.click": "…sau click pentru încărcare", - "users.avatar.error.type": "Poţi încărca doar fişiere JPG, PNG sau GIF.", - "users.avatar.error.folder.headline": "Directorul /assets/avatars nu are permisiuni de scriere.", - "users.avatar.error.folder.text": "Verifică dacă directorul /assets/avatars există şi are permisiuni de scriere.", - "users.avatar.error.permission": "You are not allowed to change the avatar", - "users.avatar.delete.error": "Poza de profil nu a putut fi ştearsă!", - "users.avatar.delete.error.permission": "You are not allowed to delete the avatar of this user", - "users.avatar.delete.success": "Poza de profil a fost ştearsă!", - "users.avatar.missing": "This user has no avatar", - "users.error.missing": "Contul de utilizator nu a putut fi găsit!", - "user.error.lastadmin": "You are the only admin. This cannot be changed.", - "form.error.missing": "The form cannot be found", - "form.construct.error.invalid": "Invalid form construction method", - "fields.required": "Obligatoriu", - "fields.date.label": "Data", - "fields.date.months": [ - "Ianuarie", - "Februarie", - "Martie", - "Aprilie", - "Mai", - "Iunie", - "Iulie", - "August", - "Septembrie", - "Octombrie", - "Noiembrie", - "Decembrie" - ], - "fields.date.weekdays": [ - "Duminica", - "Luni", - "Marţi", - "Miercuri", - "Joi", - "Vineri", - "Sâmbătă" - ], - "fields.date.weekdays.short": [ - "Dum", - "Lun", - "Mar", - "Mie", - "Joi", - "Vin", - "Sâm" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "email@exemplu.com", - "fields.number.label": "Număr", - "fields.number.placeholder": "#", - "fields.page.label": "Pagină", - "fields.page.placeholder": "calea/către/pagină", - "fields.password.label": "Parola", - "fields.structure.add": "Adaugă", - "fields.structure.add.first": "Completează formularul!", - "fields.structure.empty": "Nicio inserţie.", - "fields.structure.entry.error": "The item could not be found", - "fields.structure.cancel": "Renunţă", - "fields.structure.save": "Salvează", - "fields.structure.edit": "Editează", - "fields.structure.delete": "Şterge", - "fields.structure.delete.label": "Do you really want to delete this entry?", - "fields.tags.label": "Etichete", - "fields.tel.label": "Telefon", - "fields.textarea.buttons.bold.label": "Text îngroşat", - "fields.textarea.buttons.bold.text": "Text îngroşat", - "fields.textarea.buttons.italic.label": "Text înclinat", - "fields.textarea.buttons.italic.text": "Text înclinat", - "fields.textarea.buttons.link.label": "Link", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "Imagine", - "fields.textarea.buttons.file.label": "Fişier", - "fields.toggle.yes": "Da", - "fields.toggle.no": "Nu", - "fields.toggle.on": "On", - "fields.toggle.off": "Off", - "fields.error.missing.controller": "The field controller file is missing", - "fields.error.missing.class": "The field controller class is missing", - "fields.error.route.invalid": "Invalid field route", - "fields.error.extended": "The field cannot be extended", - "editor.link.url.label": "Inserează URL", - "editor.link.text.label": "Link text", - "editor.link.text.help": "Linkul text este opţional.", - "editor.email.address.label": "Inserează adresa email", - "editor.email.address.placeholder": "email@exemplu.com", - "editor.email.text.label": "Link text", - "editor.email.text.help": "Linkul text este opţional.", - "editor.file.empty": "Această pagină nu conţine fişiere.", - "editor.image.empty": "Această pagină nu conţine imagini.", - "autocomplete.method.error": "Invalid autocomplete method", - "blueprints.error.default.missing": "Missing default blueprint", - "error": "Eroare", - "error.headline": "Eroare" -} \ No newline at end of file diff --git a/panel/app/translations/ro/package.json b/panel/app/translations/ro/package.json deleted file mode 100644 index a0e3e8a..0000000 --- a/panel/app/translations/ro/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Română", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/ru/core.json b/panel/app/translations/ru/core.json deleted file mode 100644 index c58a509..0000000 --- a/panel/app/translations/ru/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Отменить", - "add": "Добавить", - "addit": "Добавить и Изменить", - "save": "Сохранить", - "saved": "Сохранено", - "change": "Изменить", - "delete": "Удалить", - "insert": "Вставить", - "ok": "Ок", - "routes.error.invalid": "Неверный URL Панели", - "controller.error.invalid": "Неверный контроллер", - "controller.error.action": "Неверное действие", - "view.error.invalid": "Неверный вид:", - "options.show": "Показать опции", - "options.hide": "Скрыть опции", - "installation": "Установка", - "installation.check.headline": "Установка панели Kirby", - "installation.check.text": "Во время установки Kirby возникли следующие проблемы…", - "installation.check.retry": "Повторить", - "installation.check.error": "Не все прошло так гладко :(", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts не доступно для записи", - "installation.check.error.avatars": "/assets/avatars не доступно для записи", - "installation.check.error.blueprints": "Пожалуйста, создайте папку /site/blueprints", - "installation.check.error.content": "Папка content в все вложенные папки и файлы должны быть доступны для записи.", - "installation.check.error.thumbs": "Папка thumbs должна быть доступна для записи.", - "installation.signup.username.label": "Создайте первый аккаунт пользователя", - "installation.signup.username.placeholder": "Логин", - "installation.signup.email.label": "Эл.почта", - "installation.signup.email.placeholder": "pochta@domen.com", - "installation.signup.password.label": "Пароль", - "installation.signup.language.label": "Язык", - "installation.signup.button": "Создать аккаунт", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Логин", - "login.password.label": "Пароль", - "login.error": "Неверный логин или пароль", - "login.button": "Log in", - "login.log.error.permissions": "Файл журнала входов не доступен для записи.", - "logout": "Log out", - "topbar.error.class.definition": "Missing topbar definition for class:", - "dashboard": "Панель управления", - "dashboard.index.pages.title": "Страницы", - "dashboard.index.pages.edit": "Настроить", - "dashboard.index.pages.add": "Добавить", - "dashboard.index.site.title": "Адрес вашего сайта", - "dashboard.index.account.title": "Ваш аккаунт", - "dashboard.index.account.edit": "Настроить", - "dashboard.index.metatags.title": "Переменные сайта", - "dashboard.index.metatags.edit": "Настроить", - "dashboard.index.history.title": "Ваши последние правки", - "dashboard.index.history.text": "Последние измененные вами страницы будут показаны здесь для быстрого доступа к ним.", - "dashboard.index.license.title": "Лицензия Kirby", - "dashboard.index.license.text": "Кажется, вы запустили Kirby на общедоступном сервере без действующей лицензии!\n\nПожалуйста, поддержите Kirby и (link: {buy} text: купите лицензию)\n\nЕсли у вас уже есть лицензионный ключ, просто добавьте его в ваш конфигурационный файл: (link: {docs} text: site/config/config.php)", - "metatags": "Переменные сайта", - "metatags.info": "Информация о Kirby", - "metatags.license": "Лицензия Kirby", - "metatags.version.toolkit": "Версия Инструментария", - "metatags.version.kirby": "Версия Kirby", - "metatags.version.panel": "Версия панели", - "metatags.back": "Назад в панель управления", - "metatags.files": "Файлы сайта", - "site.delete.error": "Сайт не может быть удален", - "pages.show.settings": "Настройки страницы", - "pages.show.preview": "Предпросмотр", - "pages.show.template": "Шаблон", - "pages.show.changeurl": "Изменить ссылку (ЧПУ)", - "pages.show.invisible": "Статус: не отображается", - "pages.show.visible": "Статус: отображается", - "pages.show.changes.text": "Вы не сохранили изменения!", - "pages.show.changes.button": "Сброс", - "pages.show.delete": "Удалить эту страницу", - "pages.show.subpages.title": "Страницы", - "pages.show.subpages.edit": "Настроить", - "pages.show.subpages.add": "Добавить", - "pages.show.subpages.empty": "Для этой страницы нет подстраниц", - "pages.show.files.title": "Файлы", - "pages.show.files.edit": "Настроить", - "pages.show.files.add": "Добавить", - "pages.show.files.empty": "Для этой страницы нет файлов", - "pages.show.error.permissions.title": "Эта страница не доступна для записи", - "pages.show.error.permissions.text": "Пожалуйста, проверьте права для папки content и всех файлов.", - "pages.show.error.permissions.retry": "Повторить", - "pages.show.error.notitle.title": "В этом шаблоне формы должно быть поле для названия", - "pages.show.error.notitle.text": "Пожалуйста, заполните название и повторите снова", - "pages.show.error.notitle.retry": "Повторить", - "pages.show.error.form": "Пожалуйста, заполните все необходимые поля корректно", - "pages.add.title.label": "Создать новую страницу", - "pages.add.title.placeholder": "Название", - "pages.add.url.label": "понятная ссылка (ЧПУ)", - "pages.add.url.enter": "(введите название страницы)", - "pages.add.url.close": "Закрыть", - "pages.add.url.help": "Формат: нижние латинские буквы, цифры и дефисы", - "pages.add.template.label": "Шаблон", - "pages.add.error.create": "Страница не может быть создана", - "pages.add.error.title": "Отсутствует название", - "pages.add.error.template": "Отсутствует шаблон", - "pages.add.error.max.headline": "Предельное количество страниц", - "pages.add.error.max.text": "Для данной страницы достигнут максимальный предел подстраниц.", - "pages.url.uid.label": "ссылка (ЧПУ)", - "pages.url.uid.label.option": "сформировать", - "pages.url.error.exists": "Страница с такой же понятной ссылкой (ЧПУ) уже существует", - "pages.url.error.move": "Понятная ссылка (ЧПУ) не может быть изменена", - "pages.url.error.rights": "Вы не можете изменить URL этой страницы", - "pages.template.select.label": "Шаблон", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Позиция", - "pages.toggle.invisible": "не отображается", - "pages.toggle.publish": "Вы действительно хотите изменить статус этой страницы на **отображается?**", - "pages.toggle.hide": "Вы действительно хотите изменить статус этой страницы на **не отображается?**", - "pages.toggle.error.error": "Статус страницы ошибки не может быть изменен", - "pages.delete.headline": "Вы действительно хотите удалить эту страницу?", - "pages.delete.error.home.headline": "Индексная (домашняя) страница не может быть удалена", - "pages.delete.error.home.text": "Вы пытаетесь удалить индексную (домашнюю) страницу. Это невозможно, так как может привести к непредсказуемым результатам.", - "pages.delete.error.error.headline": "Страница ошибок (404) не может быть удалена", - "pages.delete.error.error.text": "Вы пытаетесь удалить страницу ошибок (Error 404 Page). Это невозможно, так как может привести к непредсказуемым результатам.", - "pages.delete.error.children.headline": "Страница не может быть удалена", - "pages.delete.error.children.text": "Для этой страницы существуют подстраницы. Пожалуйста, удалите сначала подстраницы.", - "pages.delete.error.blocked.headline": "Эта страница не может быть удалена", - "pages.delete.error.blocked.text": "Эта страница заблокирована и не может быть удалена в настоящий момент.", - "pages.search.help": "Поиск страниц по ссылкам. Для перемещения по результатам поиска используйте стрелки на клавиатуре ВВЕРХ и ВНИЗ. Для открытия страницы, нажмите ВВОД.", - "pages.search.noresults": "Нет результатов по вашему запросу. Пожалуйста, проверьте строку поиска.", - "pages.error.missing": "Страница не найдена", - "subpages": "Страницы", - "subpages.index.headline": "Страниц для", - "subpages.index.back": "Назад", - "subpages.index.add": "Добавить новую страницу", - "subpages.index.add.first.text": "Для этой страницы пока нет подстраниц", - "subpages.index.add.first.button": "Добавить первую страницу", - "subpages.index.visible": "Видимые страницы", - "subpages.index.visible.help": "Перетащите невидимые страницы сюда для их публикации (сортировки в меню).", - "subpages.index.invisible": "Невидимые страницы", - "subpages.index.invisible.help": "Перетащите видимые страницы сюда для их сокрытия (удаления из меню).", - "subpages.add.error": "Эта страница не имеет подстраниц", - "subpages.add.error.more": "Эта страница не может иметь больше подстраниц", - "subpages.error.missing": "Страница не найдена", - "files": "Файлы", - "files.index.headline": "Файлов для", - "files.index.back": "назад", - "files.index.upload": "Закачать новый файл", - "files.index.upload.first.text": "Для этой страницы пока нет файлов", - "files.index.upload.first.button": "Закачать первый файл", - "files.index.edit": "Настроить", - "files.index.delete": "Удалить", - "files.index.error.disabled": "The page is not allowed to have any files", - "files.add.error.max": "The maximum number of files for the current page has been reached.", - "files.add.error.extension.missing": "You cannot upload files without extension", - "files.add.error.extension.forbidden": "Forbidden file extension", - "files.add.error.mime.forbidden": "Forbidden mime type", - "files.add.error.htaccess": "htaccess files cannot be uploaded", - "files.add.error.invisible": "Invisible files cannot be uploaded", - "files.add.blueprint.type.error": "Page only allows:", - "files.add.blueprint.size.error": "Page only allows file size of", - "files.show.name.label": "Имя файла", - "files.show.info.label": "Тип / размер / Разрешение", - "files.show.link.label": "Публичная ссылка", - "files.show.open": "Показать/скачать файл", - "files.show.back": "Назад", - "files.show.replace": "Заменить", - "files.show.delete": "Удалить", - "files.show.error.rename": "Файл не может быть переименован", - "files.show.error.form": "Пожалуйста, заполните все необходимые поля корректно", - "files.upload.drop": "Перетащите файлы сюда…", - "files.upload.click": "…или кликните для выбора", - "files.replace.drop": "Перетащите файлы сюда…", - "files.replace.click": "…или кликните для выбора", - "files.replace.error.type": "Закачиваемый файл должен иметь такое же расширение (тип)", - "files.delete.headline": "Вы действительно хотите удалить файл?", - "files.error.missing.page": "Страница не найдена", - "files.error.missing.file": "Файл не найден", - "users": "Пользователи", - "users.index.headline": "Все пользователи", - "users.index.add": "Добавить нового пользователя", - "users.index.edit": "Настроить", - "users.index.delete": "Удалить", - "users.form.username.label": "Логин", - "users.form.username.placeholder": "Ваш логин", - "users.form.username.help": "Формат: нижние латинские буквы, цифры и дефисы", - "users.form.username.readonly": "Логин не может быть изменен", - "users.form.firstname.label": "Имя", - "users.form.lastname.label": "Фамилия", - "users.form.email.label": "Эл.почта", - "users.form.email.placeholder": "pochta@domen.com", - "users.form.password.label": "Пароль", - "users.form.password.confirm.label": "Подтвердите пароль", - "users.form.password.new.label": "Новый пароль", - "users.form.password.new.confirm.label": "Подтвердите новый пароль", - "users.form.password.new.help": "Оставьте пустым, чтобы не менять пароль", - "users.form.language.label": "Язык", - "users.form.role.label": "Роль", - "users.form.options.headline": "Опции аккаунта", - "users.form.options.message": "Отправить эл.почту", - "users.form.options.delete": "Удалить аккаунт", - "users.form.avatar.headline": "Аватар (фото)", - "users.form.avatar.upload": "Закачать картинку для аккаунта", - "users.form.avatar.replace": "Заменить картинку для аккаунта", - "users.form.avatar.delete": "Удалить картинку для аккаунта", - "users.form.back": "назад к аккаунтам", - "users.form.error.password.confirm": "Пожалуйста, подтвердите пароль", - "users.form.error.update": "Аккаунт не может быть изменен", - "users.form.error.update.rights": "You are not allowed to update this user", - "users.form.error.create": "Аккаунт не может быть создан", - "users.form.error.permissions.title": "Папка account не доступна для записи", - "users.form.error.permissions.text": "Пожалуйста, убедитесь, что папка /site/accounts существует и доступна для записи.", - "users.delete.headline": "Вы действительно хотите удалить аккаунт?", - "users.delete.error": "Аккаунт не может быть удален", - "users.delete.error.permission": "You are not allowed to delete users", - "users.delete.error.permission.single": "You are not allowed to delete this user", - "users.delete.error.lastadmin": "Вы не можете удалить единственного администратора", - "users.avatar.drop": "Перетащите картинку для аккаунта сюда…", - "users.avatar.click": "…или кликните для выбора", - "users.avatar.error.type": "Формат файлов картинок может быть JPG, PNG или GIF", - "users.avatar.error.folder.headline": "Папка avatar не доступна для записи", - "users.avatar.error.folder.text": "Пожалуйста, убедитесь, что папка /assets/avatars существует и доступна для записи перед добавлением аватаров (фото) к аккаунтам.", - "users.avatar.error.permission": "You are not allowed to change the avatar", - "users.avatar.delete.error": "Аватар (фото) к аккаунту не может быть удален", - "users.avatar.delete.error.permission": "You are not allowed to delete the avatar of this user", - "users.avatar.delete.success": "Аватар (фото) к аккаунту удален", - "users.avatar.missing": "У пользователя нет аватара", - "users.error.missing": "Аккаунт не найден", - "user.error.lastadmin": "You are the only admin. This cannot be changed.", - "form.error.missing": "The form cannot be found", - "form.construct.error.invalid": "Invalid form construction method", - "fields.required": "Необходимо", - "fields.date.label": "Дата", - "fields.date.months": [ - "Январь", - "Февраль", - "Март", - "Апрель", - "Май", - "Июнь", - "Июль", - "Август", - "Сентябрь", - "Октябрь", - "Ноябрь", - "Декабрь" - ], - "fields.date.weekdays": [ - "Воскресенье", - "Понедельник", - "Вторник", - "Среда", - "Четверг", - "Пятница", - "Суббота" - ], - "fields.date.weekdays.short": [ - "Вс", - "Пн", - "Вт", - "Ср", - "Чт", - "Пт", - "Сб" - ], - "fields.email.label": "Эл.почта", - "fields.email.placeholder": "pochta@domen.com", - "fields.number.label": "Номер", - "fields.number.placeholder": "#", - "fields.page.label": "Страница", - "fields.page.placeholder": "путь/к/странице", - "fields.password.label": "Пароль", - "fields.structure.add": "Добавить", - "fields.structure.add.first": "Добавить первую запись", - "fields.structure.empty": "Пока нет записей.", - "fields.structure.entry.error": "The item could not be found", - "fields.structure.cancel": "Отмена", - "fields.structure.save": "Сохранить", - "fields.structure.edit": "Настроить", - "fields.structure.delete": "Удалить", - "fields.structure.delete.label": "Do you really want to delete this entry?", - "fields.tags.label": "Тэги", - "fields.tel.label": "Телефон", - "fields.textarea.buttons.bold.label": "Жирный шрифт", - "fields.textarea.buttons.bold.text": "Жирный шрифт", - "fields.textarea.buttons.italic.label": "Наклонный шрифт", - "fields.textarea.buttons.italic.text": "Наклонный шрифт", - "fields.textarea.buttons.link.label": "Ссылка", - "fields.textarea.buttons.email.label": "Эл.почта", - "fields.textarea.buttons.image.label": "Картинка", - "fields.textarea.buttons.file.label": "Файл", - "fields.toggle.yes": "Да", - "fields.toggle.no": "Нет", - "fields.toggle.on": "Вкл", - "fields.toggle.off": "Выкл", - "fields.error.missing.controller": "The field controller file is missing", - "fields.error.missing.class": "The field controller class is missing", - "fields.error.route.invalid": "Invalid field route", - "fields.error.extended": "The field cannot be extended", - "editor.link.url.label": "Вставить ссылку", - "editor.link.text.label": "Текст ссылки", - "editor.link.text.help": "Текст ссылки не обязателен", - "editor.email.address.label": "Введите адрес эл.почты", - "editor.email.address.placeholder": "pochta@domen.com", - "editor.email.text.label": "Текст ссылки эл.почты", - "editor.email.text.help": "Текст ссылки эл.почты не обязателен", - "editor.file.empty": "Для этой страницы нет файлов", - "editor.image.empty": "Для этой страницы нет картинок", - "autocomplete.method.error": "Invalid autocomplete method", - "blueprints.error.default.missing": "Missing default blueprint", - "error": "Ошибка", - "error.headline": "Ошибка" -} \ No newline at end of file diff --git a/panel/app/translations/ru/package.json b/panel/app/translations/ru/package.json deleted file mode 100644 index 6d6c6ec..0000000 --- a/panel/app/translations/ru/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Русский (Russian)‎", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/sv_SE/core.json b/panel/app/translations/sv_SE/core.json deleted file mode 100644 index e5cafc8..0000000 --- a/panel/app/translations/sv_SE/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "Avbryt", - "add": "Lägg till", - "addit": "Lägg till & redigera", - "save": "Spara", - "saved": "Sparad!", - "change": "Spara ändring", - "delete": "Radera", - "insert": "Infoga", - "ok": "Ok", - "routes.error.invalid": "Ogiltig URL för panel", - "controller.error.invalid": "Ogiltig kontroll", - "controller.error.action": "Ogiltig åtgärd", - "view.error.invalid": "Ogiltig vy:", - "options.show": "Visa alternativ", - "options.hide": "Göm alternativ", - "installation": "Installation", - "installation.check.headline": "Kirby Panel-installation", - "installation.check.text": "Kirby påträffade följande fel under installationen…", - "installation.check.retry": "Försök igen", - "installation.check.error": "Det finns några problem!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "Mappen /site/accounts saknar skrivrättigheter", - "installation.check.error.avatars": "Mappen /assets/avatars saknar skrivrättigheter", - "installation.check.error.blueprints": "Vänligen lägg till en mapp för /site/blueprints", - "installation.check.error.content": "Innehållet i mappen, alla dess filer och undermappar, måste ha skrivrättigheter.", - "installation.check.error.thumbs": "Mappen /thumbs måste ha skrivrättigheter.", - "installation.signup.username.label": "Skapa ditt första konto", - "installation.signup.username.placeholder": "Användarnamn", - "installation.signup.email.label": "E-mail", - "installation.signup.email.placeholder": "namn@exempel.se", - "installation.signup.password.label": "Lösenord", - "installation.signup.language.label": "Språk", - "installation.signup.button": "Skapa ett konto", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "Användarnamn", - "login.password.label": "Lösenord", - "login.error": "Fel användarnamn eller lösenord", - "login.button": "Log in", - "login.log.error.permissions": "Logg-filen för inloggningar är ej skrivbar.", - "logout": "Log out", - "topbar.error.class.definition": "Missing topbar definition for class:", - "dashboard": "Kontrollpanel", - "dashboard.index.pages.title": "Sidor", - "dashboard.index.pages.edit": "Ändra", - "dashboard.index.pages.add": "Lägg till", - "dashboard.index.site.title": "Webbplatsens webbadress", - "dashboard.index.account.title": "Ditt konto", - "dashboard.index.account.edit": "Ändra", - "dashboard.index.metatags.title": "Webbplatsens metadata", - "dashboard.index.metatags.edit": "Ändra", - "dashboard.index.history.title": "Senast ändrade sidor", - "dashboard.index.history.text": "Dina senast ändrade sidor kommer att listas här för att underlätta att hitta dem igen senare.", - "dashboard.index.license.title": "Kirbylicens", - "dashboard.index.license.text": "Det verkar som att du kör Kirby på en publik server utan giltig licens. \n\nVänligen, stöd Kirby genom att (link: {buy} text: köpa en licens nu).\n\nOm du redan har en licens, se till att lägga till den i din konfigurationsfil: (link: {docs} text: site/config/config.php)", - "metatags": "Webbplatsens metadata", - "metatags.info": "Information om Kirby", - "metatags.license": "Kirbylicens", - "metatags.version.toolkit": "Version av Toolkit", - "metatags.version.kirby": "Version av Kirby", - "metatags.version.panel": "Version av Panel", - "metatags.back": "Tillbaka till kontrollpanelen", - "metatags.files": "Webbplatsfiler", - "site.delete.error": "Sidan kan inte raderas", - "pages.show.settings": "Inställningar för sida", - "pages.show.preview": "Förhandsvisa sida", - "pages.show.template": "Mall", - "pages.show.changeurl": "Ändra webbadress", - "pages.show.invisible": "Dold i meny", - "pages.show.visible": "Synlig i meny", - "pages.show.changes.text": "Du har ändringar som inte sparats!", - "pages.show.changes.button": "Skrota", - "pages.show.delete": "Radera sida", - "pages.show.subpages.title": "Undersidor", - "pages.show.subpages.edit": "Ändra", - "pages.show.subpages.add": "Lägg till", - "pages.show.subpages.empty": "Den här sidan har inga undersidor.", - "pages.show.files.title": "Filer", - "pages.show.files.edit": "Ändra", - "pages.show.files.add": "Lägg till", - "pages.show.files.empty": "Den här sidan har inga filer.", - "pages.show.error.permissions.title": "Sidan är ej skrivbar", - "pages.show.error.permissions.text": "Vänligen kontrollera skriv- och läsrättigheter för mappen /content samt dess underliggande filer och mappar.", - "pages.show.error.permissions.retry": "Försök igen", - "pages.show.error.notitle.title": "Blueprinten har inget titel-fält", - "pages.show.error.notitle.text": "Vänligen lägg till ett titel-fält och försök igen", - "pages.show.error.notitle.retry": "Försök igen", - "pages.show.error.form": "vänligen fyll i alla fält korrekt", - "pages.add.title.label": "Lägg till en ny sida", - "pages.add.title.placeholder": "Titel", - "pages.add.url.label": "Tillägg i webbadress", - "pages.add.url.enter": "(skriv in din titel)", - "pages.add.url.close": "Stäng", - "pages.add.url.help": "Format: gemener a-z, 0-9 och vanliga streck", - "pages.add.template.label": "Mall", - "pages.add.error.create": "Sidan kan ej skapas", - "pages.add.error.title": "Titel saknas", - "pages.add.error.template": "Mall saknas", - "pages.add.error.max.headline": "Nya sidor är ej tillåtet", - "pages.add.error.max.text": "Det maximala antalet undersidor för den här sidan har nåtts.", - "pages.url.uid.label": "Tillägg i webbadress", - "pages.url.uid.label.option": "Skapa utifrån titel", - "pages.url.error.exists": "En sida med samma webbadress existerar redan", - "pages.url.error.move": "Tillägget i webbadress kan ej ändras", - "pages.url.error.rights": "Du kan inte ändra URL:en på denna sidan", - "pages.template.select.label": "Mall", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Position", - "pages.toggle.invisible": "dold", - "pages.toggle.publish": "Är du säker på att du vill ändra sidan status till **synlig i meny?**", - "pages.toggle.hide": "Är du säker på att du vill ändra sidan status till **dold i meny?**", - "pages.toggle.error.error": "Statusen för felsidan kan inte ändras", - "pages.delete.headline": "Vill du verkligen radera sidan?", - "pages.delete.error.home.headline": "Startsidan kan ej raderas", - "pages.delete.error.home.text": "Du försöker radera startsidan. Det är inte möjligt och får oönskad effekt.", - "pages.delete.error.error.headline": "Felsidan kan inte tas bort", - "pages.delete.error.error.text": "Du försöker ta bort felsidan. Det är inte möjligt och får oönskad effekt.", - "pages.delete.error.children.headline": "Den här sidan kan ej raderas", - "pages.delete.error.children.text": "Den här sidan har undersidor och kan ej raderas. Vänlig radera alla undersidor först.", - "pages.delete.error.blocked.headline": "Den här sidan kan ej raderas", - "pages.delete.error.blocked.text": "Den här sidan är låst och kan ej raderas.", - "pages.search.help": "Sök bland alla sidor via dess webbadress. Navigera upp och ner genom sökresultaten med piltangenterna och tryck enter-/retur-knapp för att redigera markerad sida.", - "pages.search.noresults": "Det finns inga resultat på din sökning. Var vänlig och försök igen med en annan webbadress.", - "pages.error.missing": "Sidan kan ej hittas", - "subpages": "Alla sidor", - "subpages.index.headline": "Alla undersidor i", - "subpages.index.back": "Tillbaka", - "subpages.index.add": "Lägg till en ny sida", - "subpages.index.add.first.text": "Den här sidan har inga undersidor än", - "subpages.index.add.first.button": "Lägg till den första sidan", - "subpages.index.visible": "Synliga sidor i meny", - "subpages.index.visible.help": "Dra dolda sidor hit för att sortera dem/göra dem synliga.", - "subpages.index.invisible": "Dolda sidor (visas ej i meny)", - "subpages.index.invisible.help": "Dra synliga sidor hit för att dölja dem.", - "subpages.add.error": "Den här sidan kan inte ha undersidor", - "subpages.add.error.more": "Den här sidan kan inte ha fler undersidor", - "subpages.error.missing": "Sidan kan ej hittas", - "files": "Filer", - "files.index.headline": "Filer för", - "files.index.back": "Tillbaka", - "files.index.upload": "Ladda upp en ny fil", - "files.index.upload.first.text": "Den här sidan har inga filer än", - "files.index.upload.first.button": "Ladda upp första filen", - "files.index.edit": "Ändra", - "files.index.delete": "Radera", - "files.index.error.disabled": "Den här sidan kan inte ha några filer", - "files.add.error.max": "Det maximala antalet filer för den här sidan har nåtts", - "files.add.error.extension.missing": "Du kan inte ladda upp filer utan filändelse", - "files.add.error.extension.forbidden": "Filändelsen är ej tillåten", - "files.add.error.mime.forbidden": "Ogiltig MIME-typ", - "files.add.error.htaccess": "Htaccess-filer är ej tillåtet att ladda upp.", - "files.add.error.invisible": "Osynliga filer är ej tillåtet att ladda upp.", - "files.add.blueprint.type.error": "Sidan tillåter endast:", - "files.add.blueprint.size.error": "Sidan tillåter endast en filstorlek på", - "files.show.name.label": "Filnamn", - "files.show.info.label": "Filtyp / storlek / dimensioner", - "files.show.link.label": "Publik webbadress", - "files.show.open": "Visa/ladda ner fil", - "files.show.back": "Tillbaka", - "files.show.replace": "Ersätt fil", - "files.show.delete": "Radera", - "files.show.error.rename": "Filen kan ej döpas om", - "files.show.error.form": "Var vänlig och fyll i alla fält korrekt", - "files.upload.drop": "Släpp filer här…", - "files.upload.click": "…eller klicka för att ladda upp", - "files.replace.drop": "Släpp en fil här …", - "files.replace.click": "… eller klicka för att välja en ny fil", - "files.replace.error.type": "Den uppladdade filen måste vara av samma filtyp", - "files.delete.headline": "Vill du verkligen ta bort denna fil?", - "files.error.missing.page": "Sidan kan ej hittas", - "files.error.missing.file": "Filen kan ej hittas", - "users": "Användare", - "users.index.headline": "Alla användare", - "users.index.add": "Lägg till en ny användare", - "users.index.edit": "Ändra", - "users.index.delete": "Radera", - "users.form.username.label": "Användarnamn", - "users.form.username.placeholder": "Ditt användarnamn", - "users.form.username.help": "Tillåtna tecken: gemener a-z, 0-9 och streck", - "users.form.username.readonly": "Användarnamnet kan ej ändras", - "users.form.firstname.label": "Förnamn", - "users.form.lastname.label": "Efternamn", - "users.form.email.label": "E-mail", - "users.form.email.placeholder": "namn@exampel.se", - "users.form.password.label": "Lösenord", - "users.form.password.confirm.label": "Bekräfta lösenord", - "users.form.password.new.label": "Nytt lösenord", - "users.form.password.new.confirm.label": "Bekräfta nytt lösenord", - "users.form.password.new.help": "Lämna blankt för att behålla nuvarande lösenord", - "users.form.language.label": "Språk", - "users.form.role.label": "Roll", - "users.form.options.headline": "Kontoinställningar", - "users.form.options.message": "Skicka mail", - "users.form.options.delete": "Radera konto", - "users.form.avatar.headline": "Profilbild", - "users.form.avatar.upload": "Ladda upp profilbild", - "users.form.avatar.replace": "Byt ut profilbild", - "users.form.avatar.delete": "Radera profilbild", - "users.form.back": "Tillbaka till användare", - "users.form.error.password.confirm": "Vänlig bekräfta ditt lösenord", - "users.form.error.update": "Användaren kan ej uppdateras", - "users.form.error.update.rights": "Du får inte uppdatera den här användaren", - "users.form.error.create": "Användaren kan ej skapas", - "users.form.error.permissions.title": "Mappen är ej skrivbar", - "users.form.error.permissions.text": "Var vänlig och kontroller att mappen sites/accounts existerar och har skrivrättigheter.", - "users.delete.headline": "Vill du verkligen radera användaren?", - "users.delete.error": "Användaren kan ej raderas", - "users.delete.error.permission": "Du får inte radera användare", - "users.delete.error.permission.single": "Du får inte radera den här användaren", - "users.delete.error.lastadmin": "Du kan inte radera sista administratören", - "users.avatar.drop": "Släpp en profilbild här…", - "users.avatar.click": "…eller klicka för att ladda upp", - "users.avatar.error.type": "Du kan bara ladda upp bilder i följande filformat: JPG, PNG och GIF", - "users.avatar.error.folder.headline": "avatar-mappen är inte skrivbar", - "users.avatar.error.folder.text": "Var vänlig och kontrollera att mappen /assets/avatars existerar och har skrivrättigheter för att kunna ladda upp profilbilder.", - "users.avatar.error.permission": "Du får inte ändra avataren", - "users.avatar.delete.error": "Profilbilden kan ej raderas", - "users.avatar.delete.error.permission": "Du får inte radera avataren för den här användaren", - "users.avatar.delete.success": "Profilbilden har raderas", - "users.avatar.missing": "Den här användare saknar avatar", - "users.error.missing": "Användaren kan ej hittas", - "user.error.lastadmin": "Du är ensam administratör. Det går inte att ändra.", - "form.error.missing": "Formuläret kan ej hittas", - "form.construct.error.invalid": "Ogiltig metod för konstruktion av formulär", - "fields.required": "Ifyllt fält krävs.", - "fields.date.label": "Datum", - "fields.date.months": [ - "Januari", - "Februari", - "Mars", - "April", - "Maj", - "Juni", - "Juli", - "Augusti", - "September", - "Oktober", - "November", - "December" - ], - "fields.date.weekdays": [ - "Söndag", - "Måndag", - "Tisdag", - "Onsdag", - "Torsdag", - "Fredag", - "Lördag" - ], - "fields.date.weekdays.short": [ - "Sön", - "Mån", - "Tis", - "Ons", - "Tor", - "Fre", - "Lör" - ], - "fields.email.label": "E-mail", - "fields.email.placeholder": "namn@exempel.se", - "fields.number.label": "Nummer", - "fields.number.placeholder": "#", - "fields.page.label": "Sida", - "fields.page.placeholder": "sökväg/till/sida", - "fields.password.label": "Lösenord", - "fields.structure.add": "Lägg till", - "fields.structure.add.first": "Lägg till första posten", - "fields.structure.empty": "Inga poster än.", - "fields.structure.entry.error": "Artikeln kan ej hittas", - "fields.structure.cancel": "Avbryt", - "fields.structure.save": "Spara", - "fields.structure.edit": "Ändra", - "fields.structure.delete": "Radera", - "fields.structure.delete.label": "Vill du verkligen radera den här posten?", - "fields.tags.label": "Taggar", - "fields.tel.label": "Telefon", - "fields.textarea.buttons.bold.label": "Fet text", - "fields.textarea.buttons.bold.text": "Fet text", - "fields.textarea.buttons.italic.label": "Kursiv text", - "fields.textarea.buttons.italic.text": "Kursiv text", - "fields.textarea.buttons.link.label": "Länk", - "fields.textarea.buttons.email.label": "E-mail", - "fields.textarea.buttons.image.label": "Bilder", - "fields.textarea.buttons.file.label": "Fil", - "fields.toggle.yes": "Ja", - "fields.toggle.no": "Nej", - "fields.toggle.on": "På", - "fields.toggle.off": "Av", - "fields.error.missing.controller": "Filen för fältkontroll saknas", - "fields.error.missing.class": "Klassen för fältkontroll saknas", - "fields.error.route.invalid": "Invalid field route", - "fields.error.extended": "Fältet kan inte förlängas", - "editor.link.url.label": "Lägg till webbadress", - "editor.link.text.label": "Länktext", - "editor.link.text.help": "Länktext är frivillig", - "editor.email.address.label": "Lägg till en emailaddress", - "editor.email.address.placeholder": "mail@exempel.se", - "editor.email.text.label": "Länktext", - "editor.email.text.help": "Länktext är frivillig", - "editor.file.empty": "Den här sidan saknar filer", - "editor.image.empty": "Den här sidan saknar bilder", - "autocomplete.method.error": "Ogiltig metod för automatisk komplettering", - "blueprints.error.default.missing": "Standard-blueprint saknas", - "error": "Fel", - "error.headline": "Error" -} \ No newline at end of file diff --git a/panel/app/translations/sv_SE/package.json b/panel/app/translations/sv_SE/package.json deleted file mode 100644 index 6b56c58..0000000 --- a/panel/app/translations/sv_SE/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Svenska", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/tr/core.json b/panel/app/translations/tr/core.json deleted file mode 100644 index c57e840..0000000 --- a/panel/app/translations/tr/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "İptal", - "add": "Ekle", - "addit": "Ekle & Düzenle", - "save": "Kaydet", - "saved": "Kaydedildi!", - "change": "Değiştir", - "delete": "Sil", - "insert": "Ekle", - "ok": "Tamam", - "routes.error.invalid": "Geçersiz Panel Adresi", - "controller.error.invalid": "Geçersiz denetleyici", - "controller.error.action": "Geçersiz eylem", - "view.error.invalid": "Geçersiz görünüm:", - "options.show": "Seçenekleri göster", - "options.hide": "Seçenekleri gizle", - "installation": "Kurulum", - "installation.check.headline": "Kirby Panel Kurulumu", - "installation.check.text": "Kirby kurulum aşamasında belirtilen sorunla karşılaştı…", - "installation.check.retry": "Tekrar Dene", - "installation.check.error": "Bazı sorunlar mevcut!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts klasörü yazılabilir değil", - "installation.check.error.avatars": "/assets/avatars klasörü yazılabilir değil", - "installation.check.error.blueprints": "Lütfen şu klasörü oluşturun : /site/blueprints", - "installation.check.error.content": "Content adındaki klasör ve içindeki tüm klasörler, dosyalar yazılabilir olmalı.", - "installation.check.error.thumbs": "thumb klasörü yazılabilir olmalı", - "installation.signup.username.label": "İlk hesabını oluştur", - "installation.signup.username.placeholder": "Kullanıcı Adı", - "installation.signup.email.label": "E-Posta", - "installation.signup.email.placeholder": "eposta@ornek.com", - "installation.signup.password.label": "Şifre", - "installation.signup.language.label": "Dil", - "installation.signup.button": "Hesabını oluştur", - "login": "Giriş", - "login.welcome": "Lütfen yeni hesabınız ile giriş yapın", - "login.username.label": "Kullanıcı Adı", - "login.password.label": "Şifre", - "login.error": "Geçersiz kullanıcı adı veya şifre", - "login.button": "Giriş", - "login.log.error.permissions": "Giriş günlük kayıt dosyası yazılabilir değil", - "logout": "Güvenli çıkış", - "topbar.error.class.definition": "Sınıfın üstbar tanımlaması eksik:", - "dashboard": "Kontrol Paneli", - "dashboard.index.pages.title": "Sayfalar", - "dashboard.index.pages.edit": "Düzenle", - "dashboard.index.pages.add": "Ekle", - "dashboard.index.site.title": "Website Adresi", - "dashboard.index.account.title": "Hesap Bilgilerin", - "dashboard.index.account.edit": "Düzenle", - "dashboard.index.metatags.title": "Site Bilgileri", - "dashboard.index.metatags.edit": "Düzenle", - "dashboard.index.history.title": "Son güncellemelerin", - "dashboard.index.history.text": "Son güncellemelerin, daha sonra tekrar kolayca bulabilmen için burada görünecek", - "dashboard.index.license.title": "Kirby lisans", - "dashboard.index.license.text": "Kirby'yi canlı sunucuda geçerli bir lisansınız olmadan kullanıyor görünüyorsunuz!\n\nLütfen, Kirby'yi destekleyin ve (link: {buy} text: bir lisans satın alın)\n\nEğer bir lisans anahtarınız var ise, bunu yapılandırma dosyanıza ekleyin: (link: {docs} text: site/config/config.php)", - "metatags": "Site seçenekleri", - "metatags.info": "Kirby bilgi", - "metatags.license": "Kirby lisans", - "metatags.version.toolkit": "Toolkit lisans", - "metatags.version.kirby": "Kirby versiyon", - "metatags.version.panel": "Panel versiyon", - "metatags.back": "Kontrol paneline geri dön", - "metatags.files": "Site dosyaları", - "site.delete.error": "Site silinemez", - "pages.show.settings": "Sayfa ayarları", - "pages.show.preview": "Önizlemeyi aç", - "pages.show.template": "Şablon", - "pages.show.changeurl": "Web adresini değiştir", - "pages.show.invisible": "Durum: görünmez", - "pages.show.visible": "Durum: görünür", - "pages.show.changes.text": "Kaydedilmemiş değişiklikleriniz var!", - "pages.show.changes.button": "Vazgeç", - "pages.show.delete": "Bu sayfayı sil", - "pages.show.subpages.title": "Alt sayfalar", - "pages.show.subpages.edit": "Düzenle", - "pages.show.subpages.add": "Ekle", - "pages.show.subpages.empty": "Bu sayfanın şu an bir alt sayfası yok", - "pages.show.files.title": "Dosyalar", - "pages.show.files.edit": "Düzenle", - "pages.show.files.add": "Ekle", - "pages.show.files.empty": "Bu sayfanın şu an bir dosyası yok", - "pages.show.error.permissions.title": "Sayfa yazılabilir değil", - "pages.show.error.permissions.text": "Lütfen content klasörünün ve içindekilerinin izin yapılandırmasını kontrol ediniz", - "pages.show.error.permissions.retry": "Tekrar Dene", - "pages.show.error.notitle.title": "Blueprint'in başlık alanı yok", - "pages.show.error.notitle.text": "Lütfen bir başlık girin ve tekrar deneyin", - "pages.show.error.notitle.retry": "Tekrar Dene", - "pages.show.error.form": "Lütfen gerekli tüm alanları doğru bir şekilde doldurunuz", - "pages.add.title.label": "Yeni bir alt sayfa ekle", - "pages.add.title.placeholder": "Başlık", - "pages.add.url.label": "Web Adres-uzantısı", - "pages.add.url.enter": "(bir başlık yaz)", - "pages.add.url.close": "Kapat", - "pages.add.url.help": "İzin verilen karakterler: a-z küçük harfler, 0-9 ve normal kesik çizgiler", - "pages.add.template.label": "Şablon", - "pages.add.error.create": "Sayfa oluşturulamadı", - "pages.add.error.title": "Başlık bulunamadı", - "pages.add.error.template": "Şablon bulunamadı", - "pages.add.error.max.headline": "Yeni sayfalar eklemeye izin verilmedi", - "pages.add.error.max.text": "Mevcut sayfa sahip olabilecek maksimum alt sayfa sayısına erişti", - "pages.url.uid.label": "Web Adres-uzantısı", - "pages.url.uid.label.option": "Başlıktan oluştur", - "pages.url.error.exists": "Bir sayfa hali hazırda aynı web adres-uzantısına sahip", - "pages.url.error.move": "Web adres-uzantısı değiştirilemedi", - "pages.url.error.rights": "Bu sayfanın adresini değiştirilemez", - "pages.template.select.label": "Şablon", - "pages.template.warning.text": "Şablonu değiştirdiğinizde ilgili alanlar da güncellenecek", - "pages.template.warning.removed": "Kaldırılan alanlar", - "pages.template.warning.replaced": "Değiştirilen alanlar", - "pages.template.warning.added": "Eklenen alanlar", - "pages.template.error": "Bu sayfa için şablon değiştirilemez", - "pages.toggle.position": "Pozisyon", - "pages.toggle.invisible": "görünmez", - "pages.toggle.publish": "Bu sayfanın durumunu **görünür** olarak değiştirmek istediğinizden emin misiniz?", - "pages.toggle.hide": "Bu sayfanın durumunu **görünmez** olarak değiştirmek istediğinizden emin misiniz?", - "pages.toggle.error.error": "Hata sayfasının durumu değiştirilemez", - "pages.delete.headline": "Bu sayfayı silmek istediğinizden emin misiniz?", - "pages.delete.error.home.headline": "Anasayfa silinemez", - "pages.delete.error.home.text": "Anasayfayı silmeyi deniyorsunuz. Fakat bu mümkün değil, çünkü istenilmeyen etkilere neden olur.", - "pages.delete.error.error.headline": "Hata sayfası silinemedi", - "pages.delete.error.error.text": "Hata sayfasını silmeyi deniyorsunuz. Fakat bu mümkün değil, çünkü istenilmeyen etkilere neden olur.", - "pages.delete.error.children.headline": "Bu sayfa silinemedi", - "pages.delete.error.children.text": "Bu sayfa alt sayfalara sahip olduğundan dolayı silinemdi. Lütfen önce bu sayfanın alt sayfalarını siliniz.", - "pages.delete.error.blocked.headline": "Bu sayfa silinemedi", - "pages.delete.error.blocked.text": "Bu sayfa kilitli ve silinemez", - "pages.search.help": "Sayfaları web adres uzantılarına göre arayınız. Arama sonuçlarından istediğiniz sayfayı klavyenizin yukarı ve aşağı tuşları ile seçip enter tuşuna bastıktan sonra aradığınız sayfaya direk yönleneceksiniz", - "pages.search.noresults": "Herhangi bir sonuç bulunamadı. Lütfen farklı bir web adres-uzantısı ismi deneyiniz.", - "pages.error.missing": "Sayfa bulunamadı", - "subpages": "Alt Sayfalar", - "subpages.index.headline": "Alt Sayfalar:", - "subpages.index.back": "Geri", - "subpages.index.add": "Yeni bir alt sayfa ekle", - "subpages.index.add.first.text": "Bu sayfanın henüz bir alt sayfası yok", - "subpages.index.add.first.button": "İlk alt sayfanı ekle", - "subpages.index.visible": "Websitesinde gösterilecek alt sayfalar", - "subpages.index.visible.help": "Buraya websitesinde gösterilecek alt sayfaları sürükleyip bırakabilirsiniz", - "subpages.index.invisible": "Websitesinden gizlenecek alt sayfalar", - "subpages.index.invisible.help": "Buraya websitesinden gizlenecek alt sayfaları sürükleyip bırakabilirsiniz", - "subpages.add.error": "Bu sayfaya alt sayfa eklenemez", - "subpages.add.error.more": "Bu sayfaya daha fazla alt sayfa eklenemez", - "subpages.error.missing": "Sayfa bulunamadı", - "files": "Dosyalar", - "files.index.headline": "Dosyalar:", - "files.index.back": "Geri", - "files.index.upload": "Yeni bir dosya yükle", - "files.index.upload.first.text": "Bu sayfanın henüz bir dosyası yok", - "files.index.upload.first.button": "İlk dosyayı yükle", - "files.index.edit": "Düzenle", - "files.index.delete": "Sil", - "files.index.error.disabled": "Bu sayfaya dosya eklenemez", - "files.add.error.max": "Bu sayfa için maximum dosya limitine ulaşıldı", - "files.add.error.extension.missing": "Uzantısı olmayan dosya yüklenemez", - "files.add.error.extension.forbidden": "İzin verilmeyen dosya uzantısı", - "files.add.error.mime.forbidden": "İzin verilmeyen dosya tanımlayıcısı", - "files.add.error.htaccess": "htaccess dosyası yüklenemez", - "files.add.error.invisible": "Görünmez dosyalar yüklenemez", - "files.add.blueprint.type.error": "Sayfanın desteklediği formatlar:", - "files.add.blueprint.size.error": "Sayfanın izin verdiği boyut:", - "files.show.name.label": "Dosya İsmi", - "files.show.info.label": "Dosya Formatı / Büyüklüğü / Boyutları", - "files.show.link.label": "Dosyanın Web Adres Uzantısı", - "files.show.open": "Göster/indir", - "files.show.back": "Geri", - "files.show.replace": "Değiştir", - "files.show.delete": "Sil", - "files.show.error.rename": "Dosya ismi yeniden adlandırılamadı", - "files.show.error.form": "Lütfen gerekli tüm alanları doğru bir şekilde doldurunuz", - "files.upload.drop": "Dosyaları buraya sürükle bırak…", - "files.upload.click": "…veya cihazından başka bir dosya yüklemek için buraya tıkla", - "files.replace.drop": "Buraya bir dosya sürükle bırak…", - "files.replace.click": "…veya cihazındaki başka bir dosya ile değiştirmek için buraya tıkla", - "files.replace.error.type": "Yüklenecek dosyalar aynı dosya formatında olmalı", - "files.delete.headline": "Bu dosyayı silmek istediğinizden emin misiniz?", - "files.error.missing.page": "Sayfa bulunamadı", - "files.error.missing.file": "Dosya bulunamadı", - "users": "Kullanıcılar", - "users.index.headline": "Bütün kullanıcılar", - "users.index.add": "Yeni bir kullanıcı ekle", - "users.index.edit": "Düzenle", - "users.index.delete": "Sil", - "users.form.username.label": "Kullanıcı Adı", - "users.form.username.placeholder": "Kullanıcı adı seç", - "users.form.username.help": "İzin verilen karakterler: a-z küçük harfler, 0-9 ve normal kesik çizgiler", - "users.form.username.readonly": "Kullancı adı değiştirilemez", - "users.form.firstname.label": "Ad", - "users.form.lastname.label": "Soyad", - "users.form.email.label": "E-Posta", - "users.form.email.placeholder": "eposta@ornek.com", - "users.form.password.label": "Şifre", - "users.form.password.confirm.label": "Şifre Tekrarı", - "users.form.password.new.label": "Yeni Şifre", - "users.form.password.new.confirm.label": "Yeni şifre tekrarı", - "users.form.password.new.help": "Mevcut şifreyi boş bırak", - "users.form.language.label": "Dil", - "users.form.role.label": "Rol", - "users.form.options.headline": "Kullanıcı Ayarları", - "users.form.options.message": "E-Posta gönder", - "users.form.options.delete": "Bu hesabı sil", - "users.form.avatar.headline": "Profil resmi", - "users.form.avatar.upload": "Profil resmi yükle", - "users.form.avatar.replace": "Profil resmini değiştir", - "users.form.avatar.delete": "Profil resmini sil", - "users.form.back": "Kullanıcılar paneline geri dön", - "users.form.error.password.confirm": "Lütfen şifreyi doğrulayın", - "users.form.error.update": "Kullanıcı güncellenemedi", - "users.form.error.update.rights": "Bu kullanıcıyı güncellemek için yetkiniz yok", - "users.form.error.create": "Kullanıcı oluşturulamadı", - "users.form.error.permissions.title": "Account klasörü yazılabilir değil", - "users.form.error.permissions.text": "Lütfen /site/accounts klasörünün mevcut olduğundan ve yazılabilir olduğundan emin olun.", - "users.delete.headline": "Bu kullanıcıyı silmek istediğinizden emin misiniz?", - "users.delete.error": "Kullanıcı silinemedi", - "users.delete.error.permission": "Kullanıcıları silme yetkiniz yok", - "users.delete.error.permission.single": "Bu kullanıcıyı silme yetkiniz yok", - "users.delete.error.lastadmin": "Son yönetici kullanıcıyı silemezsiniz", - "users.avatar.drop": "Buraya bir profil resmi sürükle bırak…", - "users.avatar.click": "…veya cihazından başka bir profil resmi yüklemek için buraya tıkla", - "users.avatar.error.type": "Sadece JPG, PNG and GIF formatındaki dosyaları yükleyebilirsin", - "users.avatar.error.folder.headline": "Avatar klasörü yazılabilir değil", - "users.avatar.error.folder.text": "Lütfen /assets/avatars adlı klasör oluştur ve profil resmini yükleyebilmek için yazılabilir izni ver.", - "users.avatar.error.permission": "Avatarı değiştirme yetkiniz yok", - "users.avatar.delete.error": "Profil resmi silinemedi", - "users.avatar.delete.error.permission": "Bu kullanıcının avatarını silme yetkiniz yok", - "users.avatar.delete.success": "Profil resmi silindi", - "users.avatar.missing": "Bu kullanıcının avatarı yok", - "users.error.missing": "Kullanıcı bulunamadı", - "user.error.lastadmin": "Tek yönetici sensin. Bu değiştirilemez", - "form.error.missing": "Form bulunamadı", - "form.construct.error.invalid": "Geçersiz form kurucu metodu", - "fields.required": "Zorunlu", - "fields.date.label": "Tarih", - "fields.date.months": [ - "Ocak", - "Şubat", - "Mart", - "Nisan", - "Mayıs", - "Haziran", - "Temmuz", - "Ağustos", - "Eylül", - "Ekim", - "Kasım", - "Aralık" - ], - "fields.date.weekdays": [ - "Pazar", - "Pazartesi", - "Salı", - "Çarşamba", - "Perşembe", - "Cuma", - "Cumartesi" - ], - "fields.date.weekdays.short": [ - "Paz", - "Pzt", - "Sal", - "Çar", - "Per", - "Cum", - "Cmt" - ], - "fields.email.label": "E-Posta", - "fields.email.placeholder": "eposta@ornek.com", - "fields.number.label": "Numara", - "fields.number.placeholder": "#", - "fields.page.label": "Sayfa", - "fields.page.placeholder": "adres/yolu/sayfa", - "fields.password.label": "Şifre", - "fields.structure.add": "Ekle", - "fields.structure.add.first": "İlk girdini ekle", - "fields.structure.empty": "Henüz bir girdi yok", - "fields.structure.entry.error": "Öğe bulunamadı", - "fields.structure.cancel": "İptal", - "fields.structure.save": "Kaydet", - "fields.structure.edit": "Düzenle", - "fields.structure.delete": "Sil", - "fields.structure.delete.label": "Bu girdiyi silmek istediğinizden emin misiniz?", - "fields.tags.label": "Anahtar Kelimeler", - "fields.tel.label": "Telefon", - "fields.textarea.buttons.bold.label": "Kalın yazı", - "fields.textarea.buttons.bold.text": "Kalın yazı", - "fields.textarea.buttons.italic.label": "Eğik yazı", - "fields.textarea.buttons.italic.text": "Eğik yazı", - "fields.textarea.buttons.link.label": "Bağlantı", - "fields.textarea.buttons.email.label": "E-Posta", - "fields.textarea.buttons.image.label": "Resim", - "fields.textarea.buttons.file.label": "Dosya", - "fields.toggle.yes": "Evet", - "fields.toggle.no": "Hayır", - "fields.toggle.on": "Açık", - "fields.toggle.off": "Kapalı", - "fields.error.missing.controller": "Alan denetleyici dosyası eksik", - "fields.error.missing.class": "Alan kontrol sınıfı eksik", - "fields.error.route.invalid": "Geçersiz alan rotası", - "fields.error.extended": "Bu alan genişletilemez", - "editor.link.url.label": "Web Adresi Ekle", - "editor.link.text.label": "Bağlantı yazısı", - "editor.link.text.help": "Bağlantı yazısı isteğe bağlı", - "editor.email.address.label": "E-Posta Adresi Ekle", - "editor.email.address.placeholder": "eposta@ornek.com", - "editor.email.text.label": "Bağlantı yazısı", - "editor.email.text.help": "Bağlantı yazısı isteğe bağlı", - "editor.file.empty": "Bu sayfanın henüz bir dosyası yok", - "editor.image.empty": "Bu sayfanın henüz bir resmi yok", - "autocomplete.method.error": "Geçersiz otomatik doldurma metodu", - "blueprints.error.default.missing": "Varsayılan taslak dosyası eksik", - "error": "Hata", - "error.headline": "Hata" -} \ No newline at end of file diff --git a/panel/app/translations/tr/package.json b/panel/app/translations/tr/package.json deleted file mode 100644 index 1be89b1..0000000 --- a/panel/app/translations/tr/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Türkçe", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/zh_CN/core.json b/panel/app/translations/zh_CN/core.json deleted file mode 100644 index dd52dec..0000000 --- a/panel/app/translations/zh_CN/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "取消", - "add": "新增", - "addit": "新增并编辑", - "save": "保存", - "saved": "已保存!", - "change": "更改", - "delete": "删除", - "insert": "插入", - "ok": "确认", - "routes.error.invalid": "无效的控制面板URL", - "controller.error.invalid": "无效的控制器", - "controller.error.action": "无效行为", - "view.error.invalid": "无效视图:", - "options.show": "显示选项", - "options.hide": "隐藏选项", - "installation": "安装", - "installation.check.headline": "安装Kirby控制面板", - "installation.check.text": "Kirby在安装过程中遇到以下问题...", - "installation.check.retry": "重试", - "installation.check.error": "存在一些问题!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "/site/accounts不可写入", - "installation.check.error.avatars": "/assets/avatars不可写入", - "installation.check.error.blueprints": "请新增/site/blueprints文件夹", - "installation.check.error.content": "content文件夹及其内容必须可写入", - "installation.check.error.thumbs": "thumbs文件夹必须可写入", - "installation.signup.username.label": "创建首个账户", - "installation.signup.username.placeholder": "用户名", - "installation.signup.email.label": "邮箱", - "installation.signup.email.placeholder": "mail@example.com", - "installation.signup.password.label": "密码", - "installation.signup.language.label": "语言", - "installation.signup.button": "创建账户", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "用户名", - "login.password.label": "密码", - "login.error": "无效的用户名或密码", - "login.button": "Log in", - "login.log.error.permissions": "登陆的log file不可写入", - "logout": "Log out", - "topbar.error.class.definition": "Missing topbar definition for class:", - "dashboard": "仪表盘", - "dashboard.index.pages.title": "页面", - "dashboard.index.pages.edit": "编辑", - "dashboard.index.pages.add": "新增", - "dashboard.index.site.title": "网址", - "dashboard.index.account.title": "您的账户", - "dashboard.index.account.edit": "编辑", - "dashboard.index.metatags.title": "网站选项", - "dashboard.index.metatags.edit": "编辑", - "dashboard.index.history.title": "最近更新", - "dashboard.index.history.text": "您最近修改的页面会显示在这里,以便查找。", - "dashboard.index.license.title": "Kirby", - "dashboard.index.license.text": "好像您在一个公共服务器上运行没有许可证的Kirby!\n请支持一下Kirby,购买一个许可证。\n如果您已有许可证号,请把它添加到config文件中。", - "metatags": "网站选项", - "metatags.info": "Kirby信息", - "metatags.license": "Kirby", - "metatags.version.toolkit": "工具箱版本", - "metatags.version.kirby": "Kirby版本", - "metatags.version.panel": "控制面板版本", - "metatags.back": "返回控制面板", - "metatags.files": "网站文件", - "site.delete.error": "该网站不能被删除", - "pages.show.settings": "页面设置", - "pages.show.preview": "打开预览", - "pages.show.template": "模版", - "pages.show.changeurl": "更改URL", - "pages.show.invisible": "状态:不可见", - "pages.show.visible": "状态:可见", - "pages.show.changes.text": "您有未保存的修改!", - "pages.show.changes.button": "放弃", - "pages.show.delete": "删除此页", - "pages.show.subpages.title": "页面", - "pages.show.subpages.edit": "编辑", - "pages.show.subpages.add": "新增", - "pages.show.subpages.empty": "此页面没有子页面", - "pages.show.files.title": "文件", - "pages.show.files.edit": "编辑", - "pages.show.files.add": "新增", - "pages.show.files.empty": "此页面没有文件", - "pages.show.error.permissions.title": "此页面不可写入", - "pages.show.error.permissions.text": "请检查content文件夹和所有文件的修改权限", - "pages.show.error.permissions.retry": "重试", - "pages.show.error.notitle.title": "该blueprint没有标题栏", - "pages.show.error.notitle.text": "请新增标题栏并重试", - "pages.show.error.notitle.retry": "重试", - "pages.show.error.form": "请正确填写所有栏", - "pages.add.title.label": "新增页面", - "pages.add.title.placeholder": "标题", - "pages.add.url.label": "URL后缀", - "pages.add.url.enter": "(输入标题)", - "pages.add.url.close": "关闭", - "pages.add.url.help": "格式要求:小写字母a-z、数字0-9及连字符-", - "pages.add.template.label": "模版", - "pages.add.error.create": "无法新增页面", - "pages.add.error.title": "标题缺失", - "pages.add.error.template": "模版缺失", - "pages.add.error.max.headline": "新页面不允许被创建", - "pages.add.error.max.text": "当前页面的子页面数量已达上限", - "pages.url.uid.label": "URL后缀", - "pages.url.uid.label.option": "从标题创建", - "pages.url.error.exists": "含有相同后缀的页面已存在", - "pages.url.error.move": "该后缀不能被修改", - "pages.url.error.rights": "您不能更改该页面的URL", - "pages.template.select.label": "模版", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "位置", - "pages.toggle.invisible": "隐藏", - "pages.toggle.publish": "确定更改该页面的状态为可见状态?", - "pages.toggle.hide": "确定更改该页面的状态为不可见状态?", - "pages.toggle.error.error": "error页面的状态不能更改", - "pages.delete.headline": "确定删除该页面?", - "pages.delete.error.home.headline": "home页面不能被删除", - "pages.delete.error.home.text": "您正在尝试删除home页面。", - "pages.delete.error.error.headline": "error页面不能删除", - "pages.delete.error.error.text": "您正在尝试删除error页面,该行为不被允许,否则会产生不利后果。", - "pages.delete.error.children.headline": "该页面不能删除", - "pages.delete.error.children.text": "该页含有子页面,不可删除。请先删除子页面。", - "pages.delete.error.blocked.headline": "该页面不能删除", - "pages.delete.error.blocked.text": "该页面已锁定,不可删除", - "pages.search.help": "通过URL搜索页面。使用上下键进行选择,按回车键进入相应页面。", - "pages.search.noresults": "当前请求没有搜索结果。请重试。", - "pages.error.missing": "该页面找不到", - "subpages": "页面", - "subpages.index.headline": "Pages in", - "subpages.index.back": "返回", - "subpages.index.add": "新增页面", - "subpages.index.add.first.text": "该页面还没有子页面", - "subpages.index.add.first.button": "添加首个页面", - "subpages.index.visible": "可见页面", - "subpages.index.visible.help": "拖拽隐藏页面到这里以排序/使其可见", - "subpages.index.invisible": "隐藏页面", - "subpages.index.invisible.help": "拖拽可见页面到这里以撤销分类/使其隐藏", - "subpages.add.error": "该页面没有拥有子页面权限", - "subpages.add.error.more": "该页面不能再添加子页面。", - "subpages.error.missing": "该页面找不到", - "files": "文件", - "files.index.headline": "Files for", - "files.index.back": "返回", - "files.index.upload": "上传新文件", - "files.index.upload.first.text": "该页面还没有文件", - "files.index.upload.first.button": "上传首份文件", - "files.index.edit": "编辑", - "files.index.delete": "删除", - "files.index.error.disabled": "该页面不允许包含任何文件", - "files.add.error.max": "当前页面的文件数量已达上限", - "files.add.error.extension.missing": "您不可上传没有扩展名的文件", - "files.add.error.extension.forbidden": "禁用文件扩展名", - "files.add.error.mime.forbidden": "禁用MIME类型", - "files.add.error.htaccess": "htaccess文件不能被上传", - "files.add.error.invisible": "隐藏页面不能被上传", - "files.add.blueprint.type.error": "该页只允许:", - "files.add.blueprint.size.error": "页面只允许文件大小为", - "files.show.name.label": "文件名", - "files.show.info.label": "类型/大小/尺寸", - "files.show.link.label": "公共链接", - "files.show.open": "显示/下载文件", - "files.show.back": "返回", - "files.show.replace": "替换", - "files.show.delete": "删除", - "files.show.error.rename": "该文件不能被重命名", - "files.show.error.form": "请正确填写所有栏", - "files.upload.drop": "拖拽文件到这里...", - "files.upload.click": "或点击来上传", - "files.replace.drop": "拖拽文件到这里...", - "files.replace.click": "...或点击来替换", - "files.replace.error.type": "上传文件必须是同类型", - "files.delete.headline": "您确定删除这个文件?", - "files.error.missing.page": "该页面找不到", - "files.error.missing.file": "文件找不到", - "users": "用户", - "users.index.headline": "所有用户", - "users.index.add": "添加新用户", - "users.index.edit": "编辑", - "users.index.delete": "删除", - "users.form.username.label": "用户名", - "users.form.username.placeholder": "您的用户名", - "users.form.username.help": "允许字符:小写字母[a-z]和连字符[-]", - "users.form.username.readonly": "用户名不可更改", - "users.form.firstname.label": "名", - "users.form.lastname.label": "姓", - "users.form.email.label": "邮箱", - "users.form.email.placeholder": "mail@example.com", - "users.form.password.label": "密码", - "users.form.password.confirm.label": "确认密码", - "users.form.password.new.label": "新密码", - "users.form.password.new.confirm.label": "确认新密码", - "users.form.password.new.help": "保留此处空白以保留当前密码", - "users.form.language.label": "语言", - "users.form.role.label": "角色", - "users.form.options.headline": "账户选项", - "users.form.options.message": "发送邮件", - "users.form.options.delete": "删除帐户", - "users.form.avatar.headline": "用户资料图片", - "users.form.avatar.upload": "上传用户资料图片", - "users.form.avatar.replace": "替换用户资料图片", - "users.form.avatar.delete": "删除用户资料图片", - "users.form.back": "回到用户", - "users.form.error.password.confirm": "请核实密码", - "users.form.error.update": "无法更新该用户", - "users.form.error.update.rights": "您没有更新该用户权限", - "users.form.error.create": "该用户无法创建", - "users.form.error.permissions.title": "账户文件夹不可写入", - "users.form.error.permissions.text": "请确保/site/accounts 文件夹存在且可写入", - "users.delete.headline": "确定删除该用户?", - "users.delete.error": "该用户无法删除", - "users.delete.error.permission": "您没有删除用户权限", - "users.delete.error.permission.single": "您没有删除该用户权限", - "users.delete.error.lastadmin": "您不能删除仅有的admin账户", - "users.avatar.drop": "拖拽用户资料图片到这里...", - "users.avatar.click": "或点击来上传", - "users.avatar.error.type": "只能上传JPG、PNG或GIF格式文件", - "users.avatar.error.folder.headline": "avatar文件夹不可写入", - "users.avatar.error.folder.text": "请新建/assets/avatats文件夹并使其可写入,以上传用户资料图片。", - "users.avatar.error.permission": "您没有修改头像的权限", - "users.avatar.delete.error": "该用户资料图片不能被删除。", - "users.avatar.delete.error.permission": "您没有删除这个用户头像的权限", - "users.avatar.delete.success": "该用户资料图片已删除。", - "users.avatar.missing": "该用户没有头像", - "users.error.missing": "该用户找不到", - "user.error.lastadmin": "您是仅有的admin用户,不可更改。", - "form.error.missing": "表单不存在", - "form.construct.error.invalid": "Invalid form construction method", - "fields.required": "必填", - "fields.date.label": "日期", - "fields.date.months": [ - "一月", - "二月", - "三月", - "四月", - "五月", - "六月", - "七月", - "八月", - "九月", - "十月", - "十一月", - "十二月" - ], - "fields.date.weekdays": [ - "周日", - "周一", - "周二", - "周三", - "周四", - "周五", - "周六" - ], - "fields.date.weekdays.short": [ - "周日", - "周一", - "周二", - "周三", - "周四", - "周五", - "周六" - ], - "fields.email.label": "邮箱", - "fields.email.placeholder": "mail@example.com", - "fields.number.label": "数字", - "fields.number.placeholder": "#", - "fields.page.label": "页面", - "fields.page.placeholder": "path/to/page", - "fields.password.label": "密码", - "fields.structure.add": "新增", - "fields.structure.add.first": "Add the first entry", - "fields.structure.empty": "No entries yet.", - "fields.structure.entry.error": "该条目无法找到", - "fields.structure.cancel": "取消", - "fields.structure.save": "确认", - "fields.structure.edit": "编辑", - "fields.structure.delete": "删除", - "fields.structure.delete.label": "确定删除这项纪录?", - "fields.tags.label": "标签", - "fields.tel.label": "电话", - "fields.textarea.buttons.bold.label": "粗体文本", - "fields.textarea.buttons.bold.text": "粗体文本", - "fields.textarea.buttons.italic.label": "斜体文本", - "fields.textarea.buttons.italic.text": "斜体文本", - "fields.textarea.buttons.link.label": "链接", - "fields.textarea.buttons.email.label": "邮箱", - "fields.textarea.buttons.image.label": "图像", - "fields.textarea.buttons.file.label": "文件", - "fields.toggle.yes": "是", - "fields.toggle.no": "否", - "fields.toggle.on": "开启", - "fields.toggle.off": "关闭", - "fields.error.missing.controller": "The field controller file is missing", - "fields.error.missing.class": "The field controller class is missing", - "fields.error.route.invalid": "Invalid field route", - "fields.error.extended": "The field cannot be extended", - "editor.link.url.label": "插入URL", - "editor.link.text.label": "链接文本", - "editor.link.text.help": "链接文本可选", - "editor.email.address.label": "插入邮箱地址", - "editor.email.address.placeholder": "mail@example.com", - "editor.email.text.label": "链接文本", - "editor.email.text.help": "链接文本可选", - "editor.file.empty": "该页面没有文件", - "editor.image.empty": "该页没有图像", - "autocomplete.method.error": "无效的自动完成方法", - "blueprints.error.default.missing": "默认blueprint缺失", - "error": "错误", - "error.headline": "错误" -} \ No newline at end of file diff --git a/panel/app/translations/zh_CN/package.json b/panel/app/translations/zh_CN/package.json deleted file mode 100644 index 52082f2..0000000 --- a/panel/app/translations/zh_CN/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "简体中文(大陆)‎", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/translations/zh_TW/core.json b/panel/app/translations/zh_TW/core.json deleted file mode 100644 index 1f1e082..0000000 --- a/panel/app/translations/zh_TW/core.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cancel": "取消", - "add": "新增", - "addit": "Add & Edit", - "save": "儲存", - "saved": "已儲存", - "change": "Change", - "delete": "刪除", - "insert": "插入", - "ok": "好", - "routes.error.invalid": "Invalid Panel URL", - "controller.error.invalid": "Invalid controller", - "controller.error.action": "Invalid action", - "view.error.invalid": "Invalid view:", - "options.show": "顯示選項", - "options.hide": "隱藏選項", - "installation": "安裝", - "installation.check.headline": "安裝Kirby控制台", - "installation.check.text": "Kirby在安裝過程中遇到以下問題…", - "installation.check.retry": "重試", - "installation.check.error": "這裡發生了一些問題!", - "installation.check.error.allowed": "You are only allowed to run the panel installer on a local machine or by setting the option panel.install to true in your /site/config/config.php", - "installation.check.error.accounts": "您沒有「/site/accounts」資料夾的修改權限", - "installation.check.error.avatars": "您沒有「/assets/avatars」資料夾的修改權限", - "installation.check.error.blueprints": "請新增「/site/blueprints」資料夾", - "installation.check.error.content": "您沒有「/content」資料夾的修改權限", - "installation.check.error.thumbs": "您沒有「/thumbs」資料夾的修改權限", - "installation.signup.username.label": "建立首位使用者", - "installation.signup.username.placeholder": "帳號", - "installation.signup.email.label": "Email", - "installation.signup.email.placeholder": "mail@example.com", - "installation.signup.password.label": "密碼", - "installation.signup.language.label": "慣用語言", - "installation.signup.button": "建立", - "login": "Log in", - "login.welcome": "Please log in with your new account", - "login.username.label": "帳號", - "login.password.label": "密碼", - "login.error": "帳號與密碼不正確!", - "login.button": "Log in", - "login.log.error.permissions": "Login log file is not writable.", - "logout": "Log out", - "topbar.error.class.definition": "Missing topbar definition for class:", - "dashboard": "控制台", - "dashboard.index.pages.title": "頁面", - "dashboard.index.pages.edit": "編輯", - "dashboard.index.pages.add": "新增", - "dashboard.index.site.title": "網址", - "dashboard.index.account.title": "您的帳號", - "dashboard.index.account.edit": "編輯", - "dashboard.index.metatags.title": "網站資料", - "dashboard.index.metatags.edit": "編輯", - "dashboard.index.history.title": "頁面編輯紀錄", - "dashboard.index.history.text": "您最近修改的頁面會顯示在這裡,方便您再次編輯。", - "dashboard.index.license.title": "Kirby license", - "dashboard.index.license.text": "It seems you are running Kirby on a public server without a valid license!\n\nPlease, support Kirby and (link: {buy} text: buy a license now)\n\nIf you already have a license key, just add it to your config file: (link: {docs} text: site/config/config.php)", - "metatags": "網站資料", - "metatags.info": "Kirby info", - "metatags.license": "Kirby license", - "metatags.version.toolkit": "Toolkit version", - "metatags.version.kirby": "Kirby version", - "metatags.version.panel": "Panel version", - "metatags.back": "返回控制台", - "metatags.files": "Site files", - "site.delete.error": "The site cannot be deleted", - "pages.show.settings": "頁面設定", - "pages.show.preview": "在新分頁中瀏覽此頁面", - "pages.show.template": "頁面模板", - "pages.show.changeurl": "更改頁面網址", - "pages.show.invisible": "Status: invisible", - "pages.show.visible": "Status: visible", - "pages.show.changes.text": "You have unsaved changes!", - "pages.show.changes.button": "Discard", - "pages.show.delete": "刪除此頁面", - "pages.show.subpages.title": "子頁面", - "pages.show.subpages.edit": "編輯", - "pages.show.subpages.add": "新增", - "pages.show.subpages.empty": "目前沒有子頁面", - "pages.show.files.title": "附加檔案", - "pages.show.files.edit": "編輯", - "pages.show.files.add": "上傳", - "pages.show.files.empty": "目前沒有附加檔案", - "pages.show.error.permissions.title": "您沒有修改此頁面的權限", - "pages.show.error.permissions.text": "請確認「/content」資料夾的修改權限", - "pages.show.error.permissions.retry": "重試", - "pages.show.error.notitle.title": "模板的「blueprint」中沒有「title」欄位", - "pages.show.error.notitle.text": "請在新增「title」欄位後重試", - "pages.show.error.notitle.retry": "重試", - "pages.show.error.form": "請正確填入所有欄位", - "pages.add.title.label": "新增頁面", - "pages.add.title.placeholder": "頁面標題", - "pages.add.url.label": "頁面網址", - "pages.add.url.enter": "(從頁面標題輸入)", - "pages.add.url.close": "關閉", - "pages.add.url.help": "可用字元:英文小寫 a-z、數字 0-9以及分號「-」", - "pages.add.template.label": "頁面模板", - "pages.add.error.create": "The page could not be created", - "pages.add.error.title": "沒有頁面標題", - "pages.add.error.template": "沒有頁面模板", - "pages.add.error.max.headline": "無法新增頁面", - "pages.add.error.max.text": "子頁面數量已達上限", - "pages.url.uid.label": "頁面網址", - "pages.url.uid.label.option": "從頁面標題輸入", - "pages.url.error.exists": "已有重複的頁面網址", - "pages.url.error.move": "無法更改頁面網址", - "pages.url.error.rights": "You cannot change the URL of this page", - "pages.template.select.label": "頁面模板", - "pages.template.warning.text": "The following fields will change, when you switch the template", - "pages.template.warning.removed": "Removed fields", - "pages.template.warning.replaced": "Replaced fields", - "pages.template.warning.added": "Added fields", - "pages.template.error": "The template for this page cannot be changed", - "pages.toggle.position": "Position", - "pages.toggle.invisible": "invisible", - "pages.toggle.publish": "Do you really want to change the status of this page to **visible?**", - "pages.toggle.hide": "Do you really want to change the status of this page to **invisible?**", - "pages.toggle.error.error": "The status of the error page cannot be changed", - "pages.delete.headline": "確認刪除此頁面?", - "pages.delete.error.home.headline": "不可刪除首頁", - "pages.delete.error.home.text": "如果刪除首頁將導致不可預期的後果。", - "pages.delete.error.error.headline": "不可刪除出錯頁面", - "pages.delete.error.error.text": "如果刪除出錯頁面將無法重新引導訪客。", - "pages.delete.error.children.headline": "無法刪除頁面", - "pages.delete.error.children.text": "此頁面底下有其他子頁面,請先刪除所有子頁面。", - "pages.delete.error.blocked.headline": "頁面不可被刪除", - "pages.delete.error.blocked.text": "此為保護頁面", - "pages.search.help": "透過頁面網址搜尋(可用上下鍵選擇並按 Enter 鍵進入)", - "pages.search.noresults": "沒有符合關鍵字的搜尋結果", - "pages.error.missing": "找不到頁面", - "subpages": "頁面", - "subpages.index.headline": "所有子頁面 in", - "subpages.index.back": "返回", - "subpages.index.add": "新增頁面", - "subpages.index.add.first.text": "目前沒有子頁面", - "subpages.index.add.first.button": "新增", - "subpages.index.visible": "可見頁面", - "subpages.index.visible.help": "可拖放隱藏頁面到這裡", - "subpages.index.invisible": "隱藏頁面", - "subpages.index.invisible.help": "可拖放頁面到這裡將它們隱藏", - "subpages.add.error": "This page is not allowed to have subpages", - "subpages.add.error.more": "This page cannot have any more subpages", - "subpages.error.missing": "找不到頁面", - "files": "附加檔案", - "files.index.headline": "附加檔案 for", - "files.index.back": "返回", - "files.index.upload": "上傳附加檔案", - "files.index.upload.first.text": "目前沒有附加檔案", - "files.index.upload.first.button": "上傳", - "files.index.edit": "編輯", - "files.index.delete": "刪除", - "files.index.error.disabled": "The page is not allowed to have any files", - "files.add.error.max": "The maximum number of files for the current page has been reached.", - "files.add.error.extension.missing": "You cannot upload files without extension", - "files.add.error.extension.forbidden": "Forbidden file extension", - "files.add.error.mime.forbidden": "Forbidden mime type", - "files.add.error.htaccess": "htaccess files cannot be uploaded", - "files.add.error.invisible": "Invisible files cannot be uploaded", - "files.add.blueprint.type.error": "Page only allows:", - "files.add.blueprint.size.error": "Page only allows file size of", - "files.show.name.label": "檔案名稱", - "files.show.info.label": "檔案格式 / 大小 / 尺寸", - "files.show.link.label": "公開連結", - "files.show.open": "開啟/下載", - "files.show.back": "返回", - "files.show.replace": "更換", - "files.show.delete": "刪除", - "files.show.error.rename": "無法重新命名檔案", - "files.show.error.form": "請正確填入所有欄位", - "files.upload.drop": "請拖放檔案到這裡", - "files.upload.click": "...或按此上傳", - "files.replace.drop": "請拖放檔案到這裡", - "files.replace.click": "...或按此上傳", - "files.replace.error.type": "必須上傳相同格式的檔案", - "files.delete.headline": "確認刪除檔案?", - "files.error.missing.page": "找不到頁面", - "files.error.missing.file": "找不到檔案", - "users": "使用者", - "users.index.headline": "所有使用者", - "users.index.add": "新增使用者", - "users.index.edit": "編輯", - "users.index.delete": "刪除", - "users.form.username.label": "帳號", - "users.form.username.placeholder": "帳號", - "users.form.username.help": "可用字元:英文小寫 a-z、數字 0-9以及分號「-」", - "users.form.username.readonly": "帳號不可更改", - "users.form.firstname.label": "名字", - "users.form.lastname.label": "姓氏", - "users.form.email.label": "Email", - "users.form.email.placeholder": "mail@example.com", - "users.form.password.label": "密碼", - "users.form.password.confirm.label": "再次確認密碼", - "users.form.password.new.label": "更改密碼", - "users.form.password.new.confirm.label": "再次確認密碼", - "users.form.password.new.help": "若要更改密碼請填入新密碼", - "users.form.language.label": "慣用語言", - "users.form.role.label": "權限", - "users.form.options.headline": "使用者選項", - "users.form.options.message": "傳送郵件", - "users.form.options.delete": "刪除使用者", - "users.form.avatar.headline": "使用者照片", - "users.form.avatar.upload": "上傳使用者照片", - "users.form.avatar.replace": "更換使用者照片", - "users.form.avatar.delete": "刪除使用者照片", - "users.form.back": "返回使用者名單", - "users.form.error.password.confirm": "請確認密碼無誤", - "users.form.error.update": "無法更改使用者", - "users.form.error.update.rights": "You are not allowed to update this user", - "users.form.error.create": "無法新增使用者", - "users.form.error.permissions.title": "您沒有「/site/accounts」資料夾的修改權限", - "users.form.error.permissions.text": "請確認「/site/accounts」資料夾是否存在並具有修改權限", - "users.delete.headline": "確認刪除使用者?", - "users.delete.error": "該使用者不可被刪除", - "users.delete.error.permission": "You are not allowed to delete users", - "users.delete.error.permission.single": "You are not allowed to delete this user", - "users.delete.error.lastadmin": "You cannot delete the last admin", - "users.avatar.drop": "請拖放照片到這裡", - "users.avatar.click": "...或按此上傳", - "users.avatar.error.type": "只能使用 JPG、PNG 和 GIF 格式的圖片", - "users.avatar.error.folder.headline": "您沒有「/assets/avatars」資料夾的修改權限", - "users.avatar.error.folder.text": "請確認「/assets/avatars」資料夾是否存在並具有修改權限", - "users.avatar.error.permission": "You are not allowed to change the avatar", - "users.avatar.delete.error": "無法刪除使用者照片", - "users.avatar.delete.error.permission": "You are not allowed to delete the avatar of this user", - "users.avatar.delete.success": "已刪除使用者照片", - "users.avatar.missing": "This user has no avatar", - "users.error.missing": "找不到使用者", - "user.error.lastadmin": "You are the only admin. This cannot be changed.", - "form.error.missing": "The form cannot be found", - "form.construct.error.invalid": "Invalid form construction method", - "fields.required": "必要欄位", - "fields.date.label": "日期", - "fields.date.months": [ - "一月", - "二月", - "三月", - "四月", - "五月", - "六月", - "七月", - "八月", - "九月", - "十月", - "十一月", - "十二月" - ], - "fields.date.weekdays": [ - "週日", - "週一", - "週二", - "週三", - "週四", - "週五", - "週六" - ], - "fields.date.weekdays.short": [ - "日", - "一", - "二", - "三", - "四", - "五", - "六" - ], - "fields.email.label": "Email", - "fields.email.placeholder": "mail@example.com", - "fields.number.label": "數字", - "fields.number.placeholder": "#", - "fields.page.label": "頁面", - "fields.page.placeholder": "頁面路徑", - "fields.password.label": "密碼", - "fields.structure.add": "新增", - "fields.structure.add.first": "新增第一筆資料", - "fields.structure.empty": "還沒有資料", - "fields.structure.entry.error": "The item could not be found", - "fields.structure.cancel": "取消", - "fields.structure.save": "儲存", - "fields.structure.edit": "編輯", - "fields.structure.delete": "刪除", - "fields.structure.delete.label": "Do you really want to delete this entry?", - "fields.tags.label": "標籤", - "fields.tel.label": "電話", - "fields.textarea.buttons.bold.label": "粗體", - "fields.textarea.buttons.bold.text": "粗體", - "fields.textarea.buttons.italic.label": "斜體", - "fields.textarea.buttons.italic.text": "斜體", - "fields.textarea.buttons.link.label": "連結", - "fields.textarea.buttons.email.label": "Email", - "fields.textarea.buttons.image.label": "圖片", - "fields.textarea.buttons.file.label": "檔案", - "fields.toggle.yes": "是", - "fields.toggle.no": "否", - "fields.toggle.on": "開啟", - "fields.toggle.off": "關閉", - "fields.error.missing.controller": "The field controller file is missing", - "fields.error.missing.class": "The field controller class is missing", - "fields.error.route.invalid": "Invalid field route", - "fields.error.extended": "The field cannot be extended", - "editor.link.url.label": "插入網址連結", - "editor.link.text.label": "連結文字", - "editor.link.text.help": "連結文字可選填", - "editor.email.address.label": "插入 Email 連結", - "editor.email.address.placeholder": "mail@example.com", - "editor.email.text.label": "連結文字", - "editor.email.text.help": "連結文字可選填", - "editor.file.empty": "無可用附加檔案", - "editor.image.empty": "無可用附加圖片檔案", - "autocomplete.method.error": "Invalid autocomplete method", - "blueprints.error.default.missing": "Missing default blueprint", - "error": "錯誤", - "error.headline": "錯誤" -} \ No newline at end of file diff --git a/panel/app/translations/zh_TW/package.json b/panel/app/translations/zh_TW/package.json deleted file mode 100644 index 7b5d8f1..0000000 --- a/panel/app/translations/zh_TW/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "繁體中文(台灣)‎", - "direction": "ltr" -} \ No newline at end of file diff --git a/panel/app/views/auth/block.php b/panel/app/views/auth/block.php deleted file mode 100644 index 043e05a..0000000 --- a/panel/app/views/auth/block.php +++ /dev/null @@ -1,16 +0,0 @@ - - - \ No newline at end of file diff --git a/panel/app/views/auth/error.php b/panel/app/views/auth/error.php deleted file mode 100644 index 17804a9..0000000 --- a/panel/app/views/auth/error.php +++ /dev/null @@ -1,16 +0,0 @@ - - - \ No newline at end of file diff --git a/panel/app/views/auth/login.php b/panel/app/views/auth/login.php deleted file mode 100644 index 0bebad8..0000000 --- a/panel/app/views/auth/login.php +++ /dev/null @@ -1,19 +0,0 @@ - - - \ No newline at end of file diff --git a/panel/app/views/avatars/delete.php b/panel/app/views/avatars/delete.php deleted file mode 100644 index fd34175..0000000 --- a/panel/app/views/avatars/delete.php +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/views/dashboard/index.php b/panel/app/views/dashboard/index.php deleted file mode 100644 index 2ffb4d5..0000000 --- a/panel/app/views/dashboard/index.php +++ /dev/null @@ -1,49 +0,0 @@ -
    - -
    - - $widget): ?> - -
    - -

    - - - - href=""> - - - - - - - - - - - - - - - - data-shortcut="" href=""> - - href=""> - - - - - - - - -

    - - - -
    - - -
    - -
    \ No newline at end of file diff --git a/panel/app/views/error/index.php b/panel/app/views/error/index.php deleted file mode 100644 index d9be728..0000000 --- a/panel/app/views/error/index.php +++ /dev/null @@ -1,4 +0,0 @@ -
    -

    -

    -
    \ No newline at end of file diff --git a/panel/app/views/error/modal.php b/panel/app/views/error/modal.php deleted file mode 100644 index 681eedf..0000000 --- a/panel/app/views/error/modal.php +++ /dev/null @@ -1,18 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/views/files/delete.php b/panel/app/views/files/delete.php deleted file mode 100644 index fd34175..0000000 --- a/panel/app/views/files/delete.php +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/views/files/edit.php b/panel/app/views/files/edit.php deleted file mode 100644 index 57e4370..0000000 --- a/panel/app/views/files/edit.php +++ /dev/null @@ -1,88 +0,0 @@ -
    - -
    - - - - - extension() == 'svg'): ?> - - canHavePreview()): ?> - <?php __($file->filename()) ?> - - - filename()) ?> - type() . ' / ' . $file->niceSize()) ?> - - - - -
    - - - -
    - - - - \ No newline at end of file diff --git a/panel/app/views/files/index.php b/panel/app/views/files/index.php deleted file mode 100644 index 23068be..0000000 --- a/panel/app/views/files/index.php +++ /dev/null @@ -1,104 +0,0 @@ -
    - -

    - - isSite()): ?> - - - title()) ?> - - ( count() ?> ) - - - - - - - - hasFiles() and $page->canHaveMoreFiles()): ?> - - - - - -

    - - count()): ?> - - - - -
    -
    -

    - canHaveMoreFiles()) : ?> - - - - -
    -
    - - - -
    - - - - \ No newline at end of file diff --git a/panel/app/views/installation/index.php b/panel/app/views/installation/index.php deleted file mode 100644 index 41e2725..0000000 --- a/panel/app/views/installation/index.php +++ /dev/null @@ -1,23 +0,0 @@ - - - \ No newline at end of file diff --git a/panel/app/views/options/index.php b/panel/app/views/options/index.php deleted file mode 100644 index 30e48f9..0000000 --- a/panel/app/views/options/index.php +++ /dev/null @@ -1,62 +0,0 @@ -
    - - - -
    -
    - -
    -
    - -
    - - \ No newline at end of file diff --git a/panel/app/views/pages/add.php b/panel/app/views/pages/add.php deleted file mode 100644 index 9299152..0000000 --- a/panel/app/views/pages/add.php +++ /dev/null @@ -1,25 +0,0 @@ - - - \ No newline at end of file diff --git a/panel/app/views/pages/delete.php b/panel/app/views/pages/delete.php deleted file mode 100644 index fd34175..0000000 --- a/panel/app/views/pages/delete.php +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/views/pages/edit.php b/panel/app/views/pages/edit.php deleted file mode 100644 index d8c497f..0000000 --- a/panel/app/views/pages/edit.php +++ /dev/null @@ -1,31 +0,0 @@ -
    - - - -
    -
    - - isWritable()): ?> -
    -

    - -

    -
    -

    -
    -
    - - - -
    -
    - - - - -
    -
    - -
    - - \ No newline at end of file diff --git a/panel/app/views/pages/template.php b/panel/app/views/pages/template.php deleted file mode 100644 index 21d06e5..0000000 --- a/panel/app/views/pages/template.php +++ /dev/null @@ -1,21 +0,0 @@ - - \ No newline at end of file diff --git a/panel/app/views/pages/toggle.php b/panel/app/views/pages/toggle.php deleted file mode 100644 index fd34175..0000000 --- a/panel/app/views/pages/toggle.php +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/views/pages/url.php b/panel/app/views/pages/url.php deleted file mode 100644 index e9e1dc3..0000000 --- a/panel/app/views/pages/url.php +++ /dev/null @@ -1,33 +0,0 @@ - - - \ No newline at end of file diff --git a/panel/app/views/search/results.php b/panel/app/views/search/results.php deleted file mode 100644 index 5338d9b..0000000 --- a/panel/app/views/search/results.php +++ /dev/null @@ -1,35 +0,0 @@ -count()): ?> -
    - -
    - - -count()): ?> -
    - -
    - \ No newline at end of file diff --git a/panel/app/views/subpages/index.php b/panel/app/views/subpages/index.php deleted file mode 100644 index 8af0578..0000000 --- a/panel/app/views/subpages/index.php +++ /dev/null @@ -1,157 +0,0 @@ -
    -

    - - isSite()): ?> - - - title()) ?> - - - - - - - - - children()->count()): ?> - - - - - - - -

    - - hasChildren()): ?> -
    - -
    -

    - - ( total() ?> ) - -

    - -
    -
    - pages() as $subpage): ?> - $page, 'subpage' => $subpage)) ?> - -
    -
    - - pagination() ?> - - total()): ?> -
    - -
    - - -
    -

    - - ( total() ?> ) - -

    - -
    -
    - - pages() as $subpage): ?> - $page, 'subpage' => $subpage)) ?> - - -
    -
    - - pagination() ?> - - total()): ?> -
    - -
    - - -
    - -
    - - - - - -
    -
    -

    - - - -
    -
    - - - - -
    - - \ No newline at end of file diff --git a/panel/app/views/users/delete.php b/panel/app/views/users/delete.php deleted file mode 100644 index fd34175..0000000 --- a/panel/app/views/users/delete.php +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/views/users/edit.php b/panel/app/views/users/edit.php deleted file mode 100644 index 06b643e..0000000 --- a/panel/app/views/users/edit.php +++ /dev/null @@ -1,108 +0,0 @@ -
    - - - -
    -
    - -
    -

    - -

    -
    -

    -
    -
    -
    - - - -
    -
    - -
    - - \ No newline at end of file diff --git a/panel/app/views/users/index.php b/panel/app/views/users/index.php deleted file mode 100644 index 3072f7a..0000000 --- a/panel/app/views/users/index.php +++ /dev/null @@ -1,60 +0,0 @@ -
    - -

    - - - ( pagination()->items() ?> ) - - - - - - - - -

    - -
    - -
    - - isCurrent()): ?> - - -
    - -
    - - - -
    \ No newline at end of file diff --git a/panel/app/widgets/account/account.html.php b/panel/app/widgets/account/account.html.php deleted file mode 100644 index ffc5ef7..0000000 --- a/panel/app/widgets/account/account.html.php +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/widgets/account/account.php b/panel/app/widgets/account/account.php deleted file mode 100644 index d369ed8..0000000 --- a/panel/app/widgets/account/account.php +++ /dev/null @@ -1,22 +0,0 @@ -user(); - -return array( - 'title' => array( - 'text' => l('dashboard.index.account.title'), - 'link' => $user->url('edit'), - ), - 'options' => array( - array( - 'text' => l('dashboard.index.account.edit'), - 'icon' => 'pencil', - 'link' => $user->url('edit') - ) - ), - 'html' => function() use($user) { - return tpl::load(__DIR__ . DS . 'account.html.php', array( - 'user' => $user - )); - } -); \ No newline at end of file diff --git a/panel/app/widgets/history/history.html.php b/panel/app/widgets/history/history.html.php deleted file mode 100644 index 4d28c24..0000000 --- a/panel/app/widgets/history/history.html.php +++ /dev/null @@ -1,18 +0,0 @@ - diff --git a/panel/app/widgets/history/history.php b/panel/app/widgets/history/history.php deleted file mode 100644 index fd50020..0000000 --- a/panel/app/widgets/history/history.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - 'text' => l('dashboard.index.history.title'), - 'link' => false, - ), - 'html' => function() { - return tpl::load(__DIR__ . DS . 'history.html.php', array( - 'history' => panel()->user()->history()->get() - )); - } -); \ No newline at end of file diff --git a/panel/app/widgets/license/license.html.php b/panel/app/widgets/license/license.html.php deleted file mode 100644 index ae0bb43..0000000 --- a/panel/app/widgets/license/license.html.php +++ /dev/null @@ -1,15 +0,0 @@ - -
    -
    - -
    -
    \ No newline at end of file diff --git a/panel/app/widgets/license/license.php b/panel/app/widgets/license/license.php deleted file mode 100644 index 006904a..0000000 --- a/panel/app/widgets/license/license.php +++ /dev/null @@ -1,25 +0,0 @@ -license(); - -if($license->type() == 'trial' and !$license->local()) { - - return array( - 'title' => array( - 'text' => l('dashboard.index.license.title'), - 'link' => false, - 'compressed' => false - ), - 'html' => function() { - return tpl::load(__DIR__ . DS . 'license.html.php', array( - 'text' => kirbytext(str::template(l('dashboard.index.license.text'), array( - 'buy' => 'http://getkirby.com/buy', - 'docs' => 'http://getkirby.com/docs/installation/license-code' - ))) - )); - } - ); - -} else { - return false; -} \ No newline at end of file diff --git a/panel/app/widgets/pages/pages.html.php b/panel/app/widgets/pages/pages.html.php deleted file mode 100644 index 785f4a3..0000000 --- a/panel/app/widgets/pages/pages.html.php +++ /dev/null @@ -1,5 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/widgets/pages/pages.php b/panel/app/widgets/pages/pages.php deleted file mode 100644 index a2ffd01..0000000 --- a/panel/app/widgets/pages/pages.php +++ /dev/null @@ -1,36 +0,0 @@ -site(); -$options = array(); - -if($site->canHaveSubpages()) { - $options[] = array( - 'text' => l('dashboard.index.pages.edit'), - 'icon' => 'pencil', - 'link' => $site->url('subpages') - ); -} - -if($addbutton = $site->addButton()) { - $options[] = array( - 'text' => l('dashboard.index.pages.add'), - 'icon' => 'plus-circle', - 'link' => $addbutton->url(), - 'modal' => $addbutton->modal(), - 'key' => '+', - ); -} - -return array( - 'title' => array( - 'text' => l('dashboard.index.pages.title'), - 'link' => $site->url('subpages'), - 'compressed' => true - ), - 'options' => $options, - 'html' => function() use($site) { - return tpl::load(__DIR__ . DS . 'pages.html.php', array( - 'pages' => $site->children()->paginated('sidebar') - )); - } -); \ No newline at end of file diff --git a/panel/app/widgets/site/site.html.php b/panel/app/widgets/site/site.html.php deleted file mode 100644 index 5f4c1d9..0000000 --- a/panel/app/widgets/site/site.html.php +++ /dev/null @@ -1,8 +0,0 @@ - \ No newline at end of file diff --git a/panel/app/widgets/site/site.php b/panel/app/widgets/site/site.php deleted file mode 100644 index 304f28b..0000000 --- a/panel/app/widgets/site/site.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - 'text' => l('dashboard.index.site.title'), - 'link' => url(), - 'target' => '_blank', - ), - 'html' => function() { - return tpl::load(__DIR__ . DS . 'site.html.php'); - } -); \ No newline at end of file diff --git a/panel/assets/css/form.min.css b/panel/assets/css/form.min.css deleted file mode 100644 index e3daf73..0000000 --- a/panel/assets/css/form.min.css +++ /dev/null @@ -1 +0,0 @@ -.field-with-headline:first-child{padding-top:0}.field-with-headline{counter-increment:count;padding-top:6em}.field-with-headline .hgroup span{padding-left:1.5em}.field-with-headline .hgroup:before{position:absolute;content:counter(count,decimal-leading-zero);left:0;color:#8dae28;font-weight:400}.field-with-image select{margin-left:3rem}.field-with-image .input-preview{position:absolute;top:2px;left:2px;bottom:2px;width:2.75em;background:url(../images/pattern.png)}.field-with-image .input-preview figure{display:block;width:100%;height:100%;background-repeat:no-repeat;background-position:center center;background-size:cover}.structure{padding-bottom:.5em}.structure-entry{background:#fff;border:2px solid #ddd;margin-bottom:.5em}.structure-readonly .structure-entry{background:#efefef;color:#777}.structure-entry:last-child{margin-bottom:0}.structure-entry-content{padding:1em 1.5em;border-bottom:1px solid #efefef}.structure[data-sortable=true] .structure-entry-content{cursor:move}.structure-entry-options .btn{padding:.75em 1.5em;width:50%;float:left;border-right:1px solid #efefef}.structure-empty{padding:1.5em;background:#ddd}.fileview-sidebar .structure-empty{background:0 0;border-radius:5px;border:1px dashed #ddd;padding:1rem 1.5rem 1.25rem}.structure-empty a{border-bottom:2px solid #aaa;margin-left:.5em}.fileview-sidebar .structure-empty a{display:inline-block;margin-left:0}.structure-empty a:hover{border-color:#000}.structure-add-button{cursor:pointer}.structure-table{width:100%;border-spacing:0;border:2px solid #ddd;border-bottom:1px solid #ddd;border-right:1px solid #ddd;table-layout:fixed}.structure-table td,.structure-table th{background:#fff;border-bottom:1px solid #ddd;border-right:1px solid #ddd;text-align:left;vertical-align:top}.structure-table th{padding:.5em;font-weight:400;color:#777;font-style:italic}.structure-table td a{display:block;padding:.5em;overflow:hidden;width:100%;text-overflow:ellipsis;cursor:move}.structure-table-options{width:3rem;text-align:center}.structure-table .structure-table-options a{text-align:center;cursor:pointer}.structure-sortable-helper{border-top:1px solid #ddd;border-left:1px solid #ddd}.field-counter{position:absolute;z-index:-1;right:0;top:0;text-align:right;font-size:.9em;line-height:1.66666666666667}.field-counter.outside-range{color:#b3000a} \ No newline at end of file diff --git a/panel/assets/css/panel.min.css b/panel/assets/css/panel.min.css deleted file mode 100644 index b65c47f..0000000 --- a/panel/assets/css/panel.min.css +++ /dev/null @@ -1,4 +0,0 @@ -@charset "UTF-8";body.ltr .shiv-left:after,body.rtl .shiv-right:after{left:-2em}#nprogress,.field-icon{pointer-events:none}.dashboard-items,.input-list-item,.nav>li{list-style:none}.btn-with-icon,.cut,.dashboard-item,.draggable-helper,.dropdown-list>li,.field-buttons,.tag .tag-label{white-space:nowrap}.breadcrumb-label:after,.breadcrumb-link:after,.breadcrumb-link:before,.breadcrumb-list:after,.cf:after,.field-buttons:after,.field-buttons:before,.hgroup a:after,.languages-toggle span:after,.shiv:after,.sidebar-toggle:after,.topbar .message-content:after,body>.message .message-content:after,form.loading:after{content:""}.cut,.dashboard-item-text,.dropdown-list>li>a,.input-list-item .input,.uid-preview{text-overflow:ellipsis}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:400;src:url(../fonts/sourcesanspro-400.woff2) format("woff2"),url(../fonts/sourcesanspro-400.woff) format("woff")}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:600;src:url(../fonts/sourcesanspro-600.woff2) format("woff2"),url(../fonts/sourcesanspro-600.woff) format("woff")}@font-face{font-family:'Source Sans Pro';font-style:italic;font-weight:400;src:url(../fonts/sourcesanspro-400-italic.woff2) format("woff2"),url(../fonts/sourcesanspro-400-italic.woff) format("woff")}*,:after,:before{margin:0;padding:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.text figure,.text p{margin-bottom:1.5em}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}abbr{border:none}img{max-width:100%}img.lazy{opacity:0;-webkit-transition:opacity .3s;-moz-transition:opacity .3s;-ms-transition:opacity .3s;transition:opacity .3s}img.lazy.has-loaded{opacity:1}body,html{height:100%}body.rtl{direction:rtl}.cf:after{display:table;clear:both}.cut{overflow-x:hidden}.hidden{display:none!important}.nav>li>a,.text figure,.uid-preview,hr{display:block}.grey{background:#efefef}.white{background:#fff}.app{padding-top:3em;background:#efefef}.section{padding:1.5em}.bars{position:relative;min-height:100%}.draggable-helper{position:fixed;z-index:10000;background:#000;padding:.25em 1em;color:#fff;width:auto!important;list-style:none;border-radius:3px;cursor:pointer}.draggable-helper a{color:#fff!important}.draggable-helper-with-image{border:2px solid #000;padding:0;line-height:0;border-radius:0;width:79px;height:79px;background:url(../images/pattern.png) #000}.draggable-helper-with-image img{position:relative;z-index:1;width:75px;height:75px;object-fit:cover}.uid-preview{max-width:20em;overflow:hidden;-ms-word-break:break-word;word-break:break-word}.shiv:after{position:absolute;width:2em;height:100%;top:0}body.ltr .shiv-right:after,body.rtl .shiv-left:after{right:-2em}.shiv-white{background:#fff}body.ltr .shiv-white:after{background:-webkit-linear-gradient(left,rgba(255,255,255,0),#fff);background:-moz-linear-gradient(left,rgba(255,255,255,0),#fff);background:-ms-linear-gradient(left,rgba(255,255,255,0),#fff);background:linear-gradient(left,rgba(255,255,255,0),#fff)}body.rtl .shiv-white:after{background:-webkit-linear-gradient(right,rgba(255,255,255,0),#fff);background:-moz-linear-gradient(right,rgba(255,255,255,0),#fff);background:-ms-linear-gradient(right,rgba(255,255,255,0),#fff);background:linear-gradient(right,rgba(255,255,255,0),#fff)}.shiv-grey{background:#efefef}body.ltr .shiv-grey:after{background:-webkit-linear-gradient(left,rgba(239,239,239,0),#efefef);background:-moz-linear-gradient(left,rgba(239,239,239,0),#efefef);background:-ms-linear-gradient(left,rgba(239,239,239,0),#efefef);background:linear-gradient(left,rgba(239,239,239,0),#efefef)}body.rtl .shiv-grey:after{background:-webkit-linear-gradient(right,rgba(239,239,239,0),#efefef);background:-moz-linear-gradient(right,rgba(239,239,239,0),#efefef);background:-ms-linear-gradient(right,rgba(239,239,239,0),#efefef);background:linear-gradient(right,rgba(239,239,239,0),#efefef)}#nprogress .bar{background:#fff;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}.alpha,.beta,.delta,.epsilon,.gamma,.text h1,.text h2,.text h3,.text h4,.text h5,.text h6,.zeta,h1,h2,h3,h4,h5,h6{font-size:1em;font-weight:600}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color:inherit}*{font-size:100%;font-family:"Source Sans Pro","Apple LiGothic Medium","Microsoft JhengHei UI","Helvetica Neue",Arial,sans-serif}.label,.text{font-size:1em}.light{font-weight:300}.strong,b,strong{font-weight:600}a{text-decoration:none;color:#000}.marginalia{color:#777}hr{height:2px;background:#ddd;border:0}.text{line-height:1.5em}.text a{font-weight:400;border-bottom:2px solid #ddd}.text a:hover{border-color:#000}.text mark{background:#8dae28;padding:0 5px;color:#fff}body.ltr .text blockquote{padding-left:1.5em;border-left:6px solid #ddd}body.rtl .text blockquote{padding-right:1.5em;border-right:6px solid #ddd}body.ltr .nav-icon-left,body.rtl .nav-icon-right{border-right:1px solid #555}.text hr{margin:1.5em 0}.text ul{margin-bottom:1.5em}.text ul ol,.text ul ul{margin-bottom:0}body.ltr .text ul{margin-left:1em}body.rtl .text ul{margin-right:1em}.text ol{margin-bottom:1.5em}.text ol ol,.text ol ul{margin-bottom:0}body.ltr .text ol{margin-left:1.25em}body.rtl .text ol{margin-right:1.25em}.btn,.nav-icon{display:inline-block;line-height:1em}body.ltr .nav-bar>li{float:left}body.rtl .nav-bar>li{float:right}.nav-icon{background:#000;color:#fff;padding:1em 0;text-align:center;height:3em;width:4em}.nav-icon:hover{color:#999}body.ltr .nav-icon-right,body.rtl .nav-icon-left{border-left:1px solid #555}.btn{background:0 0;border:0;cursor:pointer;outline:0;vertical-align:middle;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none}.dashboard-section,.field-grid-item,.tag,.tag-input{vertical-align:top}.input,.input-with-selectbox .selectbox{-webkit-appearance:none;-moz-appearance:none}.btn::-moz-focus-inner{border:0;padding:0}.btn-rounded{font-weight:600;border-radius:5em;border:2px solid #000;padding:.4em 1.5em}.btn-rounded:focus,.btn-rounded:hover{background:#000;color:#fff}.btn-negative{border-color:#b3000a;color:#b3000a}.btn-negative:focus,.btn-negative:hover{background:#b3000a}.btn-positive{border-color:#8dae28;color:#8dae28}.btn-positive:focus,.btn-positive:hover{background:#8dae28}.btn-with-icon{color:#777}body.ltr .btn-with-icon{text-align:left}body.rtl .btn-with-icon{text-align:right}.buttons-centered,.dropload-text,.dropzone-text,.field-buttons,.field-buttons .btn,.field-icon .icon,.field-icon span,.message-toggle i{text-align:center}.btn-with-icon .icon,.btn-with-icon:focus,.btn-with-icon:hover{color:#000}.btn-addit i{line-height:0}.btn-wide{min-width:10em}fieldset{border:0}form.loading:after{position:fixed;top:0;left:0;right:0;bottom:0;cursor:wait;z-index:10000}.label{position:relative;font-weight:600;display:block;line-height:1.5em;padding-bottom:.5em}.label abbr{color:#8dae28;border:0}body.ltr .label abbr{padding-left:.25em}body.rtl .label abbr{padding-right:.25em}.label-option{position:absolute;top:0;font-weight:400;color:#777;line-height:1.5em}.field,.field-content{position:relative}body.ltr .label-option{right:0}body.rtl .label-option{left:0}.label-option .icon,.label-option:hover{color:#000}.field{margin-bottom:1.5em}.field-help{display:block;font-size:.9em;padding:.5em 0;font-style:italic}.field-help .pw-suggestion{background:#dedede;padding:.15em .75em;border-radius:1em;line-height:1em;font-size:1em;font-family:Courier,monospace;font-style:normal;cursor:pointer}.field-help .pw-suggestion:hover{background:#8DAE28;color:#fff}.field-with-error .label,.field-with-error .label abbr{color:#b3000a}.field-help .pw-reload{position:relative;top:3px;border:0;margin-left:.5em}.field-with-error .input:focus{border-color:#000}.field-with-info{margin-bottom:0}.field-with-line{clear:both;margin:1.5em 0 2.5em}@media screen and (min-width:60em){.field-with-line{margin:3.5em 0 4.5em}}.field-icon{position:absolute;top:2px;bottom:2px;width:3em;background:#fff}body.ltr .field-icon{right:2px;border-left:1px dashed #ddd}body.rtl .field-icon{left:2px;border-right:1px dashed #ddd}.field-icon .icon{position:absolute;top:50%;left:0;right:0;margin-top:-7px;color:#777}.field-icon:hover .icon{color:#8dae28}body.ltr .field-with-icon .input{padding-right:3.5em}body.rtl .field-with-icon .input{padding-left:3.5em}.field-icon span{display:block;padding:0;line-height:3em;font-size:.8em;color:#777}.field-is-readonly .field-icon{background:#efefef}body.ltr .field-is-readonly .field-icon{border-left-color:#ccc}body.rtl .field-is-readonly .field-icon{border-right-color:#ccc}.field-is-disabled{opacity:.5}.field-is-disabled .label{color:#555}.field-buttons{position:absolute;bottom:2px;left:2px;right:2px;border-top:1px solid #efefef;background:#fff;line-height:0;overflow-y:hidden}.field-buttons:after,.field-buttons:before{position:absolute;top:0;bottom:0;width:1em;pointer-events:0;z-index:1}.breadcrumb-list:after,.file-preview object,.fileview-preview-link object,.input-is-readonly .selectbox-wrapper,.input-is-readonly[type=checkbox],.input-is-readonly[type=radio],.is-disabled .pika-button,body.over *{pointer-events:none}.field-buttons:before{left:0;background:-webkit-linear-gradient(left,rgba(0,0,0,.05),rgba(255,255,255,0));background:-moz-linear-gradient(left,rgba(0,0,0,.05),rgba(255,255,255,0));background:-ms-linear-gradient(left,rgba(0,0,0,.05),rgba(255,255,255,0));background:linear-gradient(left,rgba(0,0,0,.05),rgba(255,255,255,0))}.field-buttons:after{right:0;background:-webkit-linear-gradient(right,rgba(0,0,0,.05),rgba(255,255,255,0));background:-moz-linear-gradient(right,rgba(0,0,0,.05),rgba(255,255,255,0));background:-ms-linear-gradient(right,rgba(0,0,0,.05),rgba(255,255,255,0));background:linear-gradient(right,rgba(0,0,0,.05),rgba(255,255,255,0))}@media screen and (min-width:30em){.field-buttons:after,.field-buttons:before{display:none}}.field-buttons ul{overflow:auto}.input-with-checkbox,.input-with-radio,.input-with-selectbox,.selectbox-wrapper,.topbar .message{overflow:hidden}.field-buttons li{display:inline-block;border-right:1px solid #efefef;float:none!important}.field-buttons li:last-child{border-right:0}.field-buttons .btn{padding:.5em 1.5em;display:block;line-height:1em;width:100%}.field-buttons .btn:hover{color:#000}.field-with-buttons .input{min-height:10em;padding-bottom:1.5em!important}body.ltr .field-grid{margin-left:-1.5em}body.rtl .field-grid{margin-right:-1.5em}.field-grid-item{display:inline-block;width:100%}body.ltr .field-grid-item{padding-left:1.5em}body.rtl .field-grid-item{padding-right:1.5em}@media screen and (min-width:60em){.field-grid-item-1-2,.field-grid-item-2-4{width:50%}.field-grid-item-1-4{width:25%}.field-grid-item-3-4{width:75%}.field-grid-item-1-3{width:33.3333333%}.field-grid-item-2-3{width:66.666666%}.field-grid-item-1-5{width:20%}.field-grid-item-2-5{width:40%}.field-grid-item-3-5{width:60%}.field-grid-item-4-5{width:80%}}.input,.range,.selectbox{width:100%}.input{padding:.5em;font-size:1em;line-height:1.5em;font-weight:400;border:2px solid #ddd;background:#fff;display:block;-ms-appearance:none;appearance:none;border-radius:0;min-height:2.75em}.input:-webkit-autofill{box-shadow:0 0 0 1000px #fff inset!important}.input:focus{outline:0;border-color:#8dae28}.input.over{border-color:#000}textarea.input{resize:none}.input:invalid,.input:required{box-shadow:none}.input-is-readonly{background:#efefef;border-color:#ddd;color:#777}.input-is-readonly.input-is-focused,.input-is-readonly:focus{border-color:#ddd}.input-is-focused{border-color:#8dae28}.input-with-radio label{cursor:pointer}.input-with-radio .radio{position:relative;top:-1px}body.ltr .input-with-radio .radio{margin:0 1em 0 .25em}body.rtl .input-with-radio .radio{margin:0 .25em 0 1em}body.ltr .input-with-checkbox .checkbox{float:left;margin:.3em 1em .3em .25em}body.rtl .input-with-checkbox .checkbox{float:right;margin:.3em .25em .3em 1}.selectbox-wrapper{height:1.5em}.input-with-selectbox{cursor:pointer;padding:.5em;line-height:1em}body.ltr .input-with-selectbox .selectbox-wrapper{margin-right:-3em}body.rtl .input-with-selectbox .selectbox-wrapper{margin-left:-3em}.input-with-selectbox .selectbox{line-height:1.5em;display:block;cursor:pointer;appearance:none;border:0;background:0 0;outline:0;border-radius:0}.input-with-selectbox .selectbox:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}.input-with-fileupload{line-height:1em;padding:.75em .5em}.input-with-tags{padding:3px}.input-with-tags.input-is-readonly .tag{opacity:.25}body.ltr .field-with-icon .input-with-tags{padding-right:3.25em}body.rtl .field-with-icon .input-with-tags{padding-left:3.25em}.tag-input{margin:3px;display:block;-moz-appearance:none;-webkit-appearance:none;-ms-appearance:none;appearance:none;border:0;padding:.25em;width:auto;outline:0;background:0 0}@media screen and (min-width:30em){.tag-input{display:inline-block}}.input-list-item{margin-bottom:.5em}.input-list-item .input{white-space:nowrap;overflow:hidden}.input-with-items{padding:0}.input-with-items .item{border-bottom:1px solid #efefef}.input-with-items .item:last-child{border-bottom:0}.buttons{margin:.5em 0}body.ltr .buttons .btn-cancel{float:left}body.rtl .buttons .btn-cancel{float:right}body.ltr .buttons .btn-submit{float:right;margin-left:1rem}body.rtl .buttons .btn-submit{float:left;margin-right:1rem}.btn-submit .btn:first-child{border-top-right-radius:0;border-bottom-right-radius:0;padding-right:1rem}.btn-submit .btn:last-child{border-top-left-radius:0;border-bottom-left-radius:0;border-left:0;padding-left:1rem}.buttons-centered .btn{margin:0 .5em}.buttons-centered .btn-cancel,.buttons-centered .btn-submit{float:none!important}#form-field-username{text-transform:lowercase}@media screen and (min-width:50em){.mainbar .form{padding:0 1.5em 9em}.mainbar .form .buttons{position:fixed;bottom:0;background:#efefef;background:-webkit-linear-gradient(bottom,#efefef,rgba(239,239,239,.9) 75%,rgba(239,239,239,0));background:-moz-linear-gradient(bottom,#efefef,rgba(239,239,239,.9) 75%,rgba(239,239,239,0));background:-ms-linear-gradient(bottom,#efefef,rgba(239,239,239,.9) 75%,rgba(239,239,239,0));background:linear-gradient(bottom,#efefef,rgba(239,239,239,.9) 75%,rgba(239,239,239,0));margin:0;padding:1.5em 3em}.ltr .mainbar .form .buttons{left:33.33%;right:0}.rtl .mainbar .form .buttons{right:33.33%;left:0}.mainbar .form .buttons .text span{position:relative;padding:.35rem 2rem;background:#8dae28;display:inline-block;margin:0 auto 1.5rem;color:#fff;font-weight:600;box-shadow:rgba(0,0,0,.05) 0 2px 10px}.mainbar .form .buttons .text span:after{position:absolute;content:"";border-top:5px solid #8dae28;border-left:5px solid transparent;border-right:5px solid transparent;bottom:-5px;left:50%;margin-left:-5px}}.dropdown,.modal-content{box-shadow:rgba(0,0,0,.2) 0 2px 10px}.gu-mirror{position:fixed!important;margin:0!important;z-index:9999!important}.gu-hide{display:none!important}.gu-unselectable{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.gu-transit{opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0)}.dropzone{position:relative;border:1px dashed #ddd;border-radius:.2em}.grey .dropzone{border-color:#bbb}.dropzone-text{line-height:1.5em}.dropzone-text .marginalia{font-size:.9em;font-style:italic}.icon,.message-toggle i,.tag .tag-x{font-style:normal}.dropzone-progress{position:absolute;top:50%;left:0;right:0;margin-top:-5px;height:10px;border-radius:2em;background:#ddd;display:none}.dropzone-progress span{display:block;border-radius:2em;width:0;height:100%;background:#8dae28}.dropzone-is-loading{border-color:transparent!important}.dropzone-is-loading .dropzone-progress{display:block}.dropzone-is-loading .dropzone-text{opacity:.05}.dropzone.dropzone-input{border-width:2px;transition:border-color .3s;cursor:pointer}.dropzone.dropzone-input:hover{border-color:#bbb}.dropzone.dropzone-input:focus{border-color:#8dae28;outline:0}.grey .dropzone.dropzone-input:hover{border-color:#aaa}.dropload{position:relative;border:2px dashed rgba(0,0,0,.15);border-radius:.2em;transition:border-color .3s;margin-bottom:1.5em}.dropload.over,.dropload:focus,.dropload:hover{border-color:#8dae28}.dropload-text{display:none}.dropload-text strong{display:block}.dropload.is-active [type=file]{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;opacity:0;cursor:pointer}.dropload.is-active [type=submit]{display:none}.dropload.is-active .dropload-text,.tag{display:block}.message{position:relative;color:#fff;line-height:1em;cursor:pointer}.message-is-notice .message-content{background:#8dae28}.message-is-alert .message-content{background:#b3000a}.message-is-alert a{color:#fff;border-bottom:2px solid rgba(255,255,255,.5)}.message-content{display:block;line-height:1.5em;background:#000}body.ltr .message-content{padding:.75em 4.5em .75em 1.5em}body.rtl .message-content{padding:.75em 1.5em .75em 4.5em}.message-toggle{position:absolute;top:50%;margin-top:-.75em;border:2px solid rgba(255,255,255,.5);border-radius:4em;width:1.5em;height:1.5em;transition:border-color .3s;cursor:pointer}body.ltr .message-toggle{right:1.5em}body.rtl .message-toggle{left:1.5em}.message-toggle:hover{border-color:#fff}.message-toggle i{position:absolute;top:50%;left:50%;font-size:1.25em;-webkit-transform:translate(-50%,-50%);-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.message-is-notice .message-toggle{color:#fff}body>.message{position:absolute;top:0;height:3em;z-index:1;background:#000}body.ltr body>.message{right:0;left:4em;margin-left:-1px}body.rtl body>.message{left:0;right:4em;margin-right:-1px}body>.message .message-content{position:relative}body.ltr body>.message .message-content{margin-right:4.5em;padding-right:1.5em}body.rtl body>.message .message-content{margin-left:4.5em;padding-left:1.5em}body>.message .message-content:after{position:absolute;top:50%;margin-top:-.5em;border-top:.5em solid transparent;border-bottom:.5em solid transparent}body.ltr body>.message .message-content:after{right:-.5em;border-left:.5em solid #8dae28}body.rtl body>.message .message-content:after{left:-.5em;border-right:.5em solid #8dae28}body.ltr body>.message-is-alert .message-content:after{border-left:.5em solid #b3000a}body.rtl body>.message-is-alert .message-content:after{border-right:.5em solid #b3000a}.modal-content .message{margin:-1.5em -1.5em 1.5em}@keyframes showTopbarMessage{0%{-webkit-transform:translateX(6rem);-moz-transform:translateX(6rem);-ms-transform:translateX(6rem);transform:translateX(6rem);opacity:0}100%{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0);opacity:1}}.file-preview img,.file-preview object,.fileview-image-link{-webkit-transform:translate(-50%,-50%);-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%)}.topbar .message{position:absolute;top:0;z-index:100;background:#000}.ltr .topbar .message{right:0}.rtl .topbar .message{left:0}.topbar .message-content:after{position:absolute;top:50%;margin-top:-7px;border-top:7px solid transparent;border-bottom:5px solid transparent}body.ltr .topbar .message-content:after{right:-7px;border-left:7px solid #8dae28}body.rtl .topbar .message-content:after{left:-7px;border-right:7px solid #8dae28}body.ltr .topbar .message-is-alert .message-content:after{border-left:7px solid #b3000a}body.rtl .topbar .message-is-alert .message-content:after{border-right:7px solid #b3000a}body.ltr .topbar .message-toggle{right:1.25em}.modal,body.rtl .dropdown-left{right:0}body.rtl .topbar .message-toggle{left:1.25em}.modal,body.ltr .dropdown-left{left:0}.topbar .message-content{position:relative;animation-name:showTopbarMessage;animation-iteration-count:1;animation-timing-function:ease-out;animation-duration:.3s;min-width:4.5em;text-align:center}body.ltr .topbar .message-content{margin-right:4rem;padding-right:1.5rem}body.rtl .topbar .message-content{margin-left:4rem;padding-left:1.5em}.tag{margin:3px;position:relative;cursor:pointer;background:#000;border-radius:3px}a.tag{line-height:1.25em}@media screen and (min-width:30em){.tag{display:inline-block}}.tag .tag-label{display:block;width:100%;color:#fff;z-index:1;padding:.25em 1em;text-align:left;border-radius:3px}.tag .tag-label:focus,.tag-is-focused .tag-label{outline:0;background:#8dae28}.tag button{border:0;background:0 0;cursor:pointer}.tag button::-moz-focus-inner{border:0;padding:0}body.ltr .tag button.tag-label{padding-right:3.5em}body.rtl .tag button.tag-label{padding-left:3.5em}.tag .tag-x{position:absolute;top:0;line-height:1em;padding:.4em 1em;z-index:1;color:rgba(255,255,255,.7)}body.ltr .tag .tag-x{right:0;border-left:1px solid rgba(255,255,255,.3)}body.rtl .tag .tag-x{left:0;border-right:1px solid rgba(255,255,255,.3)}.tag .tag-x:focus,.tag .tag-x:hover{color:#fff}.modal{position:fixed;top:0;bottom:0;height:100%;background:rgba(30,30,30,.8);z-index:1000;overflow-y:scroll;-webkit-overflow-scrolling:touch;padding-top:3rem}.modal-content{position:relative;background:#fff;overflow:auto;z-index:2;border-radius:3px;margin:0 1.5em 3em}.modal-content .form{padding:1.5em}@media screen and (min-width:30em){.modal-content{width:22em;margin-left:auto;margin-right:auto}.modal-content-large{width:90%;max-width:40em}.modal-content-medium{width:70%;max-width:30em}}.instruction{text-align:center;padding:6em 0}.instruction-content{display:inline-block;padding:0 1.5em 1.5em;text-align:center}.instruction-text{line-height:1.5em;margin-bottom:1.5em}.dashboard-section{position:relative;display:inline-block;margin-bottom:1.5em;width:100%;padding:1em 1.5em}.dashboard-section ul,.dashboard-section:last-child{margin-bottom:0}.dashboard-box,.dashboard-section .field:last-child{margin-bottom:.5em}.dashboard-box{position:relative;display:block;border:2px solid #ddd;overflow:hidden;background:#efefef}.dashboard-item-icon,.dashboard-item-text{display:inline-block;vertical-align:middle}.dashboard-box .text{padding:.75em 1em}.dashboard-box .text :last-child{margin-bottom:0}.dashboard-items .dashboard-item{border-bottom:1px solid #ddd}.dashboard-items .dashboard-item:last-child{border-bottom:0}.dashboard-item-icon{height:2.5em;width:2.5em;text-align:center}.dashboard-item-icon-with-border{border-right:1px solid #ddd}.dashboard-item-icon i{position:static;padding-top:.8em}.dashboard-item-text{overflow:hidden;padding:0 .75em;width:calc(100% - 2.5em)}.dropdown{position:relative;background:#fff;display:none}.dropdown:after{position:absolute;content:"";top:-.5em;border-bottom:.5em solid #fff;border-left:.5em solid transparent;border-right:.5em solid transparent}.hgroup,.hgroup a,.icon{position:relative}body.ltr .dropdown:after{margin-left:-.1em}body.rtl .dropdown:after{margin-right:-.1em}body.ltr .dropdown-left:after{left:1.5em}body.rtl .dropdown-left:after{right:1.5em}body.ltr .dropdown-right{right:0}body.rtl .dropdown-right{left:0}body.ltr .dropdown-right:after{right:1.5em}body.rtl .dropdown-right:after{left:1.5em}body.ltr .hgroup a:after,body.rtl .hgroup-single-line .hgroup-options{left:0}.dropdown-list>li>a{padding:.75em 1.5em .75em 1em;overflow:hidden;border-bottom:1px solid #efefef}body.ltr .icon-left,body.rtl .icon-right{padding-right:.5em}.dropdown-list>li>a:hover{color:#777}.dropdown-list>li>a:hover i{color:#000}.dropdown-list>li i{display:inline-block;width:2em;text-align:center}.dropdown-dark{background:#000;border-radius:4px}.dropdown-dark:after{display:none}.dropdown-dark .dropdown-list a{color:#fff;border-bottom:1px solid #222}.dropdown-dark .dropdown-list a:hover,.dropdown-dark .dropdown-list a:hover i{color:#999}.dropdown-dark .dropdown-list li:last-child a{border-bottom:0}.icon{font-size:14px;top:-1px;display:inline-block;font-weight:700;text-align:center}body.ltr .icon-right,body.rtl .icon-left{padding-left:.5em}.avatar{display:block;line-height:0}.avatar img{width:4.5em;height:4.5em;padding:2px;border:2px solid #ddd}.hgroup,.hgroup-title{border-bottom:2px solid #ddd;padding-bottom:.5em}.avatar-large img{width:9em;height:9em}.avatar-centered{text-align:center}.avatar-full img{width:100%;height:auto;max-width:100%}.hgroup{line-height:1.5em;margin-bottom:1.5em}.hgroup a{display:inline-block}.hgroup a:after{position:absolute;bottom:-.5em;margin-bottom:-2px;height:2px;width:100%;background:#000}body.rtl .hgroup a:after{right:0}.hgroup-title{display:block;margin-bottom:.5em;font-weight:600;font-size:1em}.hgroup-options{display:block;font-size:1em;font-weight:400;color:#777}.hgroup-options a{display:inline-block}.hgroup-options a:hover{color:#000}body.ltr .hgroup-option-left{float:left}body.ltr .hgroup-option-right,body.rtl .hgroup-option-left{float:right}body.rtl .hgroup-option-right{float:left}body.ltr .hgroup-option-right a{margin-left:1em}body.rtl .hgroup-option-right a{margin-right:1em}@media screen and (max-width:70em){body.ltr .hgroup-option-right>a .icon-left{padding-right:0}body.rtl .hgroup-option-right>a .icon-left{padding-left:0}.hgroup-option-right>a span{display:none}}.file,.file-meta,.file-name,.file-preview{display:block}.hgroup-options .icon{top:0;color:#000}.hgroup-single-line{border:0;padding-bottom:0}.hgroup-single-line .hgroup-title{margin-bottom:0}.hgroup-single-line .hgroup-options{position:absolute;top:0}body.ltr .hgroup-single-line .hgroup-options{right:0}.hgroup-compressed{margin-bottom:.5em}.hgroup .dropdown{position:absolute;z-index:1;margin-top:-2px}.hgroup .dropdown a{font-weight:400}.file{background:#fff}.file-preview{position:relative;padding-bottom:66.66%;line-height:0;background:#000;overflow:hidden}.file-preview-is-image{background:url(../images/pattern.png)}.item,.item-options{background:#fff}.file-preview img,.file-preview object{position:absolute;top:50%;left:50%;max-width:100%;max-height:100%;transform:translate(-50%,-50%)}.file-preview span{position:absolute;top:50%;left:0;right:0;text-align:center;text-transform:uppercase;color:#fff}.item,.item-content{position:relative;overflow:hidden}.file-info{padding:1em 1.5em;line-height:1.5em;border-bottom:1px solid #ddd}.file-name{color:#000}.file-options .btn{width:50%;border-bottom:0;padding:.75em 1.5em}body.ltr .file-options .btn{float:left;text-align:center}body.rtl .file-options .btn{float:right;text-align:center}.file-options .btn:first-child{border-right:1px solid #ddd}.file-options .btn span{display:none}.file-options .btn:last-child{border-bottom:0}@media screen and (min-width:120em){.file-options .btn{padding:1em 1.5em}.file-options .btn span{display:inline}}.items .item,.items.users{margin-bottom:1.5em}.items-with-borders{border:1px solid #ddd}.items .item:last-child{margin-bottom:0}@media screen and (min-width:50em){.items .item{margin-bottom:1px}}.item{line-height:1em}.item-content{border-bottom:1px solid #efefef}.item-info{padding:1em;height:4.25em;overflow:hidden}.item-meta,.item-title{padding:0 .5em;display:block;white-space:nowrap}.item-title{margin-bottom:.25em}.item-options li{width:50%}body.ltr .item-options li{border-left:1px solid #efefef}body.rtl .item-options li{border-right:1px solid #efefef}.item-options-three li{width:33.33%}body.ltr .item-options li:first-child{border-left:0}body.rtl .item-options li:first-child{border-right:0}.item-options .btn{padding:1em 1.5em}@media screen and (min-width:50em){.item-content{border:0;line-height:1em}.item-info{height:3em}.item-title{margin-bottom:0}body.ltr .item-title{float:left}body.rtl .item-title{float:right}body.ltr .item-meta{float:left}body.rtl .item-meta{float:right}.item-options{position:absolute;top:0}body.ltr .item-options{right:0;border-left:1px solid #efefef}body.rtl .item-options{left:0;border-left:1px solid #efefef}.item-options li{width:auto}}.item-image{position:absolute;width:4.25em;height:4.25em}.item-image img{height:100%;width:100%}body.ltr .item-with-image .item-info{margin-left:4.25em}body.rtl .item-with-image .item-info{margin-right:4.25em}@media screen and (min-width:50em){.item-image{width:3em;height:3em}body.ltr .item-with-image .item-info{margin-left:3em}body.rtl .item-with-image .item-info{margin-right:3em}}.item-condensed .item-info{padding:.75em .5em;height:auto}.item-condensed .item-options .btn{padding:1em}@media screen and (min-width:50em){.item-condensed .item-info{height:auto}.item-condensed .item-options .btn{padding:.75em 1.25em}.item-condensed .item-options a span{display:none}body.ltr .item-condensed .item-options i{padding-right:0}body.rtl .item-condensed .item-options i{padding-left:0}}.item-condensed.item-with-image .item-image{position:absolute;width:3em;height:3em}body.ltr .item-condensed.item-with-image .item-info{margin-left:3.75em}body.rtl .item-condensed.item-with-image .item-info{margin-right:3.75em}@media screen and (min-width:50em){.item-condensed.item-with-image .item-image{width:2.5em;height:2.5em}body.ltr .item-condensed.item-with-image .item-info{margin-left:2.5em}body.rtl .item-condensed.item-with-image .item-info{margin-right:2.5em}}.item-options .icon.marginalia{min-width:1em}.breadcrumb{position:relative;background:#000}.breadcrumb-list{height:3em;overflow:hidden;display:none}.breadcrumb-list:after{position:absolute;top:0;bottom:0;width:2em}body.ltr .breadcrumb-list:after{right:0;background:-webkit-linear-gradient(left,transparent,#000);background:-moz-linear-gradient(left,transparent,#000);background:-ms-linear-gradient(left,transparent,#000);background:linear-gradient(left,transparent,#000)}body.rtl .breadcrumb-list:after{left:0;background:-webkit-linear-gradient(right,transparent,#000);background:-moz-linear-gradient(right,transparent,#000);background:-ms-linear-gradient(right,transparent,#000);background:linear-gradient(right,transparent,#000)}.breadcrumb-list li:last-child .breadcrumb-label{max-width:none}.breadcrumb-link{position:relative;line-height:1em;color:#fff;font-weight:400}body.ltr .breadcrumb-link{padding-left:1.25em}body.rtl .breadcrumb-link{padding-right:1.25em}.breadcrumb-link:focus{outline:0}.breadcrumb-label{display:block;white-space:nowrap;overflow:hidden;max-width:6em}body.ltr .breadcrumb-label{padding:1em .75em 1em 0}body.rtl .breadcrumb-label{padding:1em 0 1em .75em}@media screen and (min-width:50em){.breadcrumb .nav-icon,.breadcrumb-dropdown{display:none}.breadcrumb ul{display:block}}.breadcrumb-label:after{position:absolute;top:0;bottom:0;width:.75em}body.ltr .breadcrumb-label:after{right:0;background:-webkit-linear-gradient(left,transparent,#000);background:-moz-linear-gradient(left,transparent,#000);background:-ms-linear-gradient(left,transparent,#000);background:linear-gradient(left,transparent,#000)}body.rtl .breadcrumb-label:after{left:0;background:-webkit-linear-gradient(right,transparent,#000);background:-moz-linear-gradient(right,transparent,#000);background:-ms-linear-gradient(right,transparent,#000);background:linear-gradient(right,transparent,#000)}.breadcrumb-link:hover{color:#999}.breadcrumb-link:after,.breadcrumb-link:before{position:absolute;height:1.6em;width:1px;z-index:1}body.ltr .breadcrumb-link:after,body.ltr .breadcrumb-link:before{right:0}body.rtl .breadcrumb-link:after,body.rtl .breadcrumb-link:before{left:0}.breadcrumb-link:after{top:0;background:-webkit-linear-gradient(bottom,#555,#555 50%,#000);background:-moz-linear-gradient(bottom,#555,#555 50%,#000);background:-ms-linear-gradient(bottom,#555,#555 50%,#000);background:linear-gradient(bottom,#555,#555 50%,#000)}body.ltr .breadcrumb-link:after{-webkit-transform:rotate(-33.75deg);-moz-transform:rotate(-33.75deg);-ms-transform:rotate(-33.75deg);transform:rotate(-33.75deg)}body.rtl .breadcrumb-link:after{-webkit-transform:rotate(33.75deg);-moz-transform:rotate(33.75deg);-ms-transform:rotate(33.75deg);transform:rotate(33.75deg)}.breadcrumb-link:before{bottom:0;background:-webkit-linear-gradient(top,#555,#555 50%,#000);background:-moz-linear-gradient(top,#555,#555 50%,#000);background:-ms-linear-gradient(top,#555,#555 50%,#000);background:linear-gradient(top,#555,#555 50%,#000)}.languages,.topbar{z-index:100;background:#000}body.ltr .breadcrumb-link:before{-webkit-transform:rotate(33.75deg);-moz-transform:rotate(33.75deg);-ms-transform:rotate(33.75deg);transform:rotate(33.75deg)}body.rtl .breadcrumb-link:before{-webkit-transform:rotate(-33.75deg);-moz-transform:rotate(-33.75deg);-ms-transform:rotate(-33.75deg);transform:rotate(-33.75deg)}.languages{position:absolute;top:0;width:4.5em;bottom:0;text-align:center}.grid-item,.languages .dropdown{width:100%}body.ltr .languages{right:4em;border-left:1px solid #555}body.rtl .languages{left:4em;border-right:1px solid #555}.languages-toggle{display:block;color:#fff;line-height:3em;text-transform:uppercase}.languages-toggle span{position:relative;display:block}body.ltr .languages-toggle span{padding-right:1.25em}body.rtl .languages-toggle span{padding-left:1.25em}.languages-toggle span:after{position:absolute;top:50%;border-top:.3em solid #fff;border-left:.3em solid transparent;border-right:.3em solid transparent}body.ltr .languages-toggle span:after{right:1em}body.rtl .languages-toggle span:after{left:1em}body.ltr .languages .dropdown:after{left:50%;margin-left:-.5em}body.rtl .languages .dropdown:after{right:50%;margin-right:-.5em}.pagination{position:relative;margin-bottom:2.5em}.pagination a,.pagination span{padding:.5em 0;display:block}body.ltr .pagination .pagination-prev{float:left;padding-right:1em}body.ltr .pagination .pagination-next,body.rtl .pagination .pagination-prev{float:right;padding-left:1em}.pagination-index{position:absolute;left:2em;right:2em;text-align:center;color:#777}.topbar,body.ltr .topbar .nav-icon-right,body.rtl .topbar .nav-icon-left{right:0}.pagination-index select{position:absolute;top:0;bottom:0;left:50%;cursor:pointer;-webkit-transform:translate(-50%,0);-moz-transform:translate(-50%,0);-ms-transform:translate(-50%,0);transform:translate(-50%,0);min-width:6em;opacity:0}body.ltr .topbar .nav-icon-left,body.rtl .topbar .nav-icon-right{left:0}body.rtl .pagination .pagination-next{float:left;padding-right:1em}.pagination .pagination-inactive{color:#ddd;pointer-events:none}body.ltr .grid{margin-left:-1.5em}body.rtl .grid{margin-right:-1.5em}.grid-item{display:inline-block;vertical-align:top}body.ltr .grid-item{padding-left:1.5em}body.rtl .grid-item{padding-right:1.5em}body.ltr .grid-full{margin-left:0}body.rtl .grid-full{margin-right:0}body.ltr .grid-full .grid-item{padding-left:0}body.rtl .grid-full .grid-item{padding-right:0}.topbar{position:absolute;top:0;left:0;height:3em}.topbar .nav-icon{position:absolute;top:0}body.ltr .topbar .breadcrumb{margin-left:4em}body.rtl .topbar .breadcrumb{margin-right:4em}.topbar .dropdown{position:absolute;z-index:1000;top:3em}.sidebar{padding:1.5em}.sidebar-toggle{position:relative;font-weight:400;display:block;padding:1em 1.5em;color:#777;background:#efefef;border:2px solid #ddd;border-radius:3px}.sidebar-toggle:hover{color:#000}.sidebar-toggle:after{position:absolute;top:50%;margin-top:-.15em;border-top:.4em solid #000;border-left:.4em solid transparent;border-right:.4em solid transparent}body.ltr .sidebar-toggle:after{right:1.5em}body.rtl .sidebar-toggle:after{left:1.5em}.ltr .sidebar-list>li>.option,body.ltr .sidebar-list .icon{left:0}.sidebar-expanded .sidebar-toggle:before{content:attr(data-hide)}.main .loader:after,.subpages-help:after{content:""}.sidebar-expanded .sidebar-toggle{background:#fff;border-color:#fff;border-bottom:1px dashed #ddd}.sidebar-expanded .sidebar-toggle span{display:none}.sidebar-expanded .sidebar-toggle:after{border-top:0;border-bottom:.4em solid #000}.sidebar-content{display:none;background:#fff}.sidebar-expanded .sidebar-content{display:block}.sidebar-content>.marginalia{margin-bottom:1.5em;line-height:1.5em}@media screen and (min-width:50em){.mainbar,.sidebar{overflow-y:scroll;-webkit-overflow-scrolling:touch}.bars-with-sidebar-left:before,.sidebar{position:absolute;top:0;bottom:0;height:100%}body.ltr .bars-with-sidebar-left:before,body.ltr .sidebar,body.rtl .mainbar{left:0}body.ltr .mainbar,body.rtl .bars-with-sidebar-left:before,body.rtl .sidebar{right:0}.sidebar{width:33.33%;padding:0}.sidebar-toggle{display:none!important}.sidebar-content{display:block!important}.mainbar{position:absolute;top:0;bottom:0;width:66.66%}.bars-with-sidebar-left:before{content:"";width:33.33%;background:#fff;z-index:-1}}.sidebar-list{margin-bottom:1.5em}.sidebar-list>li{position:relative;white-space:nowrap;overflow:hidden}body.ltr .sidebar-list>li>a{padding:.25em 0 .25em 1.75em}body.rtl .sidebar-list>li>a{padding:.25em 1.75em .25em 0}.sidebar-list>li>.option{position:absolute;top:-1px;z-index:1;text-align:right;padding:0!important;background:#fff;display:none;font-size:18px}.rtl .sidebar-list>li>.option{right:0}.sidebar-list>li:hover .option{display:block}.sidebar-list>li:hover .draggable .icon{display:none}.sidebar-list .icon{position:absolute;top:.4em}body.rtl .sidebar-list .icon{right:0}.sidebar-list .marginalia{position:absolute}body.ltr .sidebar-list .marginalia{right:0;padding-left:.5em}body.rtl .sidebar-list .marginalia{left:0;padding-right:.5em}.sidebar-search{padding:.5em 0;margin:0 -.25em}.sidebar .pagination{border-top:2px solid #ddd;margin-top:-1em}.files .grid-item{margin-bottom:1.5em}@media screen and (min-width:40em){.dashboard{-webkit-column-count:2;-webkit-column-gap:1.5em;-moz-column-count:2;-moz-column-gap:1.5em;column-count:2;column-gap:1.5em}.files .grid-item{width:50%}}@media screen and (min-width:50em){.files .grid-item{width:33.33%}}@media screen and (min-width:60em){.dashboard{-webkit-column-count:3;-moz-column-count:3;column-count:3}.breadcrumb-label{max-width:9em}.files .grid-item{width:25%}}@media screen and (min-width:70em){.breadcrumb-label{max-width:12em}.files .grid-item{width:20%}}@media screen and (min-width:80em){.files .grid-item{width:16.66%}}.subpages{padding:.25em;margin-bottom:1em}body.ltr .subpages-help-left,body.rtl .subpages-help-right{padding-left:3em}body.ltr .subpages-help-right,body.rtl .subpages-help-left{padding-right:3em}.subpages .item{margin-bottom:.25em}.dropzone.subpages .items{min-height:2.5em}.subpages .items.sortable .item-info{cursor:move}.subpages-grid .grid-item{margin-bottom:1.5em}.subpages-grid h3{margin-bottom:1em;font-weight:400;color:#777}@media screen and (min-width:50em){.subpages .item{margin-bottom:1px}.subpages-grid .grid-item{width:50%}}.subpages-help{position:relative;font-style:italic}.subpages-help:after{position:absolute;top:-1.5em;height:6em;width:3em}.fileview-preview-link,.main{height:100%}body.ltr .subpages-help-right:after{right:0;background:url(../images/hint.arrows.png) top right no-repeat}body.ltr .subpages-help-left:after,body.rtl .subpages-help-right:after{left:0;background:url(../images/hint.arrows.png) top left no-repeat}body.rtl .subpages-help-left:after{right:0;background:url(../images/hint.arrows.png) top right no-repeat}.fileview{background:#fff}.fileview-image{position:relative;padding-bottom:66.66%;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCOTdEOEI3OUE3MDMxMUUzOEIxNEZERTM0N0EzRjlGMSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCOTdEOEI3QUE3MDMxMUUzOEIxNEZERTM0N0EzRjlGMSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkI5N0Q4Qjc3QTcwMzExRTM4QjE0RkRFMzQ3QTNGOUYxIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkI5N0Q4Qjc4QTcwMzExRTM4QjE0RkRFMzQ3QTNGOUYxIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+jGcG/wAAAAlQTFRF////zMzMzc3NCvMx6wAAACJJREFUeNpiYGRkYgQBBhgYIAGEBCO6SpIFmKCADDMAAgwATVgAkU8MrdIAAAAASUVORK5CYII=);text-align:center;overflow:hidden}.fileview-image-link{position:absolute;top:50%;max-width:75%;max-height:75%;width:100%;left:50%;transform:translate(-50%,-50%)}.fileview-image-link span{background:#000;display:inline-block;line-height:1.5em;padding:1em 1.5em;border-radius:3px;color:#999;font-weight:300;overflow:hidden}.fileview-image-link strong{color:#fff;font-weight:400;display:block}.fileview-preview-link img,.fileview-preview-link object,.fileview-preview-link span{position:absolute;top:50%;left:50%;max-width:100%;max-height:100%;-webkit-transform:translate(-50%,-50%);-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.fileview-nav{position:absolute;top:50%;left:0;right:0;margin-top:-1.5em}.fileview-nav a{display:block;padding:1em}.fileview-nav-prev{float:left}.fileview-nav-next{float:right}.fileview-options{margin-top:6em;border-top:2px solid #ddd}.fileview-options li{width:100%}.fileview-options .btn{padding:.75em 0;border-bottom:1px solid #ddd}@media screen and (min-width:50em){.fileview,.fileview-image,.fileview-sidebar{position:absolute;bottom:0}.fileview{top:3em;left:0;right:0;overflow:hidden}.fileview-image{top:0;padding:0}.ltr .fileview-image{left:0;right:50%}.rtl .fileview-image{left:50%;right:0}.fileview-sidebar{top:0;width:50%;overflow:auto}.ltr .fileview-sidebar{right:0}.rtl .fileview-sidebar{left:0}.fileview-options{margin-bottom:6em}.fileview-options li{width:33.33%}.fileview-options .btn{padding:1em;text-align:center;border-bottom:none}}@media screen and (min-width:65em){.fileview-nav{left:1.5em;right:1.5em}.ltr .fileview-image{right:33.33%}.rtl .fileview-image{left:33.33%}.fileview-sidebar{width:33.33%}}.search{width:20em}.search:after{border-bottom-color:#8dae28}.search-results{background:#000}.search-input{width:100%;padding:.75em 1em;border:0;background:#8dae28}.search-input::-webkit-input-placeholder{color:#404f12}.search-input:-moz-placeholder{color:#404f12}.search-input::-moz-placeholder{color:#404f12}.search-input:-ms-input-placeholder{color:#404f12}.search-input:focus{outline:0}.search-section{padding:.5em;border-bottom:1px solid rgba(255,255,255,.2)}.search-section:last-child{border-bottom:0}.search-section li>a{position:relative;padding:.5em 1em;line-height:1em;color:#fff;display:block;white-space:nowrap}.search-section a small,.search-section a strong{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.search-section .icon,.search-section a span{display:inline-block;vertical-align:middle}.search-section a strong{padding-bottom:.125em;font-weight:400}.search-section a small{font-size:.7em;color:#999;padding-top:.125em}.search-section li.active a,.search-section li:hover a{color:#8dae28}.search-section li.active a small,.search-section li:hover a small{color:#fff}.search-section .icon{width:2em;text-align:left}.file-selector{border:1px solid #efefef;max-height:15.4em;overflow:auto}.file-selector label{cursor:pointer}.file-selector input{position:absolute;top:1.1em}body.ltr .file-selector input{right:1.5em}body.rtl .file-selector input{left:1.5em}.main .loader{display:none}.main .loader:after{position:fixed;top:50%;width:3em;height:3em;margin-top:-1.5em;background:url(../images/loader.black.gif) center center no-repeat #fff;border-radius:50%;z-index:10000000}.autocomplete:after,.pika-single:before{top:-.5em;content:""}body.ltr .main .loader:after{left:50%;margin-left:-1.5em}body.rtl .main .loader:after{right:50%;margin-right:-1.5em}.autocomplete{position:absolute;margin-top:.5em;width:auto;z-index:1000}.autocomplete:after{position:absolute;border-left:.5em solid transparent;border-right:.5em solid transparent;border-bottom:.5em solid #000}body.ltr .autocomplete:after{left:1em}body.rtl .autocomplete:after{right:1em}.autocomplete button{display:block;width:100%;border:0;padding:.5em 1em;border-bottom:1px solid rgba(255,255,255,.2);color:#fff;background:#000;cursor:pointer}body.ltr .autocomplete button{text-align:left}body.rtl .autocomplete button{text-align:right}.fa-fw,.fa-li,.pika-button,.pika-table th,.pika-title,body.over:after{text-align:center}.autocomplete button:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.autocomplete button:last-child{border:none;border-bottom-left-radius:3px;border-bottom-right-radius:3px;box-shadow:rgba(0,0,0,.1) 0 5px 10px}.autocomplete button:focus{outline:0;background:#8dae28}.autocomplete button::-moz-focus-inner{border:0;padding:0}.autocomplete button strong{color:#8dae28;font-weight:400}.autocomplete button:focus strong{color:#000}.pika-single{display:block;position:relative;color:#fff;background:#000;margin-top:1em;margin-left:-15px;border:3px solid #151515;border-radius:3px;box-shadow:rgba(0,0,0,.1) 0 5px 10px;z-index:1000}.pika-single:before{position:absolute;left:50%;margin-left:-.5em;border-left:.5em solid transparent;border-right:.5em solid transparent;border-bottom:.5em solid #151515}.pika-single.is-hidden{display:none}.pika-single.is-bound{position:absolute;box-shadow:0 5px 15px -5px rgba(0,0,0,.5)}.pika-title{position:relative}.pika-label{display:inline-block;position:relative;z-index:9999;overflow:hidden;margin:0;padding:.6em .3em .7em;font-weight:400;color:#eee}.pika-title select{cursor:pointer;position:absolute;z-index:9998;margin:0;left:0;top:5px;filter:alpha(opacity=0);opacity:0}.pika-next,.pika-prev{position:absolute;display:block;cursor:pointer;outline:0;border:0;padding:0 1em;white-space:nowrap;overflow:hidden;background:0 0;font-size:2em;line-height:1;font-weight:400;top:0;color:#fff}.pika-next:hover,.pika-prev:hover{color:#fff}.is-rtl .pika-next,.pika-prev{left:.1em}.is-rtl .pika-prev,.pika-next{right:.1em}.pika-next.is-disabled,.pika-prev.is-disabled{cursor:default;opacity:.2}.pika-select{display:inline-block}.pika-table{width:100%;border-spacing:0;border:0}.pika-table td,.pika-table th{width:14.285714285714286%}.pika-table th{color:#999;font-weight:400;letter-spacing:1px;padding:.6em .3em;font-size:.9em;border-top:1px solid #333;font-style:none;border-bottom:1px solid #333}.pika-table th abbr{border:0}.pika-button{display:block;outline:0;border:0;width:2em;height:2em;color:#eee;font-size:1em;background:0 0;cursor:pointer;border-radius:50%;margin:.25em}.counter,.fa{display:inline-block}.is-today .pika-button{color:#8dae28}.is-selected .pika-button,.is-selected .pika-button:hover{color:#000;background:#8dae28}.is-disabled .pika-button{cursor:default;color:#fff;opacity:.3}.pika-button:hover{color:#000;background:#fff}.counter{padding:0 .5em;font-weight:400;color:#777}body.loading:before,body.over:before{position:fixed;content:"";top:0;right:0;bottom:0;left:0;background:rgba(30,30,30,.8);z-index:10000000}body.loading:after,body.over:after{position:fixed;top:50%;left:50%;z-index:10000000}body.loading:after{content:"";width:2em;height:2em;margin-left:-1em;margin-top:-1em;border-radius:50%;background:url(data:image/gif;base64,R0lGODlhEAAQAPMAAOfn51JSUpSUlCcnJ0JCQtvb27OzszU1NXp6es3NzaWlpfj4+GBgYIiIiGxsbP///yH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAAETBDISau9dYXBh2zCYmmddAxEkRElYLCEOAnoNi2sQG2GRhmDAIWDIU6MGSSAR0G4ghRa7IjIUXAog6QzpRRYhy0nILsKGuJxGcNuTyIAIfkECQoADAAsAgAAAAwAEAAABFWQyXKUvJiREVJmi3AMZIEVGzkgIABuhDIcwBIQ4YAzgfAOgsDAICEWOaQPSDVYKElC48Jo4Ah0zuBPsCCwACMFzOliIJgE06WgOnA/CSFBeVEc1IwIACH5BAkKAA0ALAIAAAAMABAAAARTsMnZAKO4qWHoEsEwHOMiFYSoikKzpESXiEcnDITZ3IgedhJBwWW4DTKSFXLBMpgKLYlhEJAsEIPoK9swkAaJhQFmMq5wQxfpGxDopAMFcsIAICMAIfkECQoAAAAsAgABAA0ADQAABEYQyEnBWnKJMEYQV5AABdGdA8Eli0kYkmF2iZBiGUc3BzzptIpQkigWcRUUgmI4NACn5aQ1EEA7r4vsBnXMUISCZKnRfZARACH5BAkKAAwALAAAAgAQAAwAAARUkEm2RBgjiDU7IFg4EEU3IYTBGSDBTSXVLaDAlMmAACajDAfCgXEBbiSGIkbxCwUME8EBE2AEp4oeADFI3BiC0Uuy4MTILdWCFRjDQKIRr1cpatwRACH5BAUKAA0ALAAAAgAQAAwAAARTsMkpxghizbmEaoZlEcVmHMOxaCAxECwjDsi2uIIEKKhVTqHAxpIQ5IYDJEtiTFg2gYFhUxAdFADma9lAzBiS28ugWaEO00nBJZoaMpuwIDo4biIAOw==) center center no-repeat #fff}body.over:after{content:"\f0ee";font-family:FontAwesome;color:#fff;font-size:3em;width:3em;height:1em;margin-left:-1.5em;margin-top:-.5em}/*! - * Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.woff2?v=4.5.0) format("woff2"),url(../fonts/fontawesome-webfont.woff?v=4.5.0) format("woff");font-weight:400;font-style:normal}.fa{font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em}.fa-li.fa-lg{left:-1.85714em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before{content:""}.fa-check-circle:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""} \ No newline at end of file diff --git a/panel/assets/fonts/fontawesome-webfont.woff b/panel/assets/fonts/fontawesome-webfont.woff deleted file mode 100644 index dc35ce3..0000000 Binary files a/panel/assets/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/panel/assets/fonts/fontawesome-webfont.woff2 b/panel/assets/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 500e517..0000000 Binary files a/panel/assets/fonts/fontawesome-webfont.woff2 and /dev/null differ diff --git a/panel/assets/fonts/sourcesanspro-400-italic.woff b/panel/assets/fonts/sourcesanspro-400-italic.woff deleted file mode 100644 index 525588f..0000000 Binary files a/panel/assets/fonts/sourcesanspro-400-italic.woff and /dev/null differ diff --git a/panel/assets/fonts/sourcesanspro-400-italic.woff2 b/panel/assets/fonts/sourcesanspro-400-italic.woff2 deleted file mode 100755 index a008526..0000000 Binary files a/panel/assets/fonts/sourcesanspro-400-italic.woff2 and /dev/null differ diff --git a/panel/assets/fonts/sourcesanspro-400.woff b/panel/assets/fonts/sourcesanspro-400.woff deleted file mode 100644 index 00b3703..0000000 Binary files a/panel/assets/fonts/sourcesanspro-400.woff and /dev/null differ diff --git a/panel/assets/fonts/sourcesanspro-400.woff2 b/panel/assets/fonts/sourcesanspro-400.woff2 deleted file mode 100755 index 0dd3464..0000000 Binary files a/panel/assets/fonts/sourcesanspro-400.woff2 and /dev/null differ diff --git a/panel/assets/fonts/sourcesanspro-600.woff b/panel/assets/fonts/sourcesanspro-600.woff deleted file mode 100644 index 8a165ec..0000000 Binary files a/panel/assets/fonts/sourcesanspro-600.woff and /dev/null differ diff --git a/panel/assets/fonts/sourcesanspro-600.woff2 b/panel/assets/fonts/sourcesanspro-600.woff2 deleted file mode 100755 index 2526d2e..0000000 Binary files a/panel/assets/fonts/sourcesanspro-600.woff2 and /dev/null differ diff --git a/panel/assets/images/avatar.png b/panel/assets/images/avatar.png deleted file mode 100644 index e200295..0000000 Binary files a/panel/assets/images/avatar.png and /dev/null differ diff --git a/panel/assets/images/hint.arrows.png b/panel/assets/images/hint.arrows.png deleted file mode 100644 index 8314e23..0000000 Binary files a/panel/assets/images/hint.arrows.png and /dev/null differ diff --git a/panel/assets/images/loader.black.gif b/panel/assets/images/loader.black.gif deleted file mode 100644 index ea331c3..0000000 Binary files a/panel/assets/images/loader.black.gif and /dev/null differ diff --git a/panel/assets/images/loader.white.gif b/panel/assets/images/loader.white.gif deleted file mode 100644 index 609cac7..0000000 Binary files a/panel/assets/images/loader.white.gif and /dev/null differ diff --git a/panel/assets/images/pattern.png b/panel/assets/images/pattern.png deleted file mode 100644 index 4bf0644..0000000 Binary files a/panel/assets/images/pattern.png and /dev/null differ diff --git a/panel/assets/images/placeholder.png b/panel/assets/images/placeholder.png deleted file mode 100644 index c82dbb5..0000000 Binary files a/panel/assets/images/placeholder.png and /dev/null differ diff --git a/panel/assets/js/dist/app.min.js b/panel/assets/js/dist/app.min.js deleted file mode 100644 index 7577c14..0000000 --- a/panel/assets/js/dist/app.min.js +++ /dev/null @@ -1 +0,0 @@ -var app={setup:function(){NProgress.configure({showSpinner:!1}),app.delay=Delay(),app.content=Content(app),app.content.setup(),app.modal=Modal(app),app.modal.setup(),new Context,new Search,$.ajaxPrefilter(function(t,a,e){a.type&&"post"==a.type.toLowerCase()&&(t.data=$.param($.extend(a.data,{csrf:$("body").attr("data-csrf")})))}),$(document).on("click","a",function(t){var a=$(this),e=a.attr("href")||"";return a.is("[data-dropdown]")||e.match(/^#/)?!0:a.is("[data-modal]")?(app.modal.open(a.attr("href")),!1):a.is("[target]")?!0:(app.content.open(e),!1)}),$(document).on("keydown",function(t){switch(t.keyCode){case 83:case 13:return t.metaKey||t.ctrlKey?(app.hasModal()||app.content.form().trigger("submit"),!1):!0;case 27:return app.modal.close(),!1}}),$(document).dropdown()},hasModal:function(){return $(".modal-content").length>0},load:function(t,a,e){if(app.isLoading(!0),"modal"==a)var o={modal:!0};else var o=!1;$.ajax({url:t,method:"GET",headers:o}).success(function(a,o,n){if(app.isLoading(!1),"object"!==$.type(a)||!a.user||!a.direction)return window.location.href=t;document.title=a.title;var r=$("body");r.hasClass(a.direction)||("ltr"==a.direction?r.removeClass("rtl").addClass("ltr"):r.removeClass("ltr").addClass("rtl"));try{e(a)}catch(d){window.location.href=t}}).error(function(){window.location.href=t})},csrf:function(){return $("body").attr("data-csrf")},isLoading:function(t){t?app.delay.start("loader",function(){NProgress.start()},250):(app.delay.stop("loader"),NProgress.done())}};$(function(){app.setup()}); \ No newline at end of file diff --git a/panel/assets/js/dist/form.min.js b/panel/assets/js/dist/form.min.js deleted file mode 100644 index 778ae13..0000000 --- a/panel/assets/js/dist/form.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(t){t.fn.date=function(){return this.each(function(){if(t(this).data("pikaday"))return t(this);var e=t(this).attr("type","text"),a=e.next(),n=e.data("format"),r=e.val(),i=r?moment(r).format(n):null;if(e.attr("placeholder",n),e.val(i),e.is("[readonly]"))return!1;e.on("change",function(){var t=e.val();t?a.val(moment(t,n).format("YYYY-MM-DD")):a.val("")});var o=new Pikaday({field:this,firstDay:1,format:n,i18n:e.data("i18n"),onSelect:function(t){a.val(moment(t).format("YYYY-MM-DD"))}});t(this).data("pikaday",o)})}}(jQuery),function(t){t.fn.imagefield=function(){return this.each(function(){var e=t(this);if(e.data("imagefield"))return!0;e.data("imagefield",!0);var a=e.find("select"),n=e.find(".input-preview figure"),r=n.parent("a");a.on("keydown change",function(){var t=a.find("option:selected"),e=t.data("url"),i=t.data("thumb");""===t.val()&&(e="#"),i?n.attr("style","background-image: url("+i+")"):n.attr("style","background-image: none"),r.attr("href",e)}).trigger("change"),e.find(".input-preview").on("click",function(){return"#"==t(this).attr("href")?!1:void 0}),e.find(".input").droppable({hoverClass:"over",accept:t(".sidebar .draggable-file"),drop:function(e,a){t(this).find("select").val(a.draggable.data("helper")).trigger("change")}})})}}(jQuery),function(t){var e=function(e){var a=t(e),n=a.data("style"),r=a.data("api"),i=a.data("sortable"),o="table"==n?a.find(".structure-table tbody"):a.find(".structure-entries");return i===!1?!1:void o.sortable({helper:function(e,a){return a.children().each(function(){t(this).width(t(this).width())}),a.addClass("structure-sortable-helper")},update:function(){var e=[];t.each(t(this).sortable("toArray"),function(t,a){e.push(a.replace("structure-entry-",""))}),t.post(r,{ids:e},function(){app.content.reload()})}})};t.fn.structure=function(){return this.each(function(){if(t(this).data("structure"))return t(this);var a=new e(this);return t(this).data("structure",a),t(this)})}}(jQuery),function(t){t.fn.counter=function(){return this.each(function(){var e=t(this);if(e.data("counter"))return e;var a=e.parent(".field").find(".input"),n=t.trim(a.val()).length,r=a.data("max"),i=a.data("min");a.keyup(function(){n=t.trim(a.val()).length,e.text(n+(r?"/"+r:"")),r&&n>r||i&&i>n?e.addClass("outside-range"):e.removeClass("outside-range")}).trigger("keyup"),e.data("counter",!0)})}}(jQuery),function(t){t.fn.editor=function(){return this.each(function(){if(t(this).data("editor"))return t(this);var e=t(this),a=e.parent().find(".field-buttons");e.autosize(),a.find(".btn").on("click.editorButton",function(a){e.focus();var n=t(this);if(n.data("action"))app.modal.open(n.data("action"),window.location.href);else{var r=e.getSelection(),i=n.data("tpl"),o=n.data("text");r.length>0&&(o=r);var u=i.replace("{text}",o);e.insertAtCursor(u),e.trigger("autosize.resize")}return!1}),a.find("[data-editor-shortcut]").each(function(a,n){var r=t(this).data("editor-shortcut"),i=function(e){return t(n).trigger("click"),!1};e.bind("keydown",r,i),r.match(/meta\+/)&&e.bind("keydown",r.replace("meta+","ctrl+"),i)}),e.data("editor",!0)})}}(jQuery),function(t){t.fn.urlfield=function(){return this.each(function(){var e=t(this);if(!e.data("urlfield")){e.data("urlfield",!0);var a=e.next(".field-icon");a.css({cursor:"pointer","pointer-events":"auto"}),a.on("click",function(){var a=t.trim(e.val());""!==a&&e.is(":valid")?window.open(a):e.focus()})}})}}(jQuery); \ No newline at end of file diff --git a/panel/assets/js/dist/panel.min.js b/panel/assets/js/dist/panel.min.js deleted file mode 100644 index a21b1cc..0000000 --- a/panel/assets/js/dist/panel.min.js +++ /dev/null @@ -1,8 +0,0 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.moment=e()}(this,function(){"use strict";function t(){return Hn.apply(null,arguments)}function e(t){Hn=t}function n(t){return"[object Array]"===Object.prototype.toString.call(t)}function i(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function o(t,e){var n,i=[];for(n=0;n0)for(n in Yn)i=Yn[n],o=e[i],"undefined"!=typeof o&&(t[i]=o);return t}function f(e){d(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),Ln===!1&&(Ln=!0,t.updateOffset(this),Ln=!1)}function p(t){return t instanceof f||null!=t&&null!=t._isAMomentObject}function m(t){return 0>t?Math.ceil(t):Math.floor(t)}function g(t){var e=+t,n=0;return 0!==e&&isFinite(e)&&(n=m(e)),n}function v(t,e,n){var i,o=Math.min(t.length,e.length),r=Math.abs(t.length-e.length),s=0;for(i=0;o>i;i++)(n&&t[i]!==e[i]||!n&&g(t[i])!==g(e[i]))&&s++;return s+r}function y(){}function b(t){return t?t.toLowerCase().replace("_","-"):t}function _(t){for(var e,n,i,o,r=0;r0;){if(i=w(o.slice(0,e).join("-")))return i;if(n&&n.length>=e&&v(o,n,!0)>=e-1)break;e--}r++}return null}function w(t){var e=null;if(!jn[t]&&"undefined"!=typeof module&&module&&module.exports)try{e=An._abbr,require("./locale/"+t),x(e)}catch(n){}return jn[t]}function x(t,e){var n;return t&&(n="undefined"==typeof e?D(t):k(t,e),n&&(An=n)),An._abbr}function k(t,e){return null!==e?(e.abbr=t,jn[t]=jn[t]||new y,jn[t].set(e),x(t),jn[t]):(delete jn[t],null)}function D(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return An;if(!n(t)){if(e=w(t))return e;t=[t]}return _(t)}function C(t,e){var n=t.toLowerCase();Wn[n]=Wn[n+"s"]=Wn[e]=t}function T(t){return"string"==typeof t?Wn[t]||Wn[t.toLowerCase()]:void 0}function S(t){var e,n,i={};for(n in t)r(t,n)&&(e=T(n),e&&(i[e]=t[n]));return i}function P(e,n){return function(i){return null!=i?(N(this,e,i),t.updateOffset(this,n),this):M(this,e)}}function M(t,e){return t._d["get"+(t._isUTC?"UTC":"")+e]()}function N(t,e,n){return t._d["set"+(t._isUTC?"UTC":"")+e](n)}function E(t,e){var n;if("object"==typeof t)for(n in t)this.set(n,t[n]);else if(t=T(t),"function"==typeof this[t])return this[t](e);return this}function O(t,e,n){var i=""+Math.abs(t),o=e-i.length,r=t>=0;return(r?n?"+":"":"-")+Math.pow(10,Math.max(0,o)).toString().substr(1)+i}function I(t,e,n,i){var o=i;"string"==typeof i&&(o=function(){return this[i]()}),t&&(qn[t]=o),e&&(qn[e[0]]=function(){return O(o.apply(this,arguments),e[1],e[2])}),n&&(qn[n]=function(){return this.localeData().ordinal(o.apply(this,arguments),t)})}function H(t){return t.match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"")}function A(t){var e,n,i=t.match(Fn);for(e=0,n=i.length;n>e;e++)qn[i[e]]?i[e]=qn[i[e]]:i[e]=H(i[e]);return function(o){var r="";for(e=0;n>e;e++)r+=i[e]instanceof Function?i[e].call(o,t):i[e];return r}}function Y(t,e){return t.isValid()?(e=L(e,t.localeData()),zn[e]=zn[e]||A(e),zn[e](t)):t.localeData().invalidDate()}function L(t,e){function n(t){return e.longDateFormat(t)||t}var i=5;for(Rn.lastIndex=0;i>=0&&Rn.test(t);)t=t.replace(Rn,n),Rn.lastIndex=0,i-=1;return t}function j(t){return"function"==typeof t&&"[object Function]"===Object.prototype.toString.call(t)}function W(t,e,n){oi[t]=j(e)?e:function(t){return t&&n?n:e}}function F(t,e){return r(oi,t)?oi[t](e._strict,e._locale):new RegExp(R(t))}function R(t){return t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,n,i,o){return e||n||i||o}).replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function z(t,e){var n,i=e;for("string"==typeof t&&(t=[t]),"number"==typeof e&&(i=function(t,n){n[e]=g(t)}),n=0;ni;i++){if(o=a([2e3,i]),n&&!this._longMonthsParse[i]&&(this._longMonthsParse[i]=new RegExp("^"+this.months(o,"").replace(".","")+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(o,"").replace(".","")+"$","i")),n||this._monthsParse[i]||(r="^"+this.months(o,"")+"|^"+this.monthsShort(o,""),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[i].test(t))return i;if(n&&"MMM"===e&&this._shortMonthsParse[i].test(t))return i;if(!n&&this._monthsParse[i].test(t))return i}}function Q(t,e){var n;return"string"==typeof e&&(e=t.localeData().monthsParse(e),"number"!=typeof e)?t:(n=Math.min(t.date(),U(t.year(),e)),t._d["set"+(t._isUTC?"UTC":"")+"Month"](e,n),t)}function V(e){return null!=e?(Q(this,e),t.updateOffset(this,!0),this):M(this,"Month")}function Z(){return U(this.year(),this.month())}function J(t){var e,n=t._a;return n&&-2===c(t).overflow&&(e=n[ai]<0||n[ai]>11?ai:n[li]<1||n[li]>U(n[si],n[ai])?li:n[ci]<0||n[ci]>24||24===n[ci]&&(0!==n[ui]||0!==n[hi]||0!==n[di])?ci:n[ui]<0||n[ui]>59?ui:n[hi]<0||n[hi]>59?hi:n[di]<0||n[di]>999?di:-1,c(t)._overflowDayOfYear&&(si>e||e>li)&&(e=li),c(t).overflow=e),t}function K(e){t.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function tt(t,e){var n=!0;return s(function(){return n&&(K(t+"\n"+(new Error).stack),n=!1),e.apply(this,arguments)},e)}function et(t,e){mi[t]||(K(e),mi[t]=!0)}function nt(t){var e,n,i=t._i,o=gi.exec(i);if(o){for(c(t).iso=!0,e=0,n=vi.length;n>e;e++)if(vi[e][1].exec(i)){t._f=vi[e][0];break}for(e=0,n=yi.length;n>e;e++)if(yi[e][1].exec(i)){t._f+=(o[6]||" ")+yi[e][0];break}i.match(ei)&&(t._f+="Z"),wt(t)}else t._isValid=!1}function it(e){var n=bi.exec(e._i);return null!==n?void(e._d=new Date(+n[1])):(nt(e),void(e._isValid===!1&&(delete e._isValid,t.createFromInputFallback(e))))}function ot(t,e,n,i,o,r,s){var a=new Date(t,e,n,i,o,r,s);return 1970>t&&a.setFullYear(t),a}function rt(t){var e=new Date(Date.UTC.apply(null,arguments));return 1970>t&&e.setUTCFullYear(t),e}function st(t){return at(t)?366:365}function at(t){return t%4===0&&t%100!==0||t%400===0}function lt(){return at(this.year())}function ct(t,e,n){var i,o=n-e,r=n-t.day();return r>o&&(r-=7),o-7>r&&(r+=7),i=Mt(t).add(r,"d"),{week:Math.ceil(i.dayOfYear()/7),year:i.year()}}function ut(t){return ct(t,this._week.dow,this._week.doy).week}function ht(){return this._week.dow}function dt(){return this._week.doy}function ft(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")}function pt(t){var e=ct(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")}function mt(t,e,n,i,o){var r,s=6+o-i,a=rt(t,0,1+s),l=a.getUTCDay();return o>l&&(l+=7),n=null!=n?1*n:o,r=1+s+7*(e-1)-l+n,{year:r>0?t:t-1,dayOfYear:r>0?r:st(t-1)+r}}function gt(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")}function vt(t,e,n){return null!=t?t:null!=e?e:n}function yt(t){var e=new Date;return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}function bt(t){var e,n,i,o,r=[];if(!t._d){for(i=yt(t),t._w&&null==t._a[li]&&null==t._a[ai]&&_t(t),t._dayOfYear&&(o=vt(t._a[si],i[si]),t._dayOfYear>st(o)&&(c(t)._overflowDayOfYear=!0),n=rt(o,0,t._dayOfYear),t._a[ai]=n.getUTCMonth(),t._a[li]=n.getUTCDate()),e=0;3>e&&null==t._a[e];++e)t._a[e]=r[e]=i[e];for(;7>e;e++)t._a[e]=r[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[ci]&&0===t._a[ui]&&0===t._a[hi]&&0===t._a[di]&&(t._nextDay=!0,t._a[ci]=0),t._d=(t._useUTC?rt:ot).apply(null,r),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[ci]=24)}}function _t(t){var e,n,i,o,r,s,a;e=t._w,null!=e.GG||null!=e.W||null!=e.E?(r=1,s=4,n=vt(e.GG,t._a[si],ct(Mt(),1,4).year),i=vt(e.W,1),o=vt(e.E,1)):(r=t._locale._week.dow,s=t._locale._week.doy,n=vt(e.gg,t._a[si],ct(Mt(),r,s).year),i=vt(e.w,1),null!=e.d?(o=e.d,r>o&&++i):o=null!=e.e?e.e+r:r),a=mt(n,i,o,s,r),t._a[si]=a.year,t._dayOfYear=a.dayOfYear}function wt(e){if(e._f===t.ISO_8601)return void nt(e);e._a=[],c(e).empty=!0;var n,i,o,r,s,a=""+e._i,l=a.length,u=0;for(o=L(e._f,e._locale).match(Fn)||[],n=0;n0&&c(e).unusedInput.push(s),a=a.slice(a.indexOf(i)+i.length),u+=i.length),qn[r]?(i?c(e).empty=!1:c(e).unusedTokens.push(r),$(r,i,e)):e._strict&&!i&&c(e).unusedTokens.push(r);c(e).charsLeftOver=l-u,a.length>0&&c(e).unusedInput.push(a),c(e).bigHour===!0&&e._a[ci]<=12&&e._a[ci]>0&&(c(e).bigHour=void 0),e._a[ci]=xt(e._locale,e._a[ci],e._meridiem),bt(e),J(e)}function xt(t,e,n){var i;return null==n?e:null!=t.meridiemHour?t.meridiemHour(e,n):null!=t.isPM?(i=t.isPM(n),i&&12>e&&(e+=12),i||12!==e||(e=0),e):e}function kt(t){var e,n,i,o,r;if(0===t._f.length)return c(t).invalidFormat=!0,void(t._d=new Date(NaN));for(o=0;or)&&(i=r,n=e));s(t,n||e)}function Dt(t){if(!t._d){var e=S(t._i);t._a=[e.year,e.month,e.day||e.date,e.hour,e.minute,e.second,e.millisecond],bt(t)}}function Ct(t){var e=new f(J(Tt(t)));return e._nextDay&&(e.add(1,"d"),e._nextDay=void 0),e}function Tt(t){var e=t._i,o=t._f;return t._locale=t._locale||D(t._l),null===e||void 0===o&&""===e?h({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),p(e)?new f(J(e)):(n(o)?kt(t):o?wt(t):i(e)?t._d=e:St(t),t))}function St(e){var r=e._i;void 0===r?e._d=new Date:i(r)?e._d=new Date(+r):"string"==typeof r?it(e):n(r)?(e._a=o(r.slice(0),function(t){return parseInt(t,10)}),bt(e)):"object"==typeof r?Dt(e):"number"==typeof r?e._d=new Date(r):t.createFromInputFallback(e)}function Pt(t,e,n,i,o){var r={};return"boolean"==typeof n&&(i=n,n=void 0),r._isAMomentObject=!0,r._useUTC=r._isUTC=o,r._l=n,r._i=t,r._f=e,r._strict=i,Ct(r)}function Mt(t,e,n,i){return Pt(t,e,n,i,!1)}function Nt(t,e){var i,o;if(1===e.length&&n(e[0])&&(e=e[0]),!e.length)return Mt();for(i=e[0],o=1;ot&&(t=-t,n="-"),n+O(~~(t/60),2)+e+O(~~t%60,2)})}function Yt(t){var e=(t||"").match(ei)||[],n=e[e.length-1]||[],i=(n+"").match(Di)||["-",0,0],o=+(60*i[1])+g(i[2]);return"+"===i[0]?o:-o}function Lt(e,n){var o,r;return n._isUTC?(o=n.clone(),r=(p(e)||i(e)?+e:+Mt(e))-+o,o._d.setTime(+o._d+r),t.updateOffset(o,!1),o):Mt(e).local()}function jt(t){return 15*-Math.round(t._d.getTimezoneOffset()/15)}function Wt(e,n){var i,o=this._offset||0;return null!=e?("string"==typeof e&&(e=Yt(e)),Math.abs(e)<16&&(e=60*e),!this._isUTC&&n&&(i=jt(this)),this._offset=e,this._isUTC=!0,null!=i&&this.add(i,"m"),o!==e&&(!n||this._changeInProgress?ee(this,Vt(e-o,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,t.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?o:jt(this)}function Ft(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()}function Rt(t){return this.utcOffset(0,t)}function zt(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(jt(this),"m")),this}function qt(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(Yt(this._i)),this}function $t(t){return t=t?Mt(t).utcOffset():0,(this.utcOffset()-t)%60===0}function Ut(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Bt(){if("undefined"!=typeof this._isDSTShifted)return this._isDSTShifted;var t={};if(d(t,this),t=Tt(t),t._a){var e=t._isUTC?a(t._a):Mt(t._a);this._isDSTShifted=this.isValid()&&v(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Xt(){return!this._isUTC}function Gt(){return this._isUTC}function Qt(){return this._isUTC&&0===this._offset}function Vt(t,e){var n,i,o,s=t,a=null;return Ht(t)?s={ms:t._milliseconds,d:t._days,M:t._months}:"number"==typeof t?(s={},e?s[e]=t:s.milliseconds=t):(a=Ci.exec(t))?(n="-"===a[1]?-1:1,s={y:0,d:g(a[li])*n,h:g(a[ci])*n,m:g(a[ui])*n,s:g(a[hi])*n,ms:g(a[di])*n}):(a=Ti.exec(t))?(n="-"===a[1]?-1:1,s={y:Zt(a[2],n),M:Zt(a[3],n),d:Zt(a[4],n),h:Zt(a[5],n),m:Zt(a[6],n),s:Zt(a[7],n),w:Zt(a[8],n)}):null==s?s={}:"object"==typeof s&&("from"in s||"to"in s)&&(o=Kt(Mt(s.from),Mt(s.to)),s={},s.ms=o.milliseconds,s.M=o.months),i=new It(s),Ht(t)&&r(t,"_locale")&&(i._locale=t._locale),i}function Zt(t,e){var n=t&&parseFloat(t.replace(",","."));return(isNaN(n)?0:n)*e}function Jt(t,e){var n={milliseconds:0,months:0};return n.months=e.month()-t.month()+12*(e.year()-t.year()),t.clone().add(n.months,"M").isAfter(e)&&--n.months,n.milliseconds=+e-+t.clone().add(n.months,"M"),n}function Kt(t,e){var n;return e=Lt(e,t),t.isBefore(e)?n=Jt(t,e):(n=Jt(e,t),n.milliseconds=-n.milliseconds,n.months=-n.months),n}function te(t,e){return function(n,i){var o,r;return null===i||isNaN(+i)||(et(e,"moment()."+e+"(period, number) is deprecated. Please use moment()."+e+"(number, period)."),r=n,n=i,i=r),n="string"==typeof n?+n:n,o=Vt(n,i),ee(this,o,t),this}}function ee(e,n,i,o){var r=n._milliseconds,s=n._days,a=n._months;o=null==o?!0:o,r&&e._d.setTime(+e._d+r*i),s&&N(e,"Date",M(e,"Date")+s*i),a&&Q(e,M(e,"Month")+a*i),o&&t.updateOffset(e,s||a)}function ne(t,e){var n=t||Mt(),i=Lt(n,this).startOf("day"),o=this.diff(i,"days",!0),r=-6>o?"sameElse":-1>o?"lastWeek":0>o?"lastDay":1>o?"sameDay":2>o?"nextDay":7>o?"nextWeek":"sameElse";return this.format(e&&e[r]||this.localeData().calendar(r,this,Mt(n)))}function ie(){return new f(this)}function oe(t,e){var n;return e=T("undefined"!=typeof e?e:"millisecond"),"millisecond"===e?(t=p(t)?t:Mt(t),+this>+t):(n=p(t)?+t:+Mt(t),n<+this.clone().startOf(e))}function re(t,e){var n;return e=T("undefined"!=typeof e?e:"millisecond"),"millisecond"===e?(t=p(t)?t:Mt(t),+t>+this):(n=p(t)?+t:+Mt(t),+this.clone().endOf(e)e-r?(n=t.clone().add(o-1,"months"),i=(e-r)/(r-n)):(n=t.clone().add(o+1,"months"),i=(e-r)/(n-r)),-(o+i)}function ue(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function he(){var t=this.clone().utc();return 0e;e++)if(this._weekdaysParse[e]||(n=Mt([2e3,1]).day(e),i="^"+this.weekdays(n,"")+"|^"+this.weekdaysShort(n,"")+"|^"+this.weekdaysMin(n,""),this._weekdaysParse[e]=new RegExp(i.replace(".",""),"i")),this._weekdaysParse[e].test(t))return e}function Re(t){var e=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=Ye(t,this.localeData()),this.add(t-e,"d")):e}function ze(t){var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")}function qe(t){return null==t?this.day()||7:this.day(this.day()%7?t:t-7)}function $e(t,e){I(t,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)})}function Ue(t,e){return e._meridiemParse}function Be(t){return"p"===(t+"").toLowerCase().charAt(0)}function Xe(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"}function Ge(t,e){e[di]=g(1e3*("0."+t))}function Qe(){return this._isUTC?"UTC":""}function Ve(){return this._isUTC?"Coordinated Universal Time":""}function Ze(t){return Mt(1e3*t)}function Je(){return Mt.apply(null,arguments).parseZone()}function Ke(t,e,n){var i=this._calendar[t];return"function"==typeof i?i.call(e,n):i}function tn(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])}function en(){return this._invalidDate}function nn(t){return this._ordinal.replace("%d",t)}function on(t){return t}function rn(t,e,n,i){var o=this._relativeTime[n];return"function"==typeof o?o(t,e,n,i):o.replace(/%d/i,t)}function sn(t,e){var n=this._relativeTime[t>0?"future":"past"];return"function"==typeof n?n(e):n.replace(/%s/i,e)}function an(t){var e,n;for(n in t)e=t[n],"function"==typeof e?this[n]=e:this["_"+n]=e;this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function ln(t,e,n,i){var o=D(),r=a().set(i,e);return o[n](r,t)}function cn(t,e,n,i,o){if("number"==typeof t&&(e=t,t=void 0),t=t||"",null!=e)return ln(t,e,n,o);var r,s=[];for(r=0;i>r;r++)s[r]=ln(t,r,n,o);return s}function un(t,e){return cn(t,e,"months",12,"month")}function hn(t,e){return cn(t,e,"monthsShort",12,"month")}function dn(t,e){return cn(t,e,"weekdays",7,"day")}function fn(t,e){return cn(t,e,"weekdaysShort",7,"day")}function pn(t,e){return cn(t,e,"weekdaysMin",7,"day")}function mn(){var t=this._data;return this._milliseconds=Qi(this._milliseconds),this._days=Qi(this._days),this._months=Qi(this._months),t.milliseconds=Qi(t.milliseconds),t.seconds=Qi(t.seconds),t.minutes=Qi(t.minutes),t.hours=Qi(t.hours),t.months=Qi(t.months),t.years=Qi(t.years),this}function gn(t,e,n,i){var o=Vt(e,n);return t._milliseconds+=i*o._milliseconds,t._days+=i*o._days,t._months+=i*o._months,t._bubble()}function vn(t,e){return gn(this,t,e,1)}function yn(t,e){return gn(this,t,e,-1)}function bn(t){return 0>t?Math.floor(t):Math.ceil(t)}function _n(){var t,e,n,i,o,r=this._milliseconds,s=this._days,a=this._months,l=this._data;return r>=0&&s>=0&&a>=0||0>=r&&0>=s&&0>=a||(r+=864e5*bn(xn(a)+s),s=0,a=0),l.milliseconds=r%1e3,t=m(r/1e3),l.seconds=t%60,e=m(t/60),l.minutes=e%60,n=m(e/60),l.hours=n%24,s+=m(n/24),o=m(wn(s)),a+=o,s-=bn(xn(o)),i=m(a/12),a%=12,l.days=s,l.months=a,l.years=i,this}function wn(t){return 4800*t/146097}function xn(t){return 146097*t/4800}function kn(t){var e,n,i=this._milliseconds;if(t=T(t),"month"===t||"year"===t)return e=this._days+i/864e5,n=this._months+wn(e),"month"===t?n:n/12;switch(e=this._days+Math.round(xn(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}}function Dn(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*g(this._months/12)}function Cn(t){return function(){return this.as(t)}}function Tn(t){return t=T(t),this[t+"s"]()}function Sn(t){return function(){return this._data[t]}}function Pn(){return m(this.days()/7)}function Mn(t,e,n,i,o){return o.relativeTime(e||1,!!n,t,i)}function Nn(t,e,n){var i=Vt(t).abs(),o=ho(i.as("s")),r=ho(i.as("m")),s=ho(i.as("h")),a=ho(i.as("d")),l=ho(i.as("M")),c=ho(i.as("y")),u=o0,u[4]=n,Mn.apply(null,u)}function En(t,e){return void 0===fo[t]?!1:void 0===e?fo[t]:(fo[t]=e,!0)}function On(t){var e=this.localeData(),n=Nn(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)}function In(){var t,e,n,i=po(this._milliseconds)/1e3,o=po(this._days),r=po(this._months);t=m(i/60),e=m(t/60),i%=60,t%=60,n=m(r/12),r%=12;var s=n,a=r,l=o,c=e,u=t,h=i,d=this.asSeconds();return d?(0>d?"-":"")+"P"+(s?s+"Y":"")+(a?a+"M":"")+(l?l+"D":"")+(c||u||h?"T":"")+(c?c+"H":"")+(u?u+"M":"")+(h?h+"S":""):"P0D"}var Hn,An,Yn=t.momentProperties=[],Ln=!1,jn={},Wn={},Fn=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,Rn=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,zn={},qn={},$n=/\d/,Un=/\d\d/,Bn=/\d{3}/,Xn=/\d{4}/,Gn=/[+-]?\d{6}/,Qn=/\d\d?/,Vn=/\d{1,3}/,Zn=/\d{1,4}/,Jn=/[+-]?\d{1,6}/,Kn=/\d+/,ti=/[+-]?\d+/,ei=/Z|[+-]\d\d:?\d\d/gi,ni=/[+-]?\d+(\.\d{1,3})?/,ii=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,oi={},ri={},si=0,ai=1,li=2,ci=3,ui=4,hi=5,di=6;I("M",["MM",2],"Mo",function(){return this.month()+1}),I("MMM",0,0,function(t){return this.localeData().monthsShort(this,t)}),I("MMMM",0,0,function(t){return this.localeData().months(this,t)}),C("month","M"),W("M",Qn),W("MM",Qn,Un),W("MMM",ii),W("MMMM",ii),z(["M","MM"],function(t,e){e[ai]=g(t)-1}),z(["MMM","MMMM"],function(t,e,n,i){var o=n._locale.monthsParse(t,i,n._strict);null!=o?e[ai]=o:c(n).invalidMonth=t});var fi="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),pi="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),mi={};t.suppressDeprecationWarnings=!1;var gi=/^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,vi=[["YYYYYY-MM-DD",/[+-]\d{6}-\d{2}-\d{2}/],["YYYY-MM-DD",/\d{4}-\d{2}-\d{2}/],["GGGG-[W]WW-E",/\d{4}-W\d{2}-\d/],["GGGG-[W]WW",/\d{4}-W\d{2}/],["YYYY-DDD",/\d{4}-\d{3}/]],yi=[["HH:mm:ss.SSSS",/(T| )\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],bi=/^\/?Date\((\-?\d+)/i;t.createFromInputFallback=tt("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(t){t._d=new Date(t._i+(t._useUTC?" UTC":""))}),I(0,["YY",2],0,function(){return this.year()%100}),I(0,["YYYY",4],0,"year"),I(0,["YYYYY",5],0,"year"),I(0,["YYYYYY",6,!0],0,"year"),C("year","y"),W("Y",ti),W("YY",Qn,Un),W("YYYY",Zn,Xn),W("YYYYY",Jn,Gn),W("YYYYYY",Jn,Gn),z(["YYYYY","YYYYYY"],si),z("YYYY",function(e,n){n[si]=2===e.length?t.parseTwoDigitYear(e):g(e)}),z("YY",function(e,n){n[si]=t.parseTwoDigitYear(e)}),t.parseTwoDigitYear=function(t){return g(t)+(g(t)>68?1900:2e3)};var _i=P("FullYear",!1);I("w",["ww",2],"wo","week"),I("W",["WW",2],"Wo","isoWeek"),C("week","w"),C("isoWeek","W"),W("w",Qn),W("ww",Qn,Un),W("W",Qn),W("WW",Qn,Un),q(["w","ww","W","WW"],function(t,e,n,i){e[i.substr(0,1)]=g(t)});var wi={dow:0,doy:6};I("DDD",["DDDD",3],"DDDo","dayOfYear"),C("dayOfYear","DDD"),W("DDD",Vn),W("DDDD",Bn),z(["DDD","DDDD"],function(t,e,n){n._dayOfYear=g(t)}),t.ISO_8601=function(){};var xi=tt("moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(){var t=Mt.apply(null,arguments);return this>t?this:t}),ki=tt("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(){var t=Mt.apply(null,arguments);return t>this?this:t});At("Z",":"),At("ZZ",""),W("Z",ei),W("ZZ",ei),z(["Z","ZZ"],function(t,e,n){n._useUTC=!0,n._tzm=Yt(t)});var Di=/([\+\-]|\d\d)/gi;t.updateOffset=function(){};var Ci=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,Ti=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;Vt.fn=It.prototype;var Si=te(1,"add"),Pi=te(-1,"subtract");t.defaultFormat="YYYY-MM-DDTHH:mm:ssZ";var Mi=tt("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(t){return void 0===t?this.localeData():this.locale(t)});I(0,["gg",2],0,function(){return this.weekYear()%100}),I(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Me("gggg","weekYear"),Me("ggggg","weekYear"),Me("GGGG","isoWeekYear"),Me("GGGGG","isoWeekYear"),C("weekYear","gg"),C("isoWeekYear","GG"),W("G",ti),W("g",ti),W("GG",Qn,Un),W("gg",Qn,Un),W("GGGG",Zn,Xn),W("gggg",Zn,Xn),W("GGGGG",Jn,Gn),W("ggggg",Jn,Gn),q(["gggg","ggggg","GGGG","GGGGG"],function(t,e,n,i){e[i.substr(0,2)]=g(t)}),q(["gg","GG"],function(e,n,i,o){n[o]=t.parseTwoDigitYear(e)}),I("Q",0,0,"quarter"),C("quarter","Q"),W("Q",$n),z("Q",function(t,e){e[ai]=3*(g(t)-1)}),I("D",["DD",2],"Do","date"),C("date","D"),W("D",Qn),W("DD",Qn,Un),W("Do",function(t,e){return t?e._ordinalParse:e._ordinalParseLenient}),z(["D","DD"],li),z("Do",function(t,e){e[li]=g(t.match(Qn)[0],10)});var Ni=P("Date",!0);I("d",0,"do","day"),I("dd",0,0,function(t){return this.localeData().weekdaysMin(this,t)}),I("ddd",0,0,function(t){return this.localeData().weekdaysShort(this,t)}),I("dddd",0,0,function(t){return this.localeData().weekdays(this,t)}),I("e",0,0,"weekday"),I("E",0,0,"isoWeekday"),C("day","d"),C("weekday","e"),C("isoWeekday","E"),W("d",Qn),W("e",Qn),W("E",Qn),W("dd",ii),W("ddd",ii),W("dddd",ii),q(["dd","ddd","dddd"],function(t,e,n){var i=n._locale.weekdaysParse(t);null!=i?e.d=i:c(n).invalidWeekday=t}),q(["d","e","E"],function(t,e,n,i){e[i]=g(t)});var Ei="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Oi="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Ii="Su_Mo_Tu_We_Th_Fr_Sa".split("_");I("H",["HH",2],0,"hour"),I("h",["hh",2],0,function(){return this.hours()%12||12}),$e("a",!0),$e("A",!1),C("hour","h"),W("a",Ue),W("A",Ue),W("H",Qn),W("h",Qn),W("HH",Qn,Un),W("hh",Qn,Un),z(["H","HH"],ci),z(["a","A"],function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t}),z(["h","hh"],function(t,e,n){e[ci]=g(t),c(n).bigHour=!0});var Hi=/[ap]\.?m?\.?/i,Ai=P("Hours",!0);I("m",["mm",2],0,"minute"),C("minute","m"),W("m",Qn),W("mm",Qn,Un),z(["m","mm"],ui);var Yi=P("Minutes",!1);I("s",["ss",2],0,"second"),C("second","s"),W("s",Qn),W("ss",Qn,Un),z(["s","ss"],hi);var Li=P("Seconds",!1);I("S",0,0,function(){return~~(this.millisecond()/100)}),I(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),I(0,["SSS",3],0,"millisecond"),I(0,["SSSS",4],0,function(){return 10*this.millisecond()}),I(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),I(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),I(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),I(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),I(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),C("millisecond","ms"),W("S",Vn,$n),W("SS",Vn,Un),W("SSS",Vn,Bn);var ji;for(ji="SSSS";ji.length<=9;ji+="S")W(ji,Kn);for(ji="S";ji.length<=9;ji+="S")z(ji,Ge);var Wi=P("Milliseconds",!1);I("z",0,0,"zoneAbbr"),I("zz",0,0,"zoneName");var Fi=f.prototype;Fi.add=Si,Fi.calendar=ne,Fi.clone=ie,Fi.diff=le,Fi.endOf=_e,Fi.format=de,Fi.from=fe,Fi.fromNow=pe,Fi.to=me,Fi.toNow=ge,Fi.get=E,Fi.invalidAt=Pe,Fi.isAfter=oe,Fi.isBefore=re,Fi.isBetween=se,Fi.isSame=ae,Fi.isValid=Te,Fi.lang=Mi,Fi.locale=ve,Fi.localeData=ye,Fi.max=ki,Fi.min=xi,Fi.parsingFlags=Se,Fi.set=E,Fi.startOf=be,Fi.subtract=Pi,Fi.toArray=De,Fi.toObject=Ce,Fi.toDate=ke,Fi.toISOString=he,Fi.toJSON=he,Fi.toString=ue,Fi.unix=xe,Fi.valueOf=we,Fi.year=_i,Fi.isLeapYear=lt,Fi.weekYear=Ee,Fi.isoWeekYear=Oe,Fi.quarter=Fi.quarters=Ae,Fi.month=V,Fi.daysInMonth=Z,Fi.week=Fi.weeks=ft,Fi.isoWeek=Fi.isoWeeks=pt,Fi.weeksInYear=He,Fi.isoWeeksInYear=Ie,Fi.date=Ni,Fi.day=Fi.days=Re,Fi.weekday=ze,Fi.isoWeekday=qe,Fi.dayOfYear=gt,Fi.hour=Fi.hours=Ai,Fi.minute=Fi.minutes=Yi,Fi.second=Fi.seconds=Li, -Fi.millisecond=Fi.milliseconds=Wi,Fi.utcOffset=Wt,Fi.utc=Rt,Fi.local=zt,Fi.parseZone=qt,Fi.hasAlignedHourOffset=$t,Fi.isDST=Ut,Fi.isDSTShifted=Bt,Fi.isLocal=Xt,Fi.isUtcOffset=Gt,Fi.isUtc=Qt,Fi.isUTC=Qt,Fi.zoneAbbr=Qe,Fi.zoneName=Ve,Fi.dates=tt("dates accessor is deprecated. Use date instead.",Ni),Fi.months=tt("months accessor is deprecated. Use month instead",V),Fi.years=tt("years accessor is deprecated. Use year instead",_i),Fi.zone=tt("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",Ft);var Ri=Fi,zi={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},qi={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},$i="Invalid date",Ui="%d",Bi=/\d{1,2}/,Xi={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},Gi=y.prototype;Gi._calendar=zi,Gi.calendar=Ke,Gi._longDateFormat=qi,Gi.longDateFormat=tn,Gi._invalidDate=$i,Gi.invalidDate=en,Gi._ordinal=Ui,Gi.ordinal=nn,Gi._ordinalParse=Bi,Gi.preparse=on,Gi.postformat=on,Gi._relativeTime=Xi,Gi.relativeTime=rn,Gi.pastFuture=sn,Gi.set=an,Gi.months=B,Gi._months=fi,Gi.monthsShort=X,Gi._monthsShort=pi,Gi.monthsParse=G,Gi.week=ut,Gi._week=wi,Gi.firstDayOfYear=dt,Gi.firstDayOfWeek=ht,Gi.weekdays=Le,Gi._weekdays=Ei,Gi.weekdaysMin=We,Gi._weekdaysMin=Ii,Gi.weekdaysShort=je,Gi._weekdaysShort=Oi,Gi.weekdaysParse=Fe,Gi.isPM=Be,Gi._meridiemParse=Hi,Gi.meridiem=Xe,x("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10,n=1===g(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th";return t+n}}),t.lang=tt("moment.lang is deprecated. Use moment.locale instead.",x),t.langData=tt("moment.langData is deprecated. Use moment.localeData instead.",D);var Qi=Math.abs,Vi=Cn("ms"),Zi=Cn("s"),Ji=Cn("m"),Ki=Cn("h"),to=Cn("d"),eo=Cn("w"),no=Cn("M"),io=Cn("y"),oo=Sn("milliseconds"),ro=Sn("seconds"),so=Sn("minutes"),ao=Sn("hours"),lo=Sn("days"),co=Sn("months"),uo=Sn("years"),ho=Math.round,fo={s:45,m:45,h:22,d:26,M:11},po=Math.abs,mo=It.prototype;mo.abs=mn,mo.add=vn,mo.subtract=yn,mo.as=kn,mo.asMilliseconds=Vi,mo.asSeconds=Zi,mo.asMinutes=Ji,mo.asHours=Ki,mo.asDays=to,mo.asWeeks=eo,mo.asMonths=no,mo.asYears=io,mo.valueOf=Dn,mo._bubble=_n,mo.get=Tn,mo.milliseconds=oo,mo.seconds=ro,mo.minutes=so,mo.hours=ao,mo.days=lo,mo.weeks=Pn,mo.months=co,mo.years=uo,mo.humanize=On,mo.toISOString=In,mo.toString=In,mo.toJSON=In,mo.locale=ve,mo.localeData=ye,mo.toIsoString=tt("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",In),mo.lang=Mi,I("X",0,0,"unix"),I("x",0,0,"valueOf"),W("x",ti),W("X",ni),z("X",function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))}),z("x",function(t,e,n){n._d=new Date(g(t))}),t.version="2.10.6",e(Mt),t.fn=Ri,t.min=Et,t.max=Ot,t.utc=a,t.unix=Ze,t.months=un,t.isDate=i,t.locale=x,t.invalid=h,t.duration=Vt,t.isMoment=p,t.weekdays=dn,t.parseZone=Je,t.localeData=D,t.isDuration=Ht,t.monthsShort=hn,t.weekdaysMin=pn,t.defineLocale=k,t.weekdaysShort=fn,t.normalizeUnits=T,t.relativeTimeThreshold=En;var go=t;return go}),function(t,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():t.NProgress=e()}(this,function(){function t(t,e,n){return e>t?e:t>n?n:t}function e(t){return 100*(-1+t)}function n(t,n,i){var o;return o="translate3d"===c.positionUsing?{transform:"translate3d("+e(t)+"%,0,0)"}:"translate"===c.positionUsing?{transform:"translate("+e(t)+"%,0)"}:{"margin-left":e(t)+"%"},o.transition="all "+n+"ms "+i,o}function i(t,e){var n="string"==typeof t?t:s(t);return n.indexOf(" "+e+" ")>=0}function o(t,e){var n=s(t),o=n+e;i(n,e)||(t.className=o.substring(1))}function r(t,e){var n,o=s(t);i(t,e)&&(n=o.replace(" "+e+" "," "),t.className=n.substring(1,n.length-1))}function s(t){return(" "+(t.className||"")+" ").replace(/\s+/gi," ")}function a(t){t&&t.parentNode&&t.parentNode.removeChild(t)}var l={};l.version="0.2.0";var c=l.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
    '};l.configure=function(t){var e,n;for(e in t)n=t[e],void 0!==n&&t.hasOwnProperty(e)&&(c[e]=n);return this},l.status=null,l.set=function(e){var i=l.isStarted();e=t(e,c.minimum,1),l.status=1===e?null:e;var o=l.render(!i),r=o.querySelector(c.barSelector),s=c.speed,a=c.easing;return o.offsetWidth,u(function(t){""===c.positionUsing&&(c.positionUsing=l.getPositioningCSS()),h(r,n(e,s,a)),1===e?(h(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout(function(){h(o,{transition:"all "+s+"ms linear",opacity:0}),setTimeout(function(){l.remove(),t()},s)},s)):setTimeout(t,s)}),this},l.isStarted=function(){return"number"==typeof l.status},l.start=function(){l.status||l.set(0);var t=function(){setTimeout(function(){l.status&&(l.trickle(),t())},c.trickleSpeed)};return c.trickle&&t(),this},l.done=function(t){return t||l.status?l.inc(.3+.5*Math.random()).set(1):this},l.inc=function(e){var n=l.status;return n?("number"!=typeof e&&(e=(1-n)*t(Math.random()*n,.1,.95)),n=t(n+e,0,.994),l.set(n)):l.start()},l.trickle=function(){return l.inc(Math.random()*c.trickleRate)},function(){var t=0,e=0;l.promise=function(n){return n&&"resolved"!==n.state()?(0===e&&l.start(),t++,e++,n.always(function(){e--,0===e?(t=0,l.done()):l.set((t-e)/t)}),this):this}}(),l.render=function(t){if(l.isRendered())return document.getElementById("nprogress");o(document.documentElement,"nprogress-busy");var n=document.createElement("div");n.id="nprogress",n.innerHTML=c.template;var i,r=n.querySelector(c.barSelector),s=t?"-100":e(l.status||0),u=document.querySelector(c.parent);return h(r,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),c.showSpinner||(i=n.querySelector(c.spinnerSelector),i&&a(i)),u!=document.body&&o(u,"nprogress-custom-parent"),u.appendChild(n),n},l.remove=function(){r(document.documentElement,"nprogress-busy"),r(document.querySelector(c.parent),"nprogress-custom-parent");var t=document.getElementById("nprogress");t&&a(t)},l.isRendered=function(){return!!document.getElementById("nprogress")},l.getPositioningCSS=function(){var t=document.body.style,e="WebkitTransform"in t?"Webkit":"MozTransform"in t?"Moz":"msTransform"in t?"ms":"OTransform"in t?"O":"";return e+"Perspective"in t?"translate3d":e+"Transform"in t?"translate":"margin"};var u=function(){function t(){var n=e.shift();n&&n(t)}var e=[];return function(n){e.push(n),1==e.length&&t()}}(),h=function(){function t(t){return t.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(t,e){return e.toUpperCase()})}function e(t){var e=document.body.style;if(t in e)return t;for(var n,i=o.length,r=t.charAt(0).toUpperCase()+t.slice(1);i--;)if(n=o[i]+r,n in e)return n;return t}function n(n){return n=t(n),r[n]||(r[n]=e(n))}function i(t,e,i){e=n(e),t.style[e]=i}var o=["Webkit","O","Moz","ms"],r={};return function(t,e){var n,o,r=arguments;if(2==r.length)for(n in e)o=e[n],void 0!==o&&e.hasOwnProperty(n)&&i(t,n,o);else i(t,r[1],r[2])}}();return l}),function(t,e){"use strict";var n;if("object"==typeof exports){try{n=require("moment")}catch(i){}module.exports=e(n)}else"function"==typeof define&&define.amd?define(function(t){var i="moment";try{n=t(i)}catch(o){}return e(n)}):t.Pikaday=e(t.moment)}(this,function(t){"use strict";var e="function"==typeof t,n=!!window.addEventListener,i=window.document,o=window.setTimeout,r=function(t,e,i,o){n?t.addEventListener(e,i,!!o):t.attachEvent("on"+e,i)},s=function(t,e,i,o){n?t.removeEventListener(e,i,!!o):t.detachEvent("on"+e,i)},a=function(t,e,n){var o;i.createEvent?(o=i.createEvent("HTMLEvents"),o.initEvent(e,!0,!1),o=b(o,n),t.dispatchEvent(o)):i.createEventObject&&(o=i.createEventObject(),o=b(o,n),t.fireEvent("on"+e,o))},l=function(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")},c=function(t,e){return-1!==(" "+t.className+" ").indexOf(" "+e+" ")},u=function(t,e){c(t,e)||(t.className=""===t.className?e:t.className+" "+e)},h=function(t,e){t.className=l((" "+t.className+" ").replace(" "+e+" "," "))},d=function(t){return/Array/.test(Object.prototype.toString.call(t))},f=function(t){return/Date/.test(Object.prototype.toString.call(t))&&!isNaN(t.getTime())},p=function(t){var e=t.getDay();return 0===e||6===e},m=function(t){return t%4===0&&t%100!==0||t%400===0},g=function(t,e){return[31,m(t)?29:28,31,30,31,30,31,31,30,31,30,31][e]},v=function(t){f(t)&&t.setHours(0,0,0,0)},y=function(t,e){return t.getTime()===e.getTime()},b=function(t,e,n){var i,o;for(i in e)o=void 0!==t[i],o&&"object"==typeof e[i]&&null!==e[i]&&void 0===e[i].nodeName?f(e[i])?n&&(t[i]=new Date(e[i].getTime())):d(e[i])?n&&(t[i]=e[i].slice(0)):t[i]=b({},e[i],n):!n&&o||(t[i]=e[i]);return t},_=function(t){return t.month<0&&(t.year-=Math.ceil(Math.abs(t.month)/12),t.month+=12),t.month>11&&(t.year+=Math.floor(Math.abs(t.month)/12),t.month-=12),t},w={field:null,bound:void 0,position:"bottom left",reposition:!0,format:"YYYY-MM-DD",defaultDate:null,setDefaultDate:!1,firstDay:0,minDate:null,maxDate:null,yearRange:10,showWeekNumber:!1,minYear:0,maxYear:9999,minMonth:void 0,maxMonth:void 0,startRange:null,endRange:null,isRTL:!1,yearSuffix:"",showMonthAfterYear:!1,numberOfMonths:1,mainCalendar:"left",container:void 0,i18n:{previousMonth:"Previous Month",nextMonth:"Next Month",months:["January","February","March","April","May","June","July","August","September","October","November","December"],weekdays:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]},theme:null,onSelect:null,onOpen:null,onClose:null,onDraw:null},x=function(t,e,n){for(e+=t.firstDay;e>=7;)e-=7;return n?t.i18n.weekdaysShort[e]:t.i18n.weekdays[e]},k=function(t){if(t.isEmpty)return'';var e=[];return t.isDisabled&&e.push("is-disabled"),t.isToday&&e.push("is-today"),t.isSelected&&e.push("is-selected"),t.isInRange&&e.push("is-inrange"),t.isStartRange&&e.push("is-startrange"),t.isEndRange&&e.push("is-endrange"),'"},D=function(t,e,n){var i=new Date(n,0,1),o=Math.ceil(((new Date(n,e,t)-i)/864e5+i.getDay()+1)/7);return''+o+""},C=function(t,e){return""+(e?t.reverse():t).join("")+""},T=function(t){return""+t.join("")+""},S=function(t){var e,n=[];for(t.showWeekNumber&&n.push(""),e=0;7>e;e++)n.push(''+x(t,e,!0)+"");return""+(t.isRTL?n.reverse():n).join("")+""},P=function(t,e,n,i,o){var r,s,a,l,c,u=t._o,h=n===u.minYear,f=n===u.maxYear,p='
    ',m=!0,g=!0;for(a=[],r=0;12>r;r++)a.push('");for(l='
    '+u.i18n.months[i]+'
    ",d(u.yearRange)?(r=u.yearRange[0],s=u.yearRange[1]+1):(r=n-u.yearRange,s=1+n+u.yearRange),a=[];s>r&&r<=u.maxYear;r++)r>=u.minYear&&a.push('");return c='
    '+n+u.yearSuffix+'
    ",p+=u.showMonthAfterYear?c+l:l+c,h&&(0===i||u.minMonth>=i)&&(m=!1),f&&(11===i||u.maxMonth<=i)&&(g=!1),0===e&&(p+='"),e===t._o.numberOfMonths-1&&(p+='"),p+="
    "},M=function(t,e){return''+S(t)+T(e)+"
    "},N=function(s){var a=this,l=a.config(s);a._onMouseDown=function(t){if(a._v){t=t||window.event;var e=t.target||t.srcElement;if(e)if(c(e.parentNode,"is-disabled")||(c(e,"pika-button")&&!c(e,"is-empty")?(a.setDate(new Date(e.getAttribute("data-pika-year"),e.getAttribute("data-pika-month"),e.getAttribute("data-pika-day"))),l.bound&&o(function(){a.hide(),l.field&&l.field.blur()},100)):c(e,"pika-prev")?a.prevMonth():c(e,"pika-next")&&a.nextMonth()),c(e,"pika-select"))a._c=!0;else{if(!t.preventDefault)return t.returnValue=!1,!1;t.preventDefault()}}},a._onChange=function(t){t=t||window.event;var e=t.target||t.srcElement;e&&(c(e,"pika-select-month")?a.gotoMonth(e.value):c(e,"pika-select-year")&&a.gotoYear(e.value))},a._onInputChange=function(n){var i;n.firedBy!==a&&(e?(i=t(l.field.value,l.format),i=i&&i.isValid()?i.toDate():null):i=new Date(Date.parse(l.field.value)),f(i)&&a.setDate(i),a._v||a.show())},a._onInputFocus=function(){a.show()},a._onInputClick=function(){a.show()},a._onInputBlur=function(){var t=i.activeElement;do if(c(t,"pika-single"))return;while(t=t.parentNode);a._c||(a._b=o(function(){a.hide()},50)),a._c=!1},a._onClick=function(t){t=t||window.event;var e=t.target||t.srcElement,i=e;if(e){!n&&c(e,"pika-select")&&(e.onchange||(e.setAttribute("onchange","return;"),r(e,"change",a._onChange)));do if(c(i,"pika-single")||i===l.trigger)return;while(i=i.parentNode);a._v&&e!==l.trigger&&i!==l.trigger&&a.hide()}},a.el=i.createElement("div"),a.el.className="pika-single"+(l.isRTL?" is-rtl":"")+(l.theme?" "+l.theme:""),r(a.el,"mousedown",a._onMouseDown,!0),r(a.el,"touchend",a._onMouseDown,!0),r(a.el,"change",a._onChange),l.field&&(l.container?l.container.appendChild(a.el):l.bound?i.body.appendChild(a.el):l.field.parentNode.insertBefore(a.el,l.field.nextSibling),r(l.field,"change",a._onInputChange),l.defaultDate||(e&&l.field.value?l.defaultDate=t(l.field.value,l.format).toDate():l.defaultDate=new Date(Date.parse(l.field.value)),l.setDefaultDate=!0));var u=l.defaultDate;f(u)?l.setDefaultDate?a.setDate(u,!0):a.gotoDate(u):a.gotoDate(new Date),l.bound?(this.hide(),a.el.className+=" is-bound",r(l.trigger,"click",a._onInputClick),r(l.trigger,"focus",a._onInputFocus),r(l.trigger,"blur",a._onInputBlur)):this.show()};return N.prototype={config:function(t){this._o||(this._o=b({},w,!0));var e=b(this._o,t,!0);e.isRTL=!!e.isRTL,e.field=e.field&&e.field.nodeName?e.field:null,e.theme="string"==typeof e.theme&&e.theme?e.theme:null,e.bound=!!(void 0!==e.bound?e.field&&e.bound:e.field),e.trigger=e.trigger&&e.trigger.nodeName?e.trigger:e.field,e.disableWeekends=!!e.disableWeekends,e.disableDayFn="function"==typeof e.disableDayFn?e.disableDayFn:null;var n=parseInt(e.numberOfMonths,10)||1;if(e.numberOfMonths=n>4?4:n,f(e.minDate)||(e.minDate=!1),f(e.maxDate)||(e.maxDate=!1),e.minDate&&e.maxDate&&e.maxDate100&&(e.yearRange=100);return e},toString:function(n){return f(this._d)?e?t(this._d).format(n||this._o.format):this._d.toDateString():""},getMoment:function(){return e?t(this._d):null},setMoment:function(n,i){e&&t.isMoment(n)&&this.setDate(n.toDate(),i)},getDate:function(){return f(this._d)?new Date(this._d.getTime()):null},setDate:function(t,e){if(!t)return this._d=null,this._o.field&&(this._o.field.value="",a(this._o.field,"change",{firedBy:this})),this.draw();if("string"==typeof t&&(t=new Date(Date.parse(t))),f(t)){var n=this._o.minDate,i=this._o.maxDate;f(n)&&n>t?t=n:f(i)&&t>i&&(t=i),this._d=new Date(t.getTime()),v(this._d),this.gotoDate(this._d),this._o.field&&(this._o.field.value=this.toString(),a(this._o.field,"change",{firedBy:this})),e||"function"!=typeof this._o.onSelect||this._o.onSelect.call(this,this.getDate())}},gotoDate:function(t){var e=!0;if(f(t)){if(this.calendars){var n=new Date(this.calendars[0].year,this.calendars[0].month,1),i=new Date(this.calendars[this.calendars.length-1].year,this.calendars[this.calendars.length-1].month,1),o=t.getTime();i.setMonth(i.getMonth()+1),i.setDate(i.getDate()-1),e=o=i&&(this._y=i,!isNaN(s)&&this._m>s&&(this._m=s));for(var l=0;l'+P(this,l,this.calendars[l].year,this.calendars[l].month,this.calendars[0].year)+this.render(this.calendars[l].year,this.calendars[l].month)+"
    ";if(this.el.innerHTML=a,e.bound&&"hidden"!==e.field.type&&o(function(){e.trigger.focus()},1),"function"==typeof this._o.onDraw){var c=this;o(function(){c._o.onDraw.call(c)},0)}}},adjustPosition:function(){var t,e,n,o,r,s,a,l,c,u;if(!this._o.container){if(this.el.style.position="absolute",t=this._o.trigger,e=t,n=this.el.offsetWidth,o=this.el.offsetHeight,r=window.innerWidth||i.documentElement.clientWidth,s=window.innerHeight||i.documentElement.clientHeight,a=window.pageYOffset||i.body.scrollTop||i.documentElement.scrollTop,"function"==typeof t.getBoundingClientRect)u=t.getBoundingClientRect(),l=u.left+window.pageXOffset,c=u.bottom+window.pageYOffset;else for(l=e.offsetLeft,c=e.offsetTop+e.offsetHeight;e=e.offsetParent;)l+=e.offsetLeft,c+=e.offsetTop;(this._o.reposition&&l+n>r||this._o.position.indexOf("right")>-1&&l-n+t.offsetWidth>0)&&(l=l-n+t.offsetWidth),(this._o.reposition&&c+o>s+a||this._o.position.indexOf("top")>-1&&c-o-t.offsetHeight>0)&&(c=c-o-t.offsetHeight),this.el.style.left=l+"px",this.el.style.top=c+"px"}},render:function(t,e){var n=this._o,i=new Date,o=g(t,e),r=new Date(t,e,1).getDay(),s=[],a=[];v(i),n.firstDay>0&&(r-=n.firstDay,0>r&&(r+=7));for(var l=o+r,c=l;c>7;)c-=7;l+=7-c;for(var u=0,h=0;l>u;u++){var d=new Date(t,e,1+(u-r)),m=f(this._d)?y(d,this._d):!1,b=y(d,i),_=r>u||u>=o+r,w=n.startRange&&y(n.startRange,d),x=n.endRange&&y(n.endRange,d),T=n.startRange&&n.endRange&&n.startRangen.maxDate||n.disableWeekends&&p(d)||n.disableDayFn&&n.disableDayFn(d),P={day:1+(u-r),month:e,year:t,isSelected:m,isToday:b,isDisabled:S,isEmpty:_,isStartRange:w,isEndRange:x,isInRange:T};a.push(k(P)),7===++h&&(n.showWeekNumber&&a.unshift(D(u-r,e,t)),s.push(C(a,n.isRTL)),a=[],h=0)}return M(n,s)},isVisible:function(){return this._v},show:function(){this._v||(h(this.el,"is-hidden"),this._v=!0,this.draw(),this._o.bound&&(r(i,"click",this._onClick),this.adjustPosition()),"function"==typeof this._o.onOpen&&this._o.onOpen.call(this))},hide:function(){var t=this._v;t!==!1&&(this._o.bound&&s(i,"click",this._onClick),this.el.style.position="static",this.el.style.left="auto",this.el.style.top="auto",u(this.el,"is-hidden"),this._v=!1,void 0!==t&&"function"==typeof this._o.onClose&&this._o.onClose.call(this))},destroy:function(){this.hide(),s(this.el,"mousedown",this._onMouseDown,!0),s(this.el,"touchend",this._onMouseDown,!0),s(this.el,"change",this._onChange),this._o.field&&(s(this._o.field,"change",this._onInputChange),this._o.bound&&(s(this._o.trigger,"click",this._onInputClick),s(this._o.trigger,"focus",this._onInputFocus),s(this._o.trigger,"blur",this._onInputBlur))),this.el.parentNode&&this.el.parentNode.removeChild(this.el)}},N}),!function(t,e){"object"==typeof module&&"object"==typeof module.exports?module.exports=t.document?e(t,!0):function(t){if(!t.document)throw new Error("jQuery requires a window with a document");return e(t)}:e(t)}("undefined"!=typeof window?window:this,function(t,e){function n(t){var e="length"in t&&t.length,n=K.type(t);return"function"===n||K.isWindow(t)?!1:1===t.nodeType&&e?!0:"array"===n||0===e||"number"==typeof e&&e>0&&e-1 in t}function i(t,e,n){if(K.isFunction(e))return K.grep(t,function(t,i){return!!e.call(t,i,t)!==n});if(e.nodeType)return K.grep(t,function(t){return t===e!==n});if("string"==typeof e){if(at.test(e))return K.filter(e,t,n);e=K.filter(e,t)}return K.grep(t,function(t){return B.call(e,t)>=0!==n})}function o(t,e){for(;(t=t[e])&&1!==t.nodeType;);return t}function r(t){var e=pt[t]={};return K.each(t.match(ft)||[],function(t,n){e[n]=!0}),e}function s(){Z.removeEventListener("DOMContentLoaded",s,!1),t.removeEventListener("load",s,!1),K.ready()}function a(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=K.expando+a.uid++}function l(t,e,n){var i;if(void 0===n&&1===t.nodeType)if(i="data-"+e.replace(_t,"-$1").toLowerCase(),n=t.getAttribute(i),"string"==typeof n){try{n="true"===n?!0:"false"===n?!1:"null"===n?null:+n+""===n?+n:bt.test(n)?K.parseJSON(n):n}catch(o){}yt.set(t,e,n)}else n=void 0;return n}function c(){return!0}function u(){return!1}function h(){try{return Z.activeElement}catch(t){}}function d(t,e){return K.nodeName(t,"table")&&K.nodeName(11!==e.nodeType?e:e.firstChild,"tr")?t.getElementsByTagName("tbody")[0]||t.appendChild(t.ownerDocument.createElement("tbody")):t}function f(t){return t.type=(null!==t.getAttribute("type"))+"/"+t.type,t}function p(t){var e=Yt.exec(t.type);return e?t.type=e[1]:t.removeAttribute("type"),t}function m(t,e){for(var n=0,i=t.length;i>n;n++)vt.set(t[n],"globalEval",!e||vt.get(e[n],"globalEval"))}function g(t,e){var n,i,o,r,s,a,l,c;if(1===e.nodeType){if(vt.hasData(t)&&(r=vt.access(t),s=vt.set(e,r),c=r.events)){delete s.handle,s.events={};for(o in c)for(n=0,i=c[o].length;i>n;n++)K.event.add(e,o,c[o][n])}yt.hasData(t)&&(a=yt.access(t),l=K.extend({},a),yt.set(e,l))}}function v(t,e){var n=t.getElementsByTagName?t.getElementsByTagName(e||"*"):t.querySelectorAll?t.querySelectorAll(e||"*"):[];return void 0===e||e&&K.nodeName(t,e)?K.merge([t],n):n}function y(t,e){var n=e.nodeName.toLowerCase();"input"===n&&Dt.test(t.type)?e.checked=t.checked:("input"===n||"textarea"===n)&&(e.defaultValue=t.defaultValue)}function b(e,n){var i,o=K(n.createElement(e)).appendTo(n.body),r=t.getDefaultComputedStyle&&(i=t.getDefaultComputedStyle(o[0]))?i.display:K.css(o[0],"display");return o.detach(),r}function _(t){var e=Z,n=Ft[t];return n||(n=b(t,e),"none"!==n&&n||(Wt=(Wt||K("