From d411be2e9e48d397af41bc552560168144e72109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Klockiewicz?= Date: Fri, 14 Apr 2017 12:39:50 +0200 Subject: [PATCH] Dodanie dokumentacji --- docs/en.md | 1315 ++++++++++++++++++++++++++++++++++++++++++++++++++++ docs/pl.md | 1314 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2629 insertions(+) create mode 100644 docs/en.md create mode 100644 docs/pl.md diff --git a/docs/en.md b/docs/en.md new file mode 100644 index 0000000..1c8de75 --- /dev/null +++ b/docs/en.md @@ -0,0 +1,1315 @@ +General +======= + +Batflat is a Polish content management system that is simple, light and fast. It was first released in May 2016. The free version of the application is shared under a [license](/license) that requires leaving information about the authors and backlinks. Batflat works great when creating small websites such as business identity, portfolios, blogs or home pages. With this documentation you will learn how to install, configure and create your own modules and themes. + +The documentation is divided into several sections. The first is for general instructions, the second is for web designers, and the last two are for web developers. + + +Requirements +------------ + +System requirements for Batflat are modest, so every modern server should suffice. + ++ Apache 2.2+ with `mod_rewrite` ++ PHP version 5.5+ ++ Access to SQLite + +PHP configuration must have the following extensions: + ++ dom ++ gd ++ mbstring ++ pdo ++ zip ++ cURL + + +Installation +------------ + +First download the latest version of [Batflat](http://feed.sruu.pl/batflat/download/latest). + +Extract all files from the compressed package and then transfer them to the local directory or remote server. In the case of a remote server, connect to it via a (S)FTP client, such as the free [FileZilla](https://filezilla-project.org) program. Usually, files should be uploaded to `www`, `htdocs` or `public_html`. + +**Warning!** Make sure the `.htaccess` file is also on the server. Without it the CMS will not work. + +Some servers may require additional permissions `chmod 777` for the following directories and files: + ++ tmp/ ++ uploads/ ++ admin/tmp/ ++ inc/data/ ++ inc/data/database.sdb + +Open your browser and navigate to the address where the Batflat's files are located. You should see a default template with sample content. + +To go to the administration panel, add `/admin/` at the end of the URL. **The initial login and password are *"admin"*.** It should be changed right after login for security reasons. We also recommend rename the directory with the administration panel. *(you need to then change the constant value in the defines file)*. + + +Configuration +------------- + +CMS can be configured by editing the settings in the administration panel and through the definition file. However, we do not recommend changing the configuration in the file if you are an inexperienced person. + +### Administration panel +To change the basic configuration in the admin panel, select the `Settings` tab. You can enter a page name, description or keywords in the meta tags, as well as elsewhere in the default template, such as in the header. You can also change the homepage, default language *(separately for the website and the panel)*, define the footer content, and choose the editor *(HTML or WYSIWYG)* that will be available when editing subpages and blog posts. + +You will change the configuration of the remaining modules in the tabs corresponding to their names. + +### Defines file +More advanced things you can change in the `inc/core/defines.php` file, which contains definitions of constant variables. + ++ `ADMIN` — the directory name that contains the administration panel ++ `THEMES` — path to the directory containing the themes ++ `MODULES` — path to the directory containing the modules ++ `UPLOADS` — path to the directory containing the uploaded files ++ `FILE_LOCK` — lock the ability to edit files through the administration panel ++ `BASIC_MODULES` — list of basic modules that can not be removed ++ `HTML_BEAUTY` — nice HTML formatting after parsing ++ `DEV_MODE` — developer mode, where PHP errors and notes are displayed + + +Update +------ + +If you want to keep up to date with all the latest news, bug fixes and security issues, you should regularly check for Batflat updates. You can do this in the `Settings -> Updates` tab. The system will check for a new version of the script and automatically download a new package from our server and update the core files and modules. + +In case of complications you can use manual mode. To do this, download the latest version of Batflat, upload it to the main application directory, and then add the `&manual` parameter to the end of the update's bookmark URL. The CMS should detect a zipped package and when you click on the update button, the process of extracting and overwriting the files will be performed. + +Before each update, Batflat creates a backup. You will find it in the script directory, in the `backup/` folder. If an update has failed, you can restore it at any time. + + +Themes +====== + +Structure +--------- + +The structure of themes in Batflat is very simple. Just create a new folder in the `themes/` directory and the `index.html` file, which will be the default template for the subpages. Each subpage can use another template, so besides the mentioned file, you can also create another, eg `xyz.html`. Template selection is available in the admin panel while creating a page. There are no rules about CSS and JS files. There is full freedom. + +In the theme folder you can also create your own module views. To do this, you need to create a directory `modules/module_name` and `*.html` files with names corresponding to the names of the original views. For example, the view of the contact form should be contained in the following path: `themes/theme_name/modules/contact/form.html`. Batflat automatically detects a new view and uses it instead of the module default view. + + +Template tags +------------- + +CMS uses a simple template system that includes the following tags: + +### Variables +```php +{$foo} // simple variable +{$foo|e} // HTML escape for variable +{$foo|cut:10} // content of the variable cut to 10 characters +{$foo.bar} // array +``` +Access to the elements of the array is done by a dot character. + +### Conditions +```php +{if: $foo > 5} + lorem +{elseif: $foo == 5} + ipsum +{else} + dolor +{/if} +``` + +### Loops +```html + +``` +The loop tag has 3 stages of expansion. The first is an array variable that the template system will break into three variables named `$key`,` $value` and `$counter`, which counts successive iterations starting from zero. The second step allows you to specify the name of the variable that holds the value, and the third is also the name of the index variable. + +### Include template files +```html + + + {template: header.html} +
+

Lorem ipsum dolor sit amet.

+
+ {template: footer.html} + + +``` + +### PHP code +```php +Today`s date: {?= date('Y-m-d') ?} +``` +If you leave the character `=`, the code will just execute and nothing will display. This allows you, for example, to define new variables within a template: +```php +{? $foo = 5 ?} +``` + +### Disable parsing +``` +{noparse}Use the {$ contact.form} tag to display contact form.{/noparse} +``` +Any tags inside the *noparse* expression will remain unchanged. + +### Comments +``` +{* this is a comment *} +``` +Comments are not visible in the source file after compiling the template. + +### Languages +``` +{lang: pl_polski} + Witaj świecie! +{/lang} +{lang: en_english} + Hello world! +{/lang} +``` +If you want to customize the template elements for a particular language, use the tags above. + + +System variables +---------------- +Batflat, like its modules, provides many variables *(usually arrays)* that serve to display each page element. Here are the most important ones: + ++ `{$settings.pole}` — an array element containing the value of the given Batflat settings field ++ `{$settings.moduł.pole}` — an array element containing the value of the module settings field ++ `{$bat.path}` — stores the path where the system resides ++ `{$bat.lang}` — displays currently used language ++ `{$bat.notify}` — the last notification ++ `{$bat.notify.text}` - notification text ++ `{$bat.notify.type}` - message type corresponding to the Bootstrap classes *(danger, success)* ++ `{$bat.header}` — additional meta tags, JS scripts and CSS style sheets loaded by modules ++ `{$bat.footer}` — additional JS scripts loaded by modules ++ `{$bat.theme}` — displays the path to the active theme with the host ++ `{$bat.powered}` — displays *Powered by Batflat* with a link to the official site ++ `{$navigation.xyz}` — displays a list of `
  • ` navigation elements ++ `{$page.title}` — displays the name of the subpage ++ `{$page.content}` — displays the contents of the subpage + +Example +------- + +```html + + + + + + {$page.title} - {$settings.title} + + + + {loop: $bat.header}{$value}{/loop} + + + + + +
    +

    {$page.title}

    + {$page.content} +
    + +
    + {$settings.footer} {$bat.powered} +
    + + + {loop: $bat.footer}{$value}{/loop} + + +``` + +Modules +======= + +Structure +--------- + +Each module, like the themes, must be in a separate folder created in the `inc/modules/` path. Please note that the directory does not contain uppercase and special characters, such as spaces. + +Podczas tworzenia modułu należy zastanowić się nad tym, jakiego typu ma być to moduł. Czy ma być konfiguralny w panelu administracyjnym, czy może ma działać wyłącznie po stronie gości odwiedzających stronę? Ze względu na taki podział, w Batflacie wyróżniamy trzy główne pliki modułu: + +When creating a module, you need to think about what type of module you want to use. Is it supposed to be configured in the admin panel or is it supposed to work only on the front-end? Due to this division, in Batflat we distinguish three main module files: + ++ `Info.php` — contains information about the module, such as name, description, author or icon ++ `Admin.php` — content of this file will be accessible through the admin panel ++ `Site.php` — content of this file will be available for visitors of this site + +The fourth but optional file is `ReadMe.md` which should contain additional information for the future user in [Markdown](https://en.wikipedia.org/wiki/Markdown), e.g. how to use the module. + +If you are planning to write a module that will use HTML, it would be good to make sure the PHP code is separate from the hypertext markup language. To do this, you need to create a directory `views` inside the module folder. Include any view files in it. + +The problem with multilingualism of the module is similar. Just create language files with the `ini` extension inside the `lang` directory. + +The structure of the module should look something like this: +``` +example/ +|-- lang/ +| |-- admin/ +| | |-- en_english.ini +| | |-- pl_polski.ini +| |-- en_english.ini +| |-- pl_polski.ini +|-- views/ +| |-- admin/ +| | |-- bar.html +| |-- foo.html +|-- Admin.php +|-- Info.php +|-- Site.php ++-- ReadMe.md +``` + +Creating a module +----------------- + +### Info file + +The most important file for each module. It contains basic information and instructions during installation and uninstallation. + +```php + 'Example', + 'description' => 'Lorem ipsum....', + 'author' => 'Robin', + 'version' => '1.0', + 'compatibility' => '1.3.*', // Compatibility with Batflat version + 'icon' => 'bolt', + + 'pages' => ['Example' => 'example'], // Registration as a page (optional) + + 'install' => function() use($core) // Install commands + { + // lorem ipsum... + }, + 'uninstall' => function() use($core) // Uninstall commands + { + // lorem ipsum... + } + ]; +``` + +A list of icons that you can use in this file is available at [fontawesome.io](http://fontawesome.io/icons/). Be sure not to enter the icon name with the `fa-` prefix. + +Registering a module as a page allows you to freely use the routing and select it as a homepage. + + +### Admin file + +The contents of this file will be launched in the admin panel. + +```php + 'foo', + 'Bar' => 'bar', + ]; + } + + public function getFoo($parm) + { + return "Foo $parm!"; + } + + public function postBar() + { + return "Bar!"; + } + } +``` + +In the `navigation` method, include array with the subpages of the module. Each page should be assigned a method *(without a prefix)*. Items of this array will be displayed in the administration panel menu. + +Methods can also accept arguments that are passed through the URL. For example, after entering the `/example/foo/abc` address, the `getFoo` method will return *"Foo abc!"*. + +As you can see in the above listing, each method representing the subpage of the module should have a prefix specifying the type of the request. In most cases we will use the `getFoo` nomenclature, and the `postFoo` form form submission. If the method supports all types, it should precede the `any` prefix *(for example, `anyFoo`)*. This is important because pages without prefix will not be handled. Supported methods are translated by dynamic routing as follows: + ++ `getFoo()` — as `/example/foo` for a GET request ++ `getFoo($parm)` — as `/example/foo/abc` for a GET request ++ `postBar()` — as `example/bar` for POST requests *(form submission)* ++ `anyFoo()` — as `/example/foo` for each request type + +### Site file + +This file is responsible for the portion seen by visitors of the website. If the module is quite large, good practice is to register it as a page and apply routing. + +```php +_foo(); + } + + public function routes() + { + $this->route('example', '_mySite'); + } + + private function _mySite() + { + $page = [ + 'title' => 'Sample title..', + 'desc' => 'Site description', + 'content' => 'Lorem ipsum dolor...' + ]; + + $this->setTemplate('index.html'); + $this->tpl->set('page', $page); + } + + private function _foo() + { + $this->tpl->set('bar', 'Why So Serious?'); + } + } +``` + +In the above example, a new `bar` template variable has been created which, by calling the `_foo()` method in the module initializer, can be used in the theme files as `{$bar}`. In addition, the `routes()` method has created a `/example` subroutine that points to the `_mySite()` method call. If you go to `http://example.com/example`, you will call the `_mySite()` method. + +### Language files + +The module can contain language variables that can be used in classes and views. Language files have a `.ini` extension and are located in the` lang` directory of the module. +For example, if you want to add a language file containing English expressions for the administrative part of the `Example` module, you should create a new file in the `inc/modules/example/lang/admin /en_english.ini` path. +The content should resemble the following listing: + +``` +full_name = "Firstname and surname" +email = "E-mail" +subject = "Subject" +message = "Message" +send = "Send" +send_success = "Mail successfully sent. I will contact you soon." +send_failure = "Unable to send a message. Probably mail() function is disabled on the server." +wrong_email = "Submited e-mail address is incorrect." +empty_inputs = "Fill all required fields to send a message." +antiflood = "You have to wait a while before you will send another message." +``` + +Use the `$this->lang('subject')` construction in the module class and `{$lang.example.subject}` in view. For a class, we can leave the second parameter of the `lang` method, which is the name of the module. + + +Routing +------- + +Routing is the process of processing a received request address and deciding what should be run or displayed. It's supposed to call the appropriate method/function based on the URL of the page. You must use routing inside public `routes()` method. + +```php +void route(string $pattern, mixed $callback) +``` + +The first parameter of the `route` method is a regular expression. Some of the expressions have already been defined: + ++ `:any` — any string ++ `:int` — integers ++ `:str` — string that is a slug + +The second parameter is a method name or an anonymous function that passes any number of arguments defined in a regular expression. + +#### Example +```php +public function routes() +{ + // URL: http://example.com/blog + + // - by calling the method inside the module: + $this->route('blog', 'importAllPosts'); + + // - by calling an anonymous function: + $this->route('blog', function() { + $this->importAllPosts(); + }); + + // URL: http://example.com/blog/2 + $this->route('blog/(:int)', function($page) { + $this->importAllPosts($page); + }); + + // URL: http://example.com/blog/post/lorem-ipsum + $this->route('blog/post/(:str)', function($slug) { + $this->importPost($slug); + }); + + // URL: http://example.com/blog/post/lorem-ipsum/4 + $this->route('blog/post/(:str)/(:int)', function($slug, $page) { + $this->importPost($slug, $page); + }); +} +``` + + +Methods +------- + +Modules have special facades that facilitate access to the methods inside the core. This allows you to shorten the calls of `$this->core->foo->bar`. + +### db + +```php +void db([string $table]) +``` + +Allows you to operate on a database. Details are described in the core section. + +#### Arguments ++ `table` — Database table name *(optional)* + +#### Example +```php +$this->db('table')->where('age', 20)->delete(); +``` + + +### draw + +```php +string draw(string $file [, array $variables]) +``` + +Returns a compiled view code that has previously used template system tags. It also allows you to define variables by replacing the `set()` method. + +#### Arguments ++ `file` — filename with a view inside the module or path to a file outside of it ++ `variables` — an array of variable definitions that can be used as tags *(optional)* + +#### Example +```php +// Compilation of the view inside the module +$this->draw('form.html', ['form' => $this->formFields]); + +// Compilation of the view outside the module +$this->draw('../path/to/view.html', ['foo' => 'bar']); +``` + + +### lang + +```php +string lang(string $key [, string $module]) +``` + +Zwraca zawartość klucza tablicy językowej z aktualnego modułu bądź wskazanego poprzez drugi argument. + +#### Arguments ++ `key` — the name of the language array key ++ `module` — the name of the module from which you want to select the key *(optional)* + +#### Example +```php +// Reference to local translation +$this->lang('foo'); // $this->core->lang['module-name']['foo']; + +// Reference to general translation +$this->lang('cancel', 'general'); // $this->core->lang['general']['cancel']; + +// Reference to the translation of "pages" module +$this->lang('slug', 'pages') // $this->core->lang['pages']['slug']; +``` + + +### notify + +```php +void notify(string $type, string $text [, mixed $args [, mixed $... ]]) +``` + +It allows you to call the notification to the user. + +#### Arguments ++ `type` — type of notification: *success* or *failure* ++ `text` — notyfication content ++ `args` — additional arguments *(optional)* + +#### Example +```php +$foo = 'Bar'; +$this->notify('success', 'This is %s!', $foo); // $this->core->setNotify('success', 'This is %s!', $foo); + +``` + + +### settings + +```php +mixed settings(string $module [, string $field [, string $value]]) +``` + +Gets or sets the value of the module settings. By default these are the main Batflat settings. + +#### Arguments ++ `module` — the module name, the name of the Batflat settings field, or the module name and the field set with a dot ++ `field` — module field name *(optional)* ++ `value` — the value to which module field will be changed *(optional)* + +#### Example +```php +// Select the "title" field from the general system settings +$this->settings('title'); // $this->core->getSettings('title'); + +// Select the "desc" field from the "blog" module +$this->settings('blog.desc'); // $this->core->getSettings('blog', 'desc'); + +// Select the "desc" field from the "blog" module +$this->settings('blog', 'desc'); // $this->core->getSettings('blog', 'desc'); + +// Set the content of the "desc" field from the "blog" module +$this->settings('blog', 'desc', 'Lorem ipsum...'); +``` + +### setTemplate + +```php +void setTemplate(string $file) +``` + +Allows you to change the template file on the front. This method works only in the `Site` class. + +#### Arguments ++ `file` — The name of the template file + +#### Example +```php +$this->setTemplate('index.html'); // $this->core->template = 'index.html'; +``` + + +Core +==== + +This is the kernel/engine of Batflat, the most important part that is responsible for all its basic tasks. The core contains many definitions of constants, functions, and methods that you can use when writing modules. + +Constants +--------- + +All definitions of constants are described in the first part of this documentation. To use them in a PHP file just call their names. Constants are particularly useful when building URLs and file paths. + +#### Example +```php +echo MODULES.'/contact/view/form.html'; + +``` + + +Functions +--------- + +Batflat has several built-in helper functions that facilitate the creation of modules. + +### domain + +```php +string domain([bool $with_protocol = true]) +``` + +Returns the domain name with http(s) or without. + +#### Arguments ++ `with_protocol` — it decides whether the address will be returned with or without protocol + +#### Return value +String with the domain name. + +#### Example +```php +echo domain(false); +// Result: example.com +``` + + +### checkEmptyFields + +```php +bool checkEmptyFields(array $keys, array $array) +``` + +Checks whether the array contains empty elements. It is useful while validating forms. + +#### Arguments ++ `keys` — list of array items that the function has to check ++ `array` — source array + +#### Return value +Returns `TRUE` when at least one item is empty. `FALSE` when all elements are completed. + +#### Example +```php +if(checkEmptyFields(['name', 'phone', 'email'], $_POST) { + echo 'Fill in all fields!'; +} +``` + + +### currentURL + +```php +string currentURL() +``` + +Returns the current URL. + +#### Example +```php +echo currentURL(); +// Result: http://example.com/contact +``` + + +### createSlug + +```php +string createSlug(string $text) +``` + +Translates text in non-lingual characters, dashes to spaces, and removes special characters. Used to create slashes in URLs and variable names in the template system. + +#### Arguments ++ `text` — text to convert + +#### Return value +Returns the text in slug form. + +#### Example +```php +echo createSlug('To be, or not to be, that is the question!'); +// Result: to-be-or-not-to-be-that-is-the-question +``` + + +### deleteDir + +```php +bool deleteDir(string $path) +``` + +Recursive function that removes the directory and all its contents. + +#### Arguments ++ `path` — directory path + +#### Return value +Returns `TRUE` for success or `FALSE` for failure. + +#### Example +```php +deleteDir('foo/bar'); +``` + + +### getRedirectData +```php +mixed getRedirectData() +``` + +Returns the data passed to the session when using `redirect()`. + +#### Return value +An array or `null`. + +#### Example +```php +$postData = getRedirectData(); +``` + + +### htmlspecialchars_array + +```php +string htmlspecialchars_array(array $array) +``` + +Replaces special characters from array elements into HTML entities. + +#### Arguments ++ `array` — the array that will be converted + +#### Return value +Returns the converted text. + +#### Example +```php +$_POST = htmlspecialchars_array($_POST); +``` + + +### isset_or + +```php +mixed isset_or(mixed $var [, mixed $alternate = null ]) +``` + +Replaces an empty variable with an alternate value. + +#### Arguments ++ `var` — variable ++ `alternate` — replacement value of the variable *(optional)* + +#### Return value +Returns an alternative value. + +#### Example +```php +$foo = isset_or($_GET['bar'], 'baz'); +``` + + +### parseURL +```php +mixed parseURL([ int $key = null ]) +``` + +Parses the current URL of the script. + +#### Arguments ++ `key` — URL parameter number *(optional)* + +#### Return value +An array or its individual element. + +#### Example +```php +// URL: http://example.com/foo/bar/4 + +var_dump(parseURL()) +// Result: +// array(3) { +// [0] => +// string(3) "foo" +// [1] => +// string(3) "bar" +// [2] => +// int(4) +// } + +echo parseURL(2); +// Result: "bar" +``` + + +### redirect + +```php +void redirect(string $url [, array $data = [] ]) +``` + +Redirect to the specified URL. It allows you to save data from the array to a session. It is useful to memorize unsaved data from forms. + +#### Arguments ++ `url` — address to redirect ++ `data` — an array that will be passed to the session *(optional)* + +#### Example +```php +redirect('http://www.example.com/'); + +// Save the array to session: +redirect('http://www.example.com/', $_POST); +``` + + +### url +```php +string url([ mixed $data = null ]) +``` + +Creates an absolute URL. The admin panel automatically adds a token. + +#### Arguments ++ `data` — string or array + +#### Return value +Absolute URL. + +#### Example +```php +echo url(); +// Result: http://example.com + +echo url('foo/bar') +// Result: http://example.com/foo/bar + +echo url('admin/foo/bar'); +// Result: http://example.com/admin/foo/bar?t=[token] + +echo url(['admin', 'foo', 'bar']); +// Result: http://example.com/admin/foo/bar?t=[token] +``` + + +Methods +------- + +In addition to functions, there are several important methods that speed up the process of creating new system functionality. + +### addCSS + +```php +void addCSS(string $path) +``` + +Imports the CSS file in the theme header. + +#### Arguments ++ `path` — URL to file + +#### Example +```php +$this->core->addCSS('http://example.com/style.css'); +// Result: +``` + + +### addJS + +```php +void addJS(string $path [, string $location = 'header']) +``` + +Imports the JS file in the header or footer of the theme. + +#### Arguments ++ `path` — URL to file ++ `location` — *header* or *footer* *(optional)* + +#### Example +```php +$this->core->addJS('http://example.com/script.js'); +// Result: +``` + + +### append + +```php +void append(string $string, string $location) +``` + +Adds a string to the header or footer. + +#### Arguments ++ `string` — character string ++ `location` — *header* or *footer* + +#### Example +```php +$this->core->append('', 'header'); +``` + + +### getModuleInfo + +```php +array getModuleInfo(string $dir) +``` + +Returns module information. This method works only in the `Admin` class. + +#### Arguments ++ `name` — module directory name + +#### Return value +Array with informations. + +#### Example +```php +$foo = $this->core->getModuleInfo('contact'); +``` + + +### getSettings + +```php +mixed getSettings([string $module = 'settings', string $field = null]) +``` + +Gets the value of the module settings. By default these are the main Batflat settings. + +#### Arguments ++ `module` — module name *(optional)* ++ `field` — field with definition of setting *(optional)* + +#### Return value +Array or string. + +#### Example +```php +echo $this->core->getSettings('blog', 'title'); +``` + + +### getUserInfo + +```php +string getUserInfo(string $field [, int $id ]) +``` + +Returns information about the logged in user or the user with the given ID. This method works only in the `Admin` class. + +#### Arguments ++ `field` — field name in the database ++ `id` — ID number *(opcjonalne)* + +#### Return value +The string of the selected field. + +#### Example +```php +// The currently logged in user +$foo = $this->core->getUserInfo('username'); + +// User with given ID +$foo = $this->core->getUserInfo('username', 1); +``` + + +### setNotify + +```php +void setNotify(string $type, string $text [, mixed $args [, mixed $... ]]) +``` + +Generates notification. + +#### Arguments ++ `type` — type of notification: *success* or *failure* ++ `text` — notyfication content ++ `args` — additional arguments *(optional)* + +#### Example +```php +$foo = 'Bar'; +$this->core->setNotify('success', 'This is %s!', $foo); +// Result: "This is Bar!" +``` + + +Database +-------- + +The database used in Batflat is SQLite version 3. For its use, CMS uses a simple class that makes it easy to build queries. You do not need to know SQL to be able to operate it. + +In addition, we recommend [*Adminer*](https://www.adminer.org/) app for database management. This is a one-file PHP script similar to *phpMyAdmin*, where you can administer Batflat tables. This will allow you to familiarize yourself with the structure of existing tables. +The database file is located in `inc/data/database.sdb`. + + +### SELECT + +Select multiple records: + +```php +// JSON +$rows = $this->$core->db('table')->toJson(); + +// Array +$rows = $this->$core->db('table')->select('foo')->select('bar')->toArray(); + +// Object +$rows = $this->$core->db('table')->select(['foo', 'b' => 'bar'])->toObject(); +``` + +Select a single record: +```php +// JSON +$row = $this->$core->db('table')->oneJson(); + +// Array +$row = $this->$core->db('table')->select('foo')->select('bar')->oneArray(); + +// Object +$row = $this->$core->db('table')->select(['foo', 'b' => 'bar'])->oneObject(); +``` + + +### WHERE + +Select a record with the specified number in the `id` column: + +```php +$row = $this->$core->db('table')->oneArray(1); +// or +$row = $this->$core->db('table')->oneArray('id', 1); +// or +$row = $this->$core->db('table')->where(1)->oneArray(); +// or +$row = $this->$core->db('table')->where('id', 1)->oneArray(); +``` + +Complex conditions: +```php +// Fetch rows whose column value 'foo' is GREATER than 4 +$rows = $this->$core->db('table')->where('foo', '>', 4)->toArray(); + +// Fetch rows whose column value 'foo' is GREATER than 4 and LOWER than 8 +$rows = $this->$core->db('table')->where('foo', '>', 4)->where('foo', '<', 8)->toArray(); +``` + +OR WHERE: +```php +// Fetch rows whose column value 'foo' is EQUAL 4 or 8 +$rows = $this->$core->db('table')->where('foo', '=', 4)->orWhere('foo', '=', 8)->toArray(); +``` + +WHERE LIKE: +```php +// Fetch rows whose column 'foo' CONTAINS the string 'bar' OR 'bases' +$rows = $this->$core->db('table')->like('foo', '%bar%')->orLike('foo', '%baz%')->toArray(); +``` + +WHERE NOT LIKE: +```php +// Fetch rows whose column 'foo' DOES NOT CONTAIN the string 'bar' OR 'baz' +$rows = $this->$core->db('table')->notLike('foo', '%bar%')->orNotLike('foo', '%baz%')->toArray(); +``` + +WHERE IN: +```php +// Fetch rows whose column value 'foo' CONTAINS in array [1,2,3] OR [7,8,9] +$rows = $this->$core->db('table')->in('foo', [1,2,3])->orIn('foo', [7,8,9])->toArray(); +``` + +WHERE NOT IN: +```php +// Fetch rows whose column value 'foo' DOES NOT CONTAIN in array [1,2,3] OR [7,8,9] +$rows = $this->$core->db('table')->notIn('foo', [1,2,3])->orNotIn('foo', [7,8,9])->toArray(); +``` + +Allowed comparison operators: `=`, `>`, `<`, `>=`, `<=`, `<>`, `!=`. + + +### JOIN + +INNER JOIN: +```php +$rows = $this->$core->db('table')->join('foo', 'foo.table_id = table.id')->toJson(); +``` + +LEFT JOIN: +```php +$rows = $this->$core->db('table')->leftJoin('foo', 'foo.table_id = table.id')->toJson(); +``` + + +### HAVING + +```php +$rows = $this->$core->db('table')->having('COUNT(*)', '>', 5)->toArray(); +``` + +OR HAVING: +```php +$rows = $this->$core->db('table')->orHaving('COUNT(*)', '>', 5)->toArray(); +``` + + +### INSERT + +The `save` method can add a new record to the table or update an existing one when it has a condition. When you add a new record, identification number will be returned. + +```php +// Add a new record +$id = $this->$core->db('table')->save(['name' => 'James Gordon', 'city' => 'Gotham']); +// Return value: ID number of new record + +// Update an existing record +$this->$core->db('table')->where('age', 50)->save(['name' => 'James Gordon', 'city' => 'Gotham']); +// Return value: TRUE on success or FALSE on failure +``` + + +### UPDATE + +Updating records in case of success will return `TRUE`. Otherwise it will be `FALSE`. + +```php +// Changing one column +$this->$core->db('table')->where('city', 'Gotham')->update('name', 'Joker'); + +// Changing multiple columns +$this->$core->db('table')->where('city', 'Gotham')->update(['name' => 'Joker', 'type' => 'Villain']); +``` + + +### SET + +```php +$this->$core->db('table')->where('age', 65)->set('age', 70)->set('name', 'Alfred Pennyworth')->update(); +``` + + +### DELETE + +Successful deletion of records returns their number. + +```php +// Delete record with `id` equal to 1 +$this->$core->db('table')->delete(1); + +// Deletion of record with condition +$this->$core->db('table')->where('age', 20)->delete(); +``` + + +### ORDER BY + +Ascending order: +```php +$this->$core->db('table')->asc('created_at')->toJson(); +``` + +Descending order: +```php +$this->$core->db('table')->desc('created_at')->toJson(); +``` + +Combine order: +```php +$this->$core->db('table')->desc('created_at')->asc('id')->toJson(); +``` + + +### GROUP BY + +```php +$this->$core->db('table')->group('city')->toArray(); +``` + + +### OFFSET, LIMIT + +```php +// Fetch 5 records starting at tenth +$this->$core->db('table')->offset(10)->limit(5)->toJson(); +``` + + +### PDO + +Not all queries can be created using the above methods *(e.g. creating or deleting a table)*, so you can also write queries using [PDO](http://php.net/manual/en/book.pdo.php): + +```php +$this->$core->db()->pdo()->exec("DROP TABLE `example`"); +``` + + +Template system +--------------- + +Operating the template system is easy and is based primarily on two methods. One allows assigning variables, while the other returns the compiled code. In exceptional situations, the other two methods are useful. + +### set + +```php +void set(string $name, mixed $value) +``` + +Assigns a value to a variable that can be used in views. + +#### Arguments ++ `name` — variable name ++ `value` — variable value + +#### Example +```php +$foo = ['bar', 'baz', 'qux']; +$this->tpl->set('foo', $foo); +``` + + +### draw + +```php +string draw(string $file) +``` + +Returns a compiled view code that has previously used template system tags. + +#### Arguments ++ `file` — file path + +#### Return value +A string, i.e. a compiled view. + +#### Example +```php +$this->tpl->draw(MODULES.'/galleries/view/admin/manage.html'); +``` + + +### noParse + +```php +string noParse(string $text) +``` + +Protects against compiling template system tags. + +#### Arguments ++ `text` — string to be left unchanged + +#### Example +```php +$this->tpl->noParse('Place this tag in website template: {$contact.form}'); +``` + + +### noParse_array + +```php +array noParse_array(array $array) +``` + +Protects against compiling template system tags inside the array. + +#### Arguments ++ `array` — array to be left unchanged + +#### Example +```php +$this->tpl->noParse_array(['{$no}', '{$changes}']); +``` + +Languages +--------- + +All language files are located in the `lang` directories inside the modules and under the `inc/lang` path. +In this last path there are folders corresponding to the language names in the following format: `en_english`. The first part is the abbreviation of the language and the second is the full name. +Within the directory is the `general.ini` file, which contains general language variables for the system. +After creating a new language folder, Batflat automatically detects the added language and allows it to be selected in the admin panel. Note that the procedure for creating a new language should be repeated for each module. \ No newline at end of file diff --git a/docs/pl.md b/docs/pl.md new file mode 100644 index 0000000..5c22cfe --- /dev/null +++ b/docs/pl.md @@ -0,0 +1,1314 @@ +Ogólne +====== + +Batflat to polski system zarządzania treścią, który jest prosty, lekki i szybki. Po raz pierwszy został wydany w maju 2016. Darmowa wersja aplikacji jest udostępniona w ramach [licencji](/license), która wymaga pozostawienia informacji o autorach oraz linku zwrotnego. Batflat sprawdza się świetnie podczas tworzenia małych serwisów, takich jak wizytówki firmowe, portfolia, blogi czy strony domowe. Dzięki tej dokumentacji dowiesz się jak go zainstalować, skonfigurować, a także jak tworzyć własne moduły i motywy. + +Dokumentacja została podzielona na kilka sekcji. Pierwsza dotyczy ogólnych instrukcji, druga jest skierowana do web designerów, a dwie ostatnie do web deweloperów. + + +Wymagania +--------- + +Wymagania systemowe dla Batflata są skromne, zatem powinien je spełnić każdy nowoczesny serwer WWW: + ++ Apache 2.2+ z trybem `mod_rewrite` ++ PHP w wersji 5.5+ ++ Dostęp do SQLite + +Konfiguracja PHP musi posiadać następujące rozszerzenia: + ++ dom ++ gd ++ mbstring ++ pdo ++ zip ++ cURL + + +Instalacja +----------- + +Na początek należy pobrać najnowszą wersję [Batflata](http://feed.sruu.pl/batflat/download/latest). + +Wypakuj wszystkie pliki ze skompresowanej paczki, a następnie przenieś je do katalogu lokalnego lub zdalnego serwera. W przypadku serwera zdalnego, należy połączyć się z nim poprzez klienta (S)FTP, np. darmowym programem [FileZilla](https://filezilla-project.org). Zazwyczaj pliki należy wgrać do folderu `www`, `htdocs` lub `public_html`. + +**Uwaga!** Upewnij się, że plik `.htaccess` również znalazł się na serwerze. Bez niego skrypt nie będzie działał. + +Niektóre serwery mogą wymagać nadania dodatkowych uprawnień `chmod 777` dla następujących katalogów i plików: + ++ tmp/ ++ uploads/ ++ admin/tmp/ ++ inc/data/ ++ inc/data/database.sdb + +Otwórz przeglądarkę i przejdź do adresu, w którym zlokalizowane są pliki Batflata. Powinien ukazać się domyślny szablon wraz z przykładową treścią. + +Aby przejść do panelu administracyjnego, dodaj `/admin/` na koniec adresu. **Początkowy login i hasło to *"admin"*.** Wypada je zmienić zaraz po zalogowaniu ze względów bezpieczeństwa. Zalecamy również zmianę nazwy katalogu z panelem administracyjnym *(trzeba wtedy zmienić wartość stałej w pliku defines)*. + + +Konfiguracja +------------ + +CMS można skonfigurować poprzez edycję ustawień w panelu administracyjnym oraz poprzez plik z definicjami. Nie zalecamy jednak zmieniać konfiguracji w pliku, jeżeli jesteś osobą niedoświadczoną. + +### Panel administracyjny +Aby zmienić podstawową konfigurację w panelu administracyjnym, wybierz zakładkę `Ustawienia`. Możesz wprowadzić tam nazwę strony, jej opis czy słowa kluczowe, które będą zawarte w meta-tagach, a także w innych miejscach szablonu domyślnego, np. w nagłówku. Zmienisz tutaj również stronę startową, domyślny język *(zarówno dla strony jak i panelu)*, zdefiniujesz treść stopki oraz wybierzesz rodzaj edytora *(HTML lub WYSIWYG)*, który będzie dostępny podczas edycji podstron oraz wpisów na blogu. + +Konfigurację pozostałych modułów zmienisz w zakładkach odpowiadających ich nazwie. + +### Plik defines +Bardziej zaawansowane rzeczy możesz zmienić w pliku `inc/core/defines.php`, który zawiera definicje stałych wartości. + ++ `ADMIN` — nazwa katalogu zawierająca panel administracyjny ++ `THEMES` — ścieżka do katalogu zawierającego motywy ++ `MODULES` — ścieżka do katalogu zawierającego moduły ++ `UPLOADS` — ścieżka do katalogu zawierającego wgrane pliki ++ `FILE_LOCK` — blokada możliwości edycji plików poprzez panel administracyjny ++ `BASIC_MODULES` — lista podstawowych modułów, których nie można usunąć ++ `HTML_BEAUTY` — ładne formatowanie kodu HTML po jego przeparsowaniu ++ `DEV_MODE` — tryb dewelopera, podczas którego pokazywane są błędy i notatki PHP + + +Aktualizacja +------------ + +Jeżeli chcesz być na bieżąco wraz ze wszelkimi nowościami oraz poprawkami błędów i zabezpieczeń, powinieneś regularnie sprawdzać aktualizacje Batflata. Możesz to zrobić w zakładce `Ustawienia -> Aktualizacje`. System sprawdzi czy dostępna jest nowa wersja skryptu oraz automatycznie pobierze z naszego serwera nową paczkę i zaktualizuje pliki rdzenia oraz modułów. + +W przypadku komplikacji *(np. niepowodzenia pobrania nowej paczki)* możesz skorzystać z trybu manualnego. W tym celu należy ręcznie pobrać najnowszą wersję Batflata, wgrać ją do głównego katalogu aplikacji, a następnie na końcu adresu URL zakładki z aktualizacją dodać parametr `&manual`. CMS powinien wykryć wgraną paczkę ZIP i po kliknięciu w przycisk aktualizacji, przeprowadzić proces wypakowania i nadpisania plików. + +Przed każdą aktualizacją, Batflat wykonuje kopię zapasową. Znajdziesz ją w katalogu skryptu, w folderze `backup/`. W razie niepowodzenia przeprowadzonej aktualizacji, możesz w każdej chwili ją przywrócić. + + +Motywy +====== + +Struktura +--------- + +Struktura motywów w Batflacie jest bardzo prosta. Wystarczy utworzyć nowy folder z nazwą motywu w katalogu `themes/` oraz plik `index.html`, który będzie domyślnym szablonem dla podstron. Każda podstrona może korzystać z innego szablonu, zatem prócz wspomnianego pliku możesz utworzyć także inne, np. `xyz.html`. Wybór szablonu jest dostępny w panelu administracyjnym podczas tworzenia strony. Nie ma określonych reguł co do plików CSS oraz JS. Panuje pełna dowolność. + +W katalogu motywu możesz również stworzyć własne widoki modułów. Aby to zrobić, musisz utworzyć katalog `modules/nazwa_modułu/` oraz pliki `*.html` z nazwami odpowiadającymi nazwom oryginalnych widoków. Przykładowo, widok modułu formularza kontaktowego powinien być zawarty w następującej ścieżce: `themes/nazwa_motywu/modules/contact/form.html`. Batflat automatycznie wykryje nowy widok i użyje go zamiast domyślnego widoku modułu. + + +Tagi szablonów +-------------- + +CMS korzysta z prostego systemu szablonów, który zawiera następujące tagi: + +### Zmienne +```php +{$foo} // zwykła zmienna +{$foo|e} // HTML escape dla zmiennej +{$foo|cut:10} // zawartość zmiennej ucięta do 10 znaków +{$foo.bar} // tablica +``` +Dostęp do elementów tablicy odbywa się poprzez znak kropki. + +### Warunki +```php +{if: $foo > 5} + lorem +{elseif: $foo == 5} + ipsum +{else} + dolor +{/if} +``` + +### Pętle +```html + +``` +Tag pętli posiada 3 stopnie rozbudowania. W pierwszym wystarczy zmienna tablicowa, którą system szablonów rozbije na trzy zmienne o nazwach `$key`, `$value` oraz `$counter`, +która zlicza kolejne iteracje począwszy od zera. Drugi stopień pozwala określić nazwę zmiennej przechowującą wartość, zaś trzeci również nazwę zmiennej indeksu. + +### Dołączanie plików szablonu +```html + + + {template: header.html} +
    +

    Lorem ipsum dolor sit amet.

    +
    + {template: footer.html} + + +``` + +### Kod PHP +```php +Dzisiejsza data: {?= date('Y-m-d') ?} +``` +Jeżeli opuścisz znak `=`, kod jedynie się wykona i nic nie wyświetli. Dzięki temu można, np. zdefiniować nowe zmienne wewnątrz szablonu: +```php +{? $foo = 5 ?} +``` + +### Wyłączenie parsowania +``` +{noparse}Użyj tagu {$contact.form}, aby wyświetlić formularz kontaktowy.{/noparse} +``` +Wszelkie tagi wewnątrz wyrażenia *noparse* pozostaną w niezmienionym stanie. + +### Komentarze +``` +{* to jest komentarz *} +``` +Komentarze nie są widoczne w pliku źródłowym po skompilowaniu szablonu. + +### Języki +``` +{lang: pl_polski} + Witaj świecie! +{/lang} +{lang: en_english} + Hello world! +{/lang} +``` +Jeżeli chcesz dostosować elementy szablonu do konkretnego języka, użyj powyższych tagów. + + + +Zmienne systemowe +----------------- +Batflat, podobnie jak i jego moduły, dostarcza wiele zmiennych *(zazwyczaj tablicowych)*, które służą do wyświetlania poszczególnych elementów strony. Oto najważniejsze z nich: + ++ `{$settings.pole}` — element tablicy zawierający wartość danego pola ustawień Batflata ++ `{$settings.moduł.pole}` — element tablicy zawierający wartość danego pola ustawień modułu ++ `{$bat.path}` — przechowuje ścieżkę, w której znajduje się system ++ `{$bat.lang}` — wyświetla aktualnie wykorzystywany język ++ `{$bat.notify}` — ostatnie powiadomienie ++ `{$bat.notify.text}` - tekst powiadomienia ++ `{$bat.notify.type}` - typ komunikatu odpowiadający klasom bootstrapa (danger, success) ++ `{$bat.header}` — dodatkowe meta-tagi, skrypty JS i arkusze stylów CSS ładowane przez moduły ++ `{$bat.footer}` — dodatkowe skrypty JS ładowane przez moduły ++ `{$bat.theme}` — wyświetla ścieżkę do aktywnego szablonu strony wraz z hostem ++ `{$bat.powered}` — wyświetla napis *Powered by Batflat* z linkiem do oficjalnej strony ++ `{$navigation.xyz}` — wyświetla listę `
  • ` elementów danej nawigacji ++ `{$page.title}` — wyświetla nazwę podstrony ++ `{$page.content}` — wyświetla zawartość podstrony + +Przykład +-------- + +```html + + + + + + {$page.title} - {$settings.title} + + + + {loop: $bat.header}{$value}{/loop} + + + + + +
    +

    {$page.title}

    + {$page.content} +
    + +
    + {$settings.footer} {$bat.powered} +
    + + + {loop: $bat.footer}{$value}{/loop} + + +``` + +Moduły +====== + +Struktura +--------- + +Każdy moduł, podobnie jak motywy, musi znajdować się w osobnym folderze utworzonym w ścieżce `inc/modules/`. Należy zwrócić uwagę na to, by katalog nie zawierał wielkich liter oraz znaków specjalnych, np. spacji. + +Podczas tworzenia modułu należy zastanowić się nad tym, jakiego typu ma być to moduł. Czy ma być konfiguralny w panelu administracyjnym, czy może ma działać wyłącznie po stronie gości odwiedzających stronę? Ze względu na taki podział, w Batflacie wyróżniamy trzy główne pliki modułu: + ++ `Info.php` — zawiera informacje o module, takie jak nazwa, opis, autor czy ikona ++ `Admin.php` — zawartość tego pliku będzie dostępna poprzez panel administracyjny ++ `Site.php` — zawartość tego pliku będzie dostępna dla gości odwiedzających stronę + +Czwartym, lecz opcjonalnym plikiem jest `ReadMe.md`, który powinien zawierać dodatkowe informacje dla przyszłego użytkownika zapisane w jęzku [Markdown](https://en.wikipedia.org/wiki/Markdown), np. sposób używania modułu. + +Jeżeli planujesz napisać moduł, który będzie używał HTML, to dobrze byłoby zadbać o to, by kod PHP był oddzielony od hipertekstowego języka znaczników. W tym celu, wewnątrz folderu z modułem, musisz utworzyć katalog `views`. W nim składuj wszelkie pliki widokowe. + +Podobnie wygląda sprawa z wielojęzycznością modułu. Wystarczy stworzyć pliki językowe z rozszerzeniem `ini` wewnątrz katalogu `lang`. + +Struktura modułu powinna wyglądać mniej więcej w taki sposób: +``` +example/ +|-- lang/ +| |-- admin/ +| | |-- en_english.ini +| | |-- pl_polski.ini +| |-- en_english.ini +| |-- pl_polski.ini +|-- views/ +| |-- admin/ +| | |-- bar.html +| |-- foo.html +|-- Admin.php +|-- Info.php +|-- Site.php ++-- ReadMe.md +``` + +Tworzenie modułu +---------------- + +### Plik Info + +Najważniejszy plik każdego modułu. To w nim zawarte są podstawowe informacje oraz polecenia wykonywane podczas instalacji oraz deinstalacji. + +```php + 'Example', // Nazwa + 'description' => 'Lorem ipsum....', // Opis + 'author' => 'Robin', // Autor + 'version' => '1.0', // Wersja + 'compatibility' => '1.3.*', // Kompatybilność z wersją Batflata + 'icon' => 'bolt', // Ikona + + 'pages' => ['Example' => 'example'], // Rejestracja jako strona (opcjonalne) + + 'install' => function() use($core) // Polecenia instalacji + { + // lorem ipsum... + }, + 'uninstall' => function() use($core) // Polecenia deinstalacji + { + // lorem ipsum... + } + ]; +``` + +Lista ikon, które możesz użyć w tym pliku, znajduje się na stronie [fontawesome.io](http://fontawesome.io/icons/). Pamiętaj, by nie wprowadzać nazwy ikony z przedrostkiem `fa-`. + +Rejestracja modułu jako strony pozwala na swobodniejsze stosowanie routingu oraz wybranie go jako stronę startową. + + +### Plik Admin + +Zawartość tego pliku będzie uruchomiona w panelu administracyjnym. + +```php + 'foo', + 'Bar' => 'bar', + ]; + } + + public function getFoo($parm) + { + return "Foo $parm!"; + } + + public function postBar() + { + return "Bar!"; + } + } +``` + +W metodzie `navigation` należy zawrzeć tablicę z podstronami modułu. Do każdej z podstron powinna być przypisana jakaś metoda *(bez prefiksu)*. Elementy tej tablicy zostaną wyświetlone w menu panelu administracyjnego. + +Metody mogą przyjmować również argumenty, które są przekazywane poprzez adres URL. Przykładowo, po wprowadzeniu adresu `/example/foo/abc`, metoda `getFoo` zwróci tekst *"Foo abc!"*. + +Jak można zauważyć w powyższym listingu, każda metoda reprezentująca podstronę modułu powinna być opatrzona prefiksem określającym typ żądania. W większości przypadków będziemy stosować nazewnictwo `getFoo`, zaś dla przesyłanych formularzy `postFoo`. Jeżeli metoda ma obsługiwać wszystkie typy, to powinna być poprzedzona prefiksem `any` *(przykładowo: `anyFoo`)*s. Jest to ważne, ponieważ bez prefixu strony nie będą obsłużone. Obsłużone metody są tłumaczone przez dynamiczny routing w następujący sposób: + ++ `getFoo()` — jako `/example/foo` dla żądania typu GET ++ `getFoo($parm)` — jako `/example/foo/abc` dla żądania typu GET ++ `postBar()` — jako `example/bar` dla żądania typu POST *(przesyłanie formularzy)* ++ `anyFoo()` — jako `/example/foo` dla każdego rodzaju żądania + +### Plik Site + +Plik ten odpowiada za część widzianą przez gości odwiedzających stronę. Jeżeli moduł jest dość spory, dobrą praktyką jest zarejestrowanie go jako strony i zastosowanie routingu. + +```php +_foo(); + } + + public function routes() + { + $this->route('example', '_mySite'); + } + + private function _mySite() + { + $page = [ + 'title' => 'Sample title..', + 'desc' => 'Site description', + 'content' => 'Lorem ipsum dolor...' + ]; + + $this->setTemplate('index.html'); + $this->tpl->set('page', $page); + } + + private function _foo() + { + $this->tpl->set('bar', 'Why So Serious?'); + } + } +``` + +W powyższym przykładzie została utworzona nowa zmienna szablonowa `bar`, która poprzez wywołanie metody `_foo()` w inicjalizatorze modułu, będzie mogła być użyta w plikach motywu jako `{$bar}`. Dodatkowo w metodzie `routes()` został utworzony routing do podstrony `/example`, wskazujący wywołanie metody `_mySite()`. Jeżeli przejdziemy pod adres `http://example.com/example` zostanie wywołana metoda `_mySite()` modułu. + +### Pliki językowe + +Moduł może zawierać zmienne językowe, z których można korzystać zarówno w klasach, jak i widokach. Pliki językowe posiadają rozszerzenie `.ini`, a ich miejsce znajduje się w katalogu `lang` danego modułu. +Przykładowo, jeżeli chcesz dodać plik językowy zawierający angielskie wyrażenia dla części administracyjnej modułu `Example`, pownieneś utworzyć nowy plik w ścieżce `inc/modules/example/lang/admin/en_english.ini`. +Zawartość powinna przypominać poniższy listing: + +``` +full_name = "Firstname and surname" +email = "E-mail" +subject = "Subject" +message = "Message" +send = "Send" +send_success = "Mail successfully sent. I will contact you soon." +send_failure = "Unable to send a message. Probably mail() function is disabled on the server." +wrong_email = "Submited e-mail address is incorrect." +empty_inputs = "Fill all required fields to send a message." +antiflood = "You have to wait a while before you will send another message." +``` + +Aby skorzystać z utworzonych zmiennych w klasie modułu należy użyć konstrukcji `$this->lang('subject')`, zaś w widoku `{$lang.example.subject}`. W przypadku klasy możemy opuścić drugi parametr metody `lang` jakim jest nazwa modułu, z którego będzie pobierane tłumaczenie. + + +Routing +------- + +Routing to proces przetwarzania otrzymanego adresu żądania i na jego podstawie decydowanie, co powinno zostać uruchomione lub wyświetlone. Ma on za zadanie wywołać odpowiednią metodę/funkcję na podstawie adresu URL strony. Z routingu należy korzystać wewnątrz publicznej metody `routes()`. + +```php +void route(string $pattern, mixed $callback) +``` + +Pierwszym parametrem metody `route` jest wyrażenie regularne. Niektóre z wyrażeń zostały już zdefiniowane: + ++ `:any` — dowolny ciąg znaków ++ `:int` — liczby całkowite ++ `:str` — ciąg znaków będący slugiem + +Drugim parametrem jest nazwa metody lub anonimowa funkcja, która przekazuje dowolną liczbę argumentów zdefiniowanych w wyrażeniu regularnym. + +#### Przykład +```php +public function routes() +{ + // URL: http://example.com/blog + + // - poprzez wywołanie metody wewnątrz modułu: + $this->route('blog', 'importAllPosts'); + + // - poprzez wywołanie anonimowej funkcji: + $this->route('blog', function() { + $this->importAllPosts(); + }); + + // URL: http://example.com/blog/2 + $this->route('blog/(:int)', function($page) { + $this->importAllPosts($page); + }); + + // URL: http://example.com/blog/post/lorem-ipsum + $this->route('blog/post/(:str)', function($slug) { + $this->importPost($slug); + }); + + // URL: http://example.com/blog/post/lorem-ipsum/4 + $this->route('blog/post/(:str)/(:int)', function($slug, $page) { + $this->importPost($slug, $page); + }); +} +``` + + +Metody +------ + +Moduły posiadają specjalne fasady, które ułatwiają dostęp do metod wewnątrz rdzenia. Dzięki temu można skrócić wywołania typu `$this->core->foo->bar`. + +### db + +```php +void db([string $table]) +``` + +Umożliwia operowanie na bazie danych. Szczegóły zostały opisane w sekcji rdzenia. + +#### Argumenty ++ `table` — nazwa tabeli bazy danych *(opcjonalne)* + +#### Przykład +```php +$this->db('table')->where('age', 20)->delete(); +``` + + +### draw + +```php +string draw(string $file [, array $variables]) +``` + +Zwraca skompilowany kod widoku, w którym wcześniej zostały użyte tagi systemu szablonów. Pozwala również na zdefiniowanie zmiennych zastępując metodę `set()`. + +#### Argumenty ++ `file` — nazwa pliku z widokiem wewnątrz modułu lub ścieżka do pliku znajdującego się poza nim ++ `variables` — tablica z definicją zmiennych, które będzie można wykorzystać jako tagi *(opcjonalne)* + +#### Przykład +```php +// Kompilacja widoku znajdującego się wewnątrz modułu +$this->draw('form.html', ['form' => $this->formFields]); + +// Kompilacja widoku znajdującego się poza modułem +$this->draw('../path/to/view.html', ['foo' => 'bar']); +``` + + +### lang + +```php +string lang(string $key [, string $module]) +``` + +Zwraca zawartość klucza tablicy językowej z aktualnego modułu bądź wskazanego poprzez drugi argument. + +#### Argumenty ++ `key` — nazwa klucza tablicy językowej ++ `module` — nazwa modułu, z którego ma zostać pobrany klucz *(opcjonalne)* + +#### Przykład +```php +// Odwołanie się do tłumaczenia lokalnego +$this->lang('foo'); // $this->core->lang['module-name']['foo']; + +// Odwołanie się do ogólnego tłumaczenia +$this->lang('cancel', 'general'); // $this->core->lang['general']['cancel']; + +// Odwołanie się do tłumaczenia modułu "pages" +$this->lang('slug', 'pages') // $this->core->lang['pages']['slug']; +``` + + +### notify + +```php +void notify(string $type, string $text [, mixed $args [, mixed $... ]]) +``` + +Umożliwia wywołanie notyfikacji dla użytkownika. + +#### Argumenty ++ `type` — rodzaj powiadomienia: *success* lub *failure* ++ `text` — treść powiadomienia ++ `args` — dodatkowe argumenty *(opcjonalne)* + +#### Przykład +```php +$foo = 'Bar'; +$this->notify('success', 'This is %s!', $foo); // $this->core->setNotify('success', 'This is %s!', $foo); + +``` + + +### settings + +```php +mixed settings(string $module [, string $field [, string $value]]) +``` + +Pobiera lub ustawia wartość ustawień danego modułu. Domyślnie są to główne ustawienia Batflata. + +#### Argumenty ++ `module` — nazwa modułu, nazwa pola ustawień Batflata lub nazwa modułu i pole ustawień połączone kropką ++ `field` — nazwa pola modułu *(opcjonalne)* ++ `value` — wartość na jaką zostanie zmienione pole modułu *(opcjonalne)* + +#### Przykład +```php +// Pobranie pola "title" z ogólnych ustawień systemu +$this->settings('title'); // $this->core->getSettings('title'); + +// Pobranie pola "desc" z modułu "blog" +$this->settings('blog.desc'); // $this->core->getSettings('blog', 'desc'); + +// Pobranie pola "desc" z modułu "blog" +$this->settings('blog', 'desc'); // $this->core->getSettings('blog', 'desc'); + +// Ustawienie zawartości pola "desc" z modułu "blog" +$this->settings('blog', 'desc', 'Lorem ipsum...'); +``` + +### setTemplate + +```php +void setTemplate(string $file) +``` + +Umożliwia podmianę pliku z szablonem na froncie. Metoda działa wyłącznie w klasie `Site`. + +#### Argumenty ++ `file` — nazwa pliku z szablonem + +#### Przykład +```php +$this->setTemplate('index.html'); // $this->core->template = 'index.html'; +``` + + +Rdzeń +===== + +Jest to swoiste jądro / silnik Batflata, czyli najważniejsza część, która jest odpowiedzialna za wszystkie jego podstawowe zadania. Rdzeń zawiera wiele definicji stałych, funkcji i metod, które możesz wykorzystać podczas pisania modułów. + +Stałe +----- +Wszelkie definicje stałych zostały opisane w pierwszej części tej dokumentacji. Aby z nich skorzystać, wystarczy w pliku PHP wywołać ich nazwy. Stałe szczególnie przydają się przy budowie adresów URL i ścieżek do plików. + +#### Przykład +```php +echo MODULES.'/contact/view/form.html'; + +``` + + +Funkcje +------- + +Batflat posiada kilka wbudowanych funkcji pomocniczych, które ułatwiają tworzenie modułów. + +### domain + +```php +string domain([bool $with_protocol = true]) +``` + +Zwraca nazwę domeny z protokołem http(s) lub bez. + +#### Argumenty ++ `with_protocol` — decyduje czy adres zostanie zwrócony z protokołem czy bez + +#### Wartość zwracana +Tekst z nazwą domeny. + +#### Przykład +```php +echo domain(false); +// Wynik: example.com +``` + + +### checkEmptyFields + +```php +bool checkEmptyFields(array $keys, array $array) +``` + +Sprawdza czy tablica zawiera puste elementy. Przydaje się podczas walidacji formularzy. + +#### Argumenty ++ `keys` — lista elementów tablicy, które funkcja ma sprawdzić ++ `array` — tablica źródłowa + +#### Wartość zwracana +Zwraca `TRUE`, gdy przynajmniej jeden element jest pusty. `FALSE`, gdy wszystkie elementy są uzupełnione. + +#### Przykład +```php +if(checkEmptyFields(['name', 'phone', 'email'], $_POST) { + echo 'Wypełnij wszystkie pola!'; +} +``` + + +### currentURL + +```php +string currentURL() +``` + +Zwraca aktualny adres URL. + +#### Przykład +```php +echo currentURL(); +// Wynik: http://example.com/contact +``` + + +### createSlug + +```php +string createSlug(string $text) +``` + +Zamienia w tekście znaki językowe na bez ogonków, spacje na myślniki oraz usuwa znaki specjalne. Służy do tworzenia slugów w adresach URL i nazw zmiennych w systemie szablonów. + +#### Argumenty ++ `text` — tekst do konwersji + +#### Wartość zwracana +Zwraca tekst w postaci slugu. + +#### Przykład +```php +echo createSlug('Być albo nie być; oto jest pytanie!'); +// Wynik: byc-albo-nie-byc-oto-jest-pytanie +``` + + +### deleteDir + +```php +bool deleteDir(string $path) +``` + +Rekurencyjna funkcja, która usuwa katalog wraz z całą zawartością. + +#### Argumenty ++ `path` — ścieżka do katalogu + +#### Wartość zwracana +Zwraca `TRUE` w przypadku sukcesu lub `FALSE` przy niepowodzeniu. + +#### Przykład +```php +deleteDir('foo/bar'); +``` + + +### getRedirectData +```php +mixed getRedirectData() +``` + +Zwraca dane przekazane do sesji podczas użycia funkcji `redirect()`. + +#### Wartość zwracana +Tablica lub `null`. + +#### Przykład +```php +$postData = getRedirectData(); +``` + + +### htmlspecialchars_array + +```php +string htmlspecialchars_array(array $array) +``` + +Zamienia znaki specjalne z elementów tablicy na encje HTML. + +#### Argumenty ++ `array` — tablica, która zostanie przekonwertowana + +#### Wartość zwracana +Zwraca skonwertowany tekst. + +#### Przykład +```php +$_POST = htmlspecialchars_array($_POST); +``` + + +### isset_or + +```php +mixed isset_or(mixed $var [, mixed $alternate = null ]) +``` + +Zamienia pustą zmienną na wartość alternatywną. + +#### Argumenty ++ `var` — zmienna ++ `alternate` — wartość zastępcza zmiennej *(opcjonalne)* + +#### Wartość zwracana +Zwraca wartość alternatywną. + +#### Przykład +```php +$foo = isset_or($_GET['bar'], 'baz'); +``` + + +### parseURL +```php +mixed parseURL([ int $key = null ]) +``` + +Parsuje aktualny adresu URL skryptu. + +#### Argumenty ++ `key` — numer parametru adresu URL *(opcjonalne)* + +#### Wartość zwracana +Tablica lub jej pojedynczy element. + +#### Przykład +```php +// URL: http://example.com/foo/bar/4 + +var_dump(parseURL()) +// Wynik: +// array(3) { +// [0] => +// string(3) "foo" +// [1] => +// string(3) "bar" +// [2] => +// int(4) +// } + +echo parseURL(2); +// Wynik: "bar" +``` + + +### redirect + +```php +void redirect(string $url [, array $data = [] ]) +``` + +Przekierowanie do wskazanego adresu URL. Pozwala ona na zapisanie danych z tablicy do sesji. Przydaje się do zapamiętywania niezapisanych danych z formularzy. + +#### Argumenty ++ `url` — adres, na który nastąpi przekierowanie ++ `data` — tablica, która będzie przekazana do sesji *(opcjonalne)* + +#### Przykład +```php +redirect('http://www.example.com/'); + +// Zapisanie tablicy do sesji: +redirect('http://www.example.com/', $_POST); +``` + + +### url +```php +string url([ mixed $data = null ]) +``` + +Tworzy bezwzględny adres URL. W panelu administracyjnym automatycznie dodaje token. + +#### Argumenty ++ `data` — tekst lub tablica + +#### Wartość zwracana +Bezwzględny adres URL. + +#### Przykład +```php +echo url(); +// Wynik: http://example.com + +echo url('foo/bar') +// Wynik: http://example.com/foo/bar + +echo url('admin/foo/bar'); +// Wynik: http://example.com/admin/foo/bar?t=[token] + +echo url(['admin', 'foo', 'bar']); +// Wynik: http://example.com/admin/foo/bar?t=[token] +``` + + +Metody +------ + +Prócz funkcji, istnieje kilka istotnych metod, które przyspieszają proces tworzenia nowych funkcjonalności systemu. + +### addCSS + +```php +void addCSS(string $path) +``` + +Importuje plik CSS w nagłówku motywu. + +#### Argumenty ++ `path` — adres URL do pliku + +#### Przykład +```php +$this->core->addCSS('http://example.com/style.css'); +// Wynik: +``` + + +### addJS + +```php +void addJS(string $path [, string $location = 'header']) +``` + +Importuje plik JS w nagłówku lub stopce motywu. + +#### Argumenty ++ `path` — adres URL do pliku ++ `location` — lokalizacja: *header* lub *footer* *(opcjonalne)* + +#### Przykład +```php +$this->core->addJS('http://example.com/script.js'); +// Wynik: +``` + + +### append + +```php +void append(string $string, string $location) +``` + +Dodaje do nagłówka lub stopki ciąg znaków. + +#### Argumenty ++ `string` — ciąg znaków ++ `location` — lokalizacja: *header* lub *footer* + +#### Przykład +```php +$this->core->append('', 'header'); +``` + + +### getModuleInfo + +```php +array getModuleInfo(string $dir) +``` + +Zwraca informacje o module. Metoda działa wyłącznie w klasie `Admin`. + +#### Argumenty ++ `name` — nazwa katalogu modułu + +#### Wartość zwracana +Tablica z informacjami. + +#### Przykład +```php +$foo = $this->core->getModuleInfo('contact'); +``` + + +### getSettings + +```php +mixed getSettings([string $module = 'settings', string $field = null]) +``` + +Pobiera wartość ustawień danego modułu. Domyślnie są to główne ustawienia Batflata. + +#### Argumenty ++ `module` — nazwa modułu *(opcjonalne)* ++ `field` — pole z definicją ustawienia *(opcjonalne)* + +#### Wartość zwracana +Tablica lub tekst. + +#### Przykład +```php +echo $this->core->getSettings('blog', 'title'); +``` + + +### getUserInfo + +```php +string getUserInfo(string $field [, int $id ]) +``` + +Zwraca informacje o zalogowanym użytkowniku lub o danym ID. Metoda działa wyłącznie w klasie `Admin`. + +#### Argumenty ++ `field` — nazwa pola w bazie danych ++ `id` — numer identyfikacyjny *(opcjonalne)* + +#### Wartość zwracana +Ciąg znaków z wybranego pola. + +#### Przykład +```php +// Aktualnie zalogowany użytkownik +$foo = $this->core->getUserInfo('username'); + +// Użytkownik o danym ID +$foo = $this->core->getUserInfo('username', 1); +``` + + +### setNotify + +```php +void setNotify(string $type, string $text [, mixed $args [, mixed $... ]]) +``` + +Generuje notyfikację. + +#### Argumenty ++ `type` — rodzaj powiadomienia: *success* lub *failure* ++ `text` — treść powiadomienia ++ `args` — dodatkowe argumenty *(opcjonalne)* + +#### Przykład +```php +$foo = 'Bar'; +$this->core->setNotify('success', 'Pomyślnie zainstalowano moduł %s!', $foo); +// Wynik: "Pomyślnie zainstalowano moduł Bar!" +``` + + +Baza danych +----------- + +Zastosowana w Batflacie baza danych to SQLite w wersji 3. Do jej obsługi, CMS wykorzystuje prostą klasę, która ułatwia budowanie zapytań. Nie musisz znać języka SQL, by móc na niej operować. + +Dodatkowo polecamy aplikację [*Adminer*](https://www.adminer.org/) do zarządzania nią. Jest to jednoplikowy skrypt PHP, podobny do *phpMyAdmin*, przy pomocy którego można administrować tabelami Batflata. Pozwoli on zapoznać się ze strukturą istniejących tabel. +Plik bazy znajduje się w `inc/data/database.sdb`. + + +### SELECT + +Pobieranie wielu rekordów: + +```php +// JSON +$rows = $this->$core->db('table')->toJson(); + +// Tablica +$rows = $this->$core->db('table')->select('foo')->select('bar')->toArray(); + +// Obiekt +$rows = $this->$core->db('table')->select(['foo', 'b' => 'bar'])->toObject(); +``` + +Pobieranie pojedycznego rekordu: +```php +// JSON +$row = $this->$core->db('table')->oneJson(); + +// Tablica +$row = $this->$core->db('table')->select('foo')->select('bar')->oneArray(); + +// Obiekt +$row = $this->$core->db('table')->select(['foo', 'b' => 'bar'])->oneObject(); +``` + + +### WHERE + +Wybór wiersza o określonym numerze w kolumnie `id`: + +```php +$row = $this->$core->db('table')->oneArray(1); +// lub +$row = $this->$core->db('table')->oneArray('id', 1); +// lub +$row = $this->$core->db('table')->where(1)->oneArray(); +// lub +$row = $this->$core->db('table')->where('id', 1)->oneArray(); +``` + +Złożone warunki: +```php +// Pobranie wierszy, których wartość kolumny 'foo' jest WIĘKSZA od 4 +$rows = $this->$core->db('table')->where('foo', '>', 4)->toArray(); + +// Pobranie wierszy, których wartość kolumny 'foo' jest WIĘKSZA od 4 i MNIEJSZA od 8 +$rows = $this->$core->db('table')->where('foo', '>', 4)->where('foo', '<', 8)->toArray(); +``` + +OR WHERE: +```php +// Pobranie wierszy, których wartość kolumny 'foo' jest RÓWNA 4 LUB 8 +$rows = $this->$core->db('table')->where('foo', '=', 4)->orWhere('foo', '=', 8)->toArray(); +``` + +WHERE LIKE: +```php +// Pobranie wierszy, których kolumna 'foo' ZAWIERA ciąg znaków 'bar' LUB 'baz' +$rows = $this->$core->db('table')->like('foo', '%bar%')->orLike('foo', '%baz%')->toArray(); +``` + +WHERE NOT LIKE: +```php +// Pobranie wierszy, których kolumna 'foo' NIE ZAWIERA ciągu znaków 'bar' LUB 'baz' +$rows = $this->$core->db('table')->notLike('foo', '%bar%')->orNotLike('foo', '%baz%')->toArray(); +``` + +WHERE IN: +```php +// Pobranie wierszy, których wartość kolumny 'foo' ZAWIERA SIĘ w tablicy [1,2,3] LUB [7,8,9] +$rows = $this->$core->db('table')->in('foo', [1,2,3])->orIn('foo', [7,8,9])->toArray(); +``` + +WHERE NOT IN: +```php +// Pobranie wierszy, których wartość kolumny 'foo' NIE ZAWIERA SIĘ w tablicy [1,2,3] LUB [7,8,9] +$rows = $this->$core->db('table')->notIn('foo', [1,2,3])->orNotIn('foo', [7,8,9])->toArray(); +``` + +Dozwolone operatory porównania: `=`, `>`, `<`, `>=`, `<=`, `<>`, `!=`. + + +### JOIN + +INNER JOIN: +```php +$rows = $this->$core->db('table')->join('foo', 'foo.table_id = table.id')->toJson(); +``` + +LEFT JOIN: +```php +$rows = $this->$core->db('table')->leftJoin('foo', 'foo.table_id = table.id')->toJson(); +``` + + +### HAVING + +```php +$rows = $this->$core->db('table')->having('COUNT(*)', '>', 5)->toArray(); +``` + +OR HAVING: +```php +$rows = $this->$core->db('table')->orHaving('COUNT(*)', '>', 5)->toArray(); +``` + + +### INSERT + +Metoda `save` może dodać nowy rekord do tabeli lub zaktualizować istniejące, gdy zostanie opatrzona warunkiem. Po dodaniu nowego rekordu zostanie zwrócony jego numer identyfikacyjny. + +```php +// Dodanie nowego rekordu +$id = $this->$core->db('table')->save(['name' => 'James Gordon', 'city' => 'Gotham']); +// Wartość zwracana: numer ID nowego rekordu + +// Aktualizacja istniejącego rekordu +$this->$core->db('table')->where('age', 50)->save(['name' => 'James Gordon', 'city' => 'Gotham']); +// Wartość zwracana: TRUE w przypadku sukcesu lub FALSE przy niepowodzeniu +``` + + +### UPDATE + +Aktualizacja rekordów w przypadku powodzenia zwróci wartość `TRUE`. W przeciwnym razie będzie to `FALSE`. + +```php +// Zmiana jednej kolumny +$this->$core->db('table')->where('city', 'Gotham')->update('name', 'Joker'); + +// Zmiana wielu kolumn +$this->$core->db('table')->where('city', 'Gotham')->update(['name' => 'Joker', 'type' => 'Villain']); +``` + + +### SET + +```php +$this->$core->db('table')->where('age', 65)->set('age', 70)->set('name', 'Alfred Pennyworth')->update(); +``` + + +### DELETE + +Pomyślne usunięcie rekordów zwróci ich liczbę. + +```php +// Usunięcie rekordu o `id` równym 1 +$this->$core->db('table')->delete(1); + +// Usunięcie rekordu z warunkiem +$this->$core->db('table')->where('age', 20)->delete(); +``` + + +### ORDER BY + +Sortowanie rosnące: +```php +$this->$core->db('table')->asc('created_at')->toJson(); +``` + +Sortowanie malejące: +```php +$this->$core->db('table')->desc('created_at')->toJson(); +``` + +Łączenie sortowania: +```php +$this->$core->db('table')->desc('created_at')->asc('id')->toJson(); +``` + + +### GROUP BY + +```php +$this->$core->db('table')->group('city')->toArray(); +``` + + +### OFFSET, LIMIT + +```php +// Pobranie 5 rekordów, zaczynając od dziesiątego +$this->$core->db('table')->offset(10)->limit(5)->toJson(); +``` + + +### PDO + +Nie wszystkie zapytania da się stworzyć przy pomocy wyżej wymienionych metod *(np. utworzenie lub usunięcie tabeli)*, dlatego możesz również pisać zapytania przy pomocy [PDO](http://php.net/manual/en/book.pdo.php): + +```php +$this->$core->db()->pdo()->exec("DROP TABLE `example`"); +``` + + +System szablonów +---------------- + +Obsługa systemu szablonów jest łatwa i opiera się głównie na dwóch metodach. Jedna pozwala na przypisanie zmiennych, natomiast druga zwraca skompilowany kod. W wyjątkowych sytuacjach przydają się pozostałe dwie metody. + +### set + +```php +void set(string $name, mixed $value) +``` + +Przypisuje wartość do zmiennej, którą będzie można się posługiwać w widokach. + +#### Argumenty ++ `name` — nazwa zmiennej ++ `value` — wartość zmiennej + +#### Przykład +```php +$foo = ['bar', 'baz', 'qux']; +$this->tpl->set('foo', $foo); +``` + + +### draw + +```php +string draw(string $file) +``` + +Zwraca skompilowany kod widoku, w którym wcześniej zostały użyte tagi systemu szablonów. + +#### Argumenty ++ `file` — ścieżka do pliku + +#### Wartość zwracana +Ciąg znaków, tj. skompilowany widok. + +#### Przykład +```php +$this->tpl->draw(MODULES.'/galleries/view/admin/manage.html'); +``` + + +### noParse + +```php +string noParse(string $text) +``` + +Chroni przed kompilacją tagów systemu szablonów. + +#### Argumenty ++ `text` — tekst, który ma być pozostawiony bez zmian + +#### Przykład +```php +$this->tpl->noParse('Place this tag in website template: {$contact.form}'); +``` + + +### noParse_array + +```php +array noParse_array(array $array) +``` + +Chroni przed kompilacją tagów systemu szablonów wewnątrz tablicy. + +#### Argumenty ++ `array` — tablica, która ma być pozostawiona bez zmian + +#### Przykład +```php +$this->tpl->noParse_array(['{$no}', '{$changes}']); +``` + +Języki +------ + +Wszelkie pliki językowe znajdują się w katalogach `lang` wewnątrz modułów oraz pod ścieżką `inc/lang`. +W tej ostatniej ścieżce istnieją foldery odpowiadające nazwom języków w następującym formacie: `en_english`. Pierwszy człon to skrót języka, a drugi to jego pełna nazwa. +Wewnątrz katalogu mieści się plik `general.ini`, w którym zawarte są ogólne zmienne językowe dla systemu. +Po utworzeniu nowego folderu językowego, Batflat automatycznie wykryje dodany język i umożliwi jego wybranie w panelu administracyjnym. Należy jednak pamiętać, że procedurę stworzenia nowego języka należy powtórzyć dla każdego modułu. \ No newline at end of file