Файловый менеджер - Редактировать - /var/www/vhosts/studiocol.dev1.mndrn.cloud/readme.md
Назад
# Gyural PHP + MySQL Framework. ### Server Requirements - PHP >= 5.4 - MySQL >= 5 (if database required) - JSON Extension - mod_rewrite - Apache2 / Lite-speed - Basepath = '/' - Short Tag <? enabled - Love <3 ### Environment Settings You'll have to chmod the directories to allow write permission by the **WebServer**: - /upl/ - /cdn/cache/ ## Configuration If you are running the `setup` you probably don't have to touch it.. anyway the configuration file is located in `sys/version.json` **ErrorApp** Route errors to a custom **UnderscoreApp** or **Application** **IndexApp** Route the default index (http://example.com/) **sendMail** Options are: `php` or `smtp`, if you use `smtp` you'll have to edit the `/app/mail/_/mail_smtp_conf.lib.php` **tablesPrefix** You can specify a table prefix *(useful for multi-installations in the same db)* **ssl** if `true` the App require the https protocol. **dev** if `true` will output system information about the execution or errors. **online** if `false` the `sys/error-over.txt` will rendered. *(use it for maintenance)* ``` { "working":{ "ErrorApp":"error", "IndexApp":"setup/index", "siteName":"Gyural", "uri":"http://localhost:8888", "uriLogin":"/login", "uploadPath":"upl/", "mysql":"mysql://root:root@localhost/db-name", "sendmail":"php", "tablesPrefix":"", "supportMail":"noreply@gyural.com", "mail":"noreply@gyural.com", "ssl":"0", "dev":"0", "logStack":"0", "db":1, "version":"1.9.1", "online":1, "cdn":"/cdn/" } } ``` ## Getting Started You can download the latest version of Gyural from: [The Repository!](https://gyural.com/repo) ### Routing The routing mechanism is pretty easy. Every url is processed by Gyural and the most candidate App to reply to the request is invoked. Have a look at the example, to dig into: `http://www.example.com/news/detail/id:1` - exists a **sub-UnderscoreAPP** called *news_detailCtrl*? invoke it. - exists an **UnderscoreAPP** called news? and a controller named **detail** ? Invoke it. - exists an **UnderscoreAPP** called news? and the controller has the *$index_tollerant* propriety? call `MethodIndex()` - exists an **UnderscoreAPP** called news? and also an **APP** called: /news/detail.php ? invoke it. - exists a **news/detail.php** ? invoke it. - invoke the error.. there's nothing better. that's it, pretty simple. ### User Input Data `$_GET` variables can be passed as: `?var=a&va2=b` or with the custom syntax: `/var:a/var2:b` `$_POST` variables are passed as always with `<form method="post">` or via REST. `$_SESSION`, `$_REQUEST`, `$_FILES` works as default in **php** Variables, if in custom syntax, could be in every point of the url: `http://example.com/app/controller/id:1` is the same of `http://example.com/id:1/app/controller` and also `http://example.com/app/id:1/controller` ### Libs There's two type of libs (but basically the same behaviour) one, inside the **UnderscoreAPP** the other into `/libs/` ## UnderscoreApp **UnderscoreAPP** are the best way to create `Gyural Applications` work with the MVC pattern (Views are injected into Controllers) The architecture of **UnderscoreApp** is pretty simple: - /app - /nameOfApp - /_ - nameOfApp.ctrl.php [Controllers](#gyural-underscoreapp-controllers) - nameOfApp.lib.php [Libraries](#gyural-underscoreapp-libraries) - nameOfApp.funcs.php [Functions](#gyural-underscoreapp-functions) - nameOfApp.hooks.php [Hooks](#gyural-underscoreapp-hooks) - /_v - here the views.. it's not standard, it's a best pratice [Views](#gyural-underscoreapp-views) - /_assets - as above. Every **UnderscoreAPP** could have *Sub **UnderscoreApps***, that basically adds **libs** and **controllers** to the parent. ### Controllers Controllers have to extends standardController and have to specify **Ctrl** in the *class name* (eg: newsCtrl) > [standardController >](#api-standardcontroller) Controllers represent the interface between **users** and **libraries**. An **UnderscoreAPP** may not have a **controller** to work. Based on the method of access `Gyural` resolve the most adapt controller to return. **Accepted Methods** `Ctrl` (if nothing more specific exists) `Get` (for gets requests) `Post` (for posts requests) `Ajax` (for XMLHttpRequest requests) `Api` (for /api/ requests) ````public function CtrlIndex() {}```` ````public function GetIndex() {}```` ````public function PostIndex() {}```` etc. the structure is pretty simple, you'll have to specify `method` followed by the endpoint name. `function GetIndex()` reply to: `http://example.com/underscoreApp/` or `http://example.com/underscoreApp/index` ````php class newsCtrl extends standardController() { public function GetIndex() { // http://example.com/news/index } } ```` (note: All methods, expect **Api**, could print data. Api <u>must</u> return an `object`|`string`|`array`) You can request an **UnderscoreAPP** controller from another **_APP** *(actually from everywhere in Gyural)* with the helper: `LoadApp('news', 1)` A best pratice, in case of calling from the inside, is use the ApiController() because it will return infos instead of print it.. Actually this is a best pratice also for others Method in order to maximize the abstraction of the app. ````php $app = LoadApp('news', 1); $app->GetDettaglio(); ```` **For SubsUnderscoreApp** the class name must be named `parentName_subNameCtrl` and the file: `/parentName/_/parentName_subName.ctrl.php`. The end-point is: `http://example.com/parentName/subName/...` and if you'r calling it from the inside, you have to use the slashes: `LoadApp('parentName/subName', 1)` ### Libraries Libraries are the layer of data-manipolation, interaction with database or elaboration. If you'r working with database, and want to have a Libraries connected with database, see the standardObject > [standardObject >](#api-standardobject) **For SubsUnderscoreApp** the class name must be named `parentName_subName` and the file: `/parentName/_/parentName_subName.lib.php`. If you'r calling it from the inside, you have to use the slashes: `LoadClass('parentName/subName', 1)` ### Functions ### Hooks ### Views [Look at Application() >](#gyural-application) ## Application This is the old way to create Applications in Gyural, and it's basically a procedural way to build it. This is `now` used for attach **Views** to **Controller** in `UnderscoreApp` `Application($path, $behaviour, $app_data)` **$path** rapresent the path of the .php to be called. Without the .php extension. **$behaviour** accept as parameter: `null`, or `true`. Stick to `null` and everything gonna be all right :) **$app_data** is the object (actually a string, an array, everything) that will be passed to the Application. ``` php <? $news_detail = array('title' => 'Title of News', …); Application('news/detail', null, $news_detail); ?> --- /app/news/detai.php: <? <pre>print_r($app_data);</pre> will print the $news_detail; ?> ``` into the called Application, the `$app_data` is <u>always</u> stored into `$app_data` regardless the name of the given var. # API ## standardObject This Class is the basic connection between Objects and Database. It could extend every lib. ``` php class NameOfClass extends standardObject { } ``` The class has 2 required attributes: `gyu_table` map the table in the database `gyu_id` is the unique key of the table ``` var $gyu_table = 'tableName'; var $gyu_id = 'table_id'; ``` On the right, an example of working libs: `/app/news/_/news.lib.php` ``` php class news extends standardObject { var $gyu_table = 'news'; var $gyu_id = 'id_news'; } ``` ### Fetching Data The following methods fetch data from database. #### Retrive Objects @ filter() `$standardObject->filter([arg1, [arg2, [arg3, […]]])` With this method you can create the mysql query for retriving objects. Every params must be passed as args of the method. **Available parameters:** `array('key', '=|!=|>|>=|<=|<|LIKE', 'value')` > you can omit the operator if "=" `array('limit', min, max)` `'ONE'` > for only the first result `'#collection'` or `array('#collection', 'nameOfCollection')` > for return a collectionObject instead of array of arrays `'STRING'` every other non-keyword will be appended to the MySQL query. **Return** `array of objects` or `object` #### Retrive Objects @ filterArray() `$standardObject->filterArray($params)` This method is an alternative version of `->filter()` but accept an `array of arrays` as parameter instead of each array as parameters ``` php $params = array( array('author', 1), array('date', '>', 10), array('limit', 0, 100) ); $objs = LoadClass('news', 1)->filterArray($params); ``` **Return** `array of objects` or `object` #### Get Object from database @ get() This method is used to retrive a single Object identified by the `$gyu_id` field key into the `.lib.php` file. It works with every Object that `extends standardObject` ``` php $object = LoadClass('obj', 1)->get(1); $lib = LoadClass('obj', 1); $object = $lib->get(1); ``` **Return** `standardObject` This is an alias for: `LoadClass('obj', 1)->filter(array('id', 1), 'ONE')` ### Manipolate Object #### Popolate Object @ refill() `$standardObject->refill($array)` With this method you can refill the $standardObject with the given array. **Return** `standardObject` #### Get attribute @ getAttr() `$standardObject->getAttr('attribute')` This method access to the attribute specified as parameter.. By default reply with the database-stored value but you can override the behaviour creating ad-hoc getter methods: `function getTitolo()` will return in case of: `->getAttr('titolo')` ````php class test extends standardObject { function getTitolo() { return strtoupper($this->titolo); } } ```` **Return** mixed #### Verbose attribute @ verb() `$standardObject->verb('attribute')` ````php function verbTitolo() { return 'Verb: ' . $this->titolo; } ```` Works like [->getAttr()](#api-standardobject-manipolate-object) #### Set attribute @ setAttr() `$standardObject->setAttr('attribute', 'value')` This is the standard setter for the `standardObject`s. As for `->getAttr()` by defalt it store *value* as `$standardObject->`*attribute* but allow overriding `function setTitolo($value)` that will be called in case of: `->setAttr('titolo', 'test')` ````php class test extends standardObject { function setTitolo($value) { $this->titolo = $value . ' @ ' . time(); } } ```` **Return** `false` or mixed #### Check if attribute exists @ notNull() `$standardObject->notNull('attribute')` **Return** `true` or `false` ### Database Layer In order to work with Database, every standardObject must have specified the - $gyu_table *and* - $gyu_id those are used for identify objects. Nowadays it works only with mySQL, but you can create, for example, an **UnderscoreAPP** called "liteSql" and create a lib that override the `->hang` `->put` `->delete` `->get` `->filter` and also the `…Execute()` #### Store object @ hangExecute() `$standardObject->hangExecute()` This method store the `NEW` object into Database. Tecnically execute the `->hang()` query and return the inserted id. If you want to store an edit, you need to use the `->putExecute()` method. **Return** `mysql_id` of the object #### Prepare query to store Object @ hang() `$standardObject->hang()` **Return** `string` => the mySQL query #### Store updates @ putExecute() `standardObject->putExecute()` This method update the object into Database. As for the **hang** it will basically execute the `->put()` string. **Return** `Database Result` #### Prepare query to update Object @ put() `$standardObject->put()` **Return** `string` => the mySQL query #### Delete Object @ deleteExecute() `$standardObject->deleteExecute()` This method remove object from the database. (execution of the `->delete()` query) #### Prepare query to delete Object @ delete() `$standardObject->delete()` **Return** `string` => the mySQL query ## standardController For more detail look the source of: `/libs/standardController.lib.php` ## collectionsObject Collections are available for `Gyural >= 1.9` *note that this class doesn't affect the Database Query, but only manipolate the objects.* The **results** of collections are stored into: `$collectionObject->results` ### Popolate @ popolate() `$collectionObject->popolate($array_of_objects)` With this method you can create a new **Collection Object** ``` php $collection = LoadClass('collectionsObject', 1)->popolate(LoadClass('news', 1)->filter()); ``` **Return** a `collectionsObject` ### Filter @ filterBy() `$collectionsObject->filterBy($field, [$order = ASC { ASC | DESC }])` **Return** a `collectionObject` You can sort the whole collection based on an a method of the Object (contained in the collection) ``` php $collection->filterBy('author', DESC); ``` ### Change key @ changeKey() `$collectionObject->changeKey($field)` **Return** a `collectionObject` This method will rebuilt the whole collection based on the specified *$field* if there's more than 1 object for the specified field, will be created an array of results. ```php $collection->changeKey('news_id'); ``` ### Link @ link() `$collectionObject->link($field, $class)` **Return** a `collectionObject` This method will automatically load the links between objects. ```php $collection->link('author_id', 'users'); ``` ### Find in collection @ find() `$collectionObject->find($path)` **Return** a `collectionObject` This method will search in the collection for a specified *$path* ```php $collection->path('key=value'); ``` You can specify as *$path* a `string` or an `array` of `arrays` `->patch('key=value&key2=value2&key3>value3')` you can use the following operators: `=` `!=` `>` `<` `>=` `<=` `~= (this is for stristr())` if you use a string, put the operator between *key* and *value* if you use an array of arrays, you have to specify the operator as second element: `array('key', 'operator', 'value')` ```php $collection->path( array('key', '=', 'value'), array('b', '>', 1) ); is the same of: $collection->path('key=value&b>1'); ``` ### Map @ map() `$collectionObject->map($method)` Map every `object` whit specific $method **Return** a `collectionObject` ### # Objects @ lenght() This method return the lenght of the collection, as `int` **Return** an `int` ### Max value @ max() `$collectionObject->max($key, [$onlyVar])` **Return** by default the whole `object` that has the maximum value for the given *$key* **key** is the "looking for max value" field. **onlyVar** if specify the method return just the value ### Min value @ min() `$collectionObject->min($key, [$onlyVar])` **Return** by default the whole `object` that has the minimum value for the given *key* **key** is the "looking for min value" field. **onlyVar** if specify the method return just the value ### Average value @ average() `$collectionObject->average($key, [$onlyVar])` **Return** by default the whole `object` that has the average value for the give *key* **key** is the "looking for average value" field. **onlyVar** if specify the method return just the value ## Users _APP (refer to **User Underscore App** not `/libs/users.lib.php`. /libs/users.lib.php is deprecated, still in place for retro-compatibility) ## GyuOptimization _APP (refer to **User Underscore App** not `/libs/users.lib.php`. /libs/users.lib.php is deprecated, still in place for retro-compatibility) ## Api REST From `v1.6` Gyural is shipped with an REST API Layer, driven by the **Underscore App Controllers** The interface also accept **JSON Payloads** (>1.9). Every exposed API can be reached from: `http://example.com/api/underscore_app_name.method` ``` php function ApiMethod() { $object = array( 'thing' => 1, 'other_thing' => 2 ); return $object; } Will return: { thing: 1, other_thing: 2 } ``` you can also specify the output format of the request: `php|json|xml` by default (`/app/api/api.ctrl.php` to edit it), the url: `http://example.com/api/help` return a list of available API for the whole Application. # Functions ## Security **Located:** `/funcs/autoload/security.php` #### Right() #### i_can() #### logged() #### Me() ## Methods ## **Located:** `/funcs/autoload/methods.php` #### IsApplicationCallable #### ApplicationDetail #### isApplication #### MethodAjax #### isAjax #### MethodStandard #### MethodBufferSave #### MethodBuffer #### MethodDetect #### HttpResponse #### MethodApplication #### Application #### isSsl #### isMobile #### getallheaders ## Date **Located:** `/funcs/third/date.php` #### toUnix `CallFunction('date', 'toUnix', $date)` #### toDay `CallFunction('date', 'toDay', $seconds)` #### toDays `CallFunction('date', 'toDays', $seconds)` #### ago `CallFunction('date', 'ago', $data)` #### leapYear `CallFunction('date', 'leapYear', $year = null)` #### easter `CallFunction('date', 'Easter', $year = null)` ## Filesystem **Located:** `/funcs/third/filesystem.php` #### rrmdir `CallFunction('filesystem', 'rrmdir', $dir)` Remove a dir, recursively #### slug `CallFunction('filesystem', 'slug')` **Return** `string` ## Hooks **Located:** `/funcs/third/hooks.php` #### Get `CallFunction('hooks','get', $event)` #### Set `CallFunction('hooks','set', $event, $function, $priority = 0)` #### Load `CallFunction('hooks','load', $attr = null)` #### Rebuilt `CallFunction('hooks','rebuilt')` #### Empty `CallFunction('hooks','empty')` #### Dep `CallFunction('hooks','dep')` ## Strings **Located:** `/funcs/third/strings.php` #### Slug `CallFunction('strings','slug', $phrase, $maxLength = 50)` #### SubStr `CallFunction('strings','substr', $stringa, $length, $append = '…')` #### Taglia `CallFunction('strings','taglia', $testo, $word, $append = '…')` #### Taglia2 `CallFunction('strings','taglia2', $testo,$numMaxCaratteri)` #### Slug `CallFunction('strings','random', $length = 8)` ## Vars **Located:** `/funcs/third/vars.php` #### Get `CallFunction('vars', 'get', $key, $user = NULL, $complex = NULL)` #### Set `CallFunction('vars', 'set', $key, $value, $user = NULL)` #### Del `CallFunction('vars', 'del', $key, $user = NULL)` ## Maps **Located:** `/funcs/third/maps.php` #### GetLatLng `CallFunction('maps', GetLatLng', $ind)` #### GetAddress `CallFunction('maps', GetAddress', $ind)` #### CreateMap `CallFunction('maps', CreateMap', $lat, $lng, $w = '100%', $h = '600px', $js = true)` # Known Issues > [Issue Tracker >](http://bitbucket.com/mandarinoadv/gyural) ## Refresh the Cache! Roar! One of the most tedious things related to Gyural is the necessity to delete the /cdn/cache/sys/hooks.cache to allow Gyural to rebuilt it. Into the hooks.cache are stored info about the hooks (and so it affect things like: login, database connections, and any other things that uses hooks) # Credits **Gyural** is a [MandarinoAdv](http://www.mandarinoadv.com) product.
| ver. 1.4 |
Github
|
.
| PHP 8.2.5 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка