bbn / bbn
PHP opinionated framework
Installs: 2 451
Dependents: 55
Suggesters: 0
Security: 0
Stars: 3
Watchers: 5
Forks: 7
Open Issues: 0
Requires
- php: >=8.0
- ext-json: *
- ext-mbstring: *
- brick/phonenumber: 0.3.*
- composer/composer: 2.3.5
- czproject/git-php: 3.18.*
- dusterio/link-preview: 1.2.*
- erusev/parsedown: 1.7.*
- ezyang/htmlpurifier: ^4.13
- firebase/php-jwt: 5.2.*
- gettext/gettext: 4.8.1
- greenlion/php-sql-parser: 4.5.*
- mck89/peast: 1.13.*
- mollie/oauth2-mollie-php: ^2.0
- mpdf/mpdf: 8.0.*
- natxet/cssmin: 3.0.*
- nesbot/carbon: 2.57.*
- nikic/php-parser: 4.15.*
- opis/closure: ^3.5
- pear/archive_tar: 1.4.*
- phpdocumentor/reflection-docblock: 5.2.*
- phpmailer/phpmailer: 6.8.*
- psr/simple-cache: 1.0.*
- sabre/dav: 4.1.*
- scssphp/scssphp: 1.6.*
- sepia/po-parser: 6.0.*
- sunra/php-simple-html-dom-parser: 1.5.*
- tedivm/jshrink: 1.4.*
- tijsverkoyen/css-to-inline-styles: 2.2.*
- tplaner/when: 3.0.*
- wapmorgan/unified-archive: 0.1.*
- xemlock/htmlpurifier-html5: dev-master
- zordius/lightncandy: 1.2.*
Requires (Dev)
- friendsofphp/php-cs-fixer: 3.3.*
- mockery/mockery: 1.4.*
- pdepend/pdepend: 2.10.*
- phpmd/phpmd: 2.10.*
- phpunit/phpunit: 10.1.1
- phpunitgen/core: 3.0.*
- squizlabs/php_codesniffer: 3.6.*
- dev-master
- v1.x-dev
- 1.0.48
- 1.0.47
- 1.0.46
- 1.0.45
- 1.0.44
- 1.0.43
- 1.0.42
- 1.0.41
- 1.0.40
- 1.0.39
- 1.0.38
- 1.0.37
- 1.0.36
- 1.0.35
- 1.0.34
- 1.0.33
- 1.0.32
- 1.0.31
- 1.0.30
- 1.0.29
- 1.0.28
- 1.0.27
- 1.0.26
- 1.0.25
- 1.0.24
- 1.0.23
- 1.0.22
- 1.0.21
- 1.0.20
- 1.0.19
- 1.0.18
- 1.0.17
- 1.0.16
- 1.0.15
- 1.0.14
- 1.0.13
- 1.0.12
- 1.0.11
- 1.0.10
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1.x-dev
- 1.0.1
- 1.0.0
- 0.9.1
- v0.9.0
- dev-identities
- dev-cherry-pick-30d13a52
- dev-cherry-pick-a0036aa2
- dev-cherry-pick-2bbf5820
- dev-tasks_tokens
- dev-optionsv2
- dev-new-entities
- dev-fromnow_filters
- dev-fixed_provider_email
- dev-cherry-pick-bdb34bd8
- dev-fixed_button__link
- dev-origin/v1/send_abandoned_cart_fix
- dev-shop_cart_reminders_ok
- dev-abandoned_carts_email_fixes
- dev-warren-dev3
- dev-abandoned_cart_fix
- dev-check_products_in_cart
- dev-added_client_email
- dev-warren-dev
- dev-abandoned_carts_email
- dev-warren-test
- dev-shop_sales_emailing
- dev-insert_client_in_cart
- dev-db-ctypes
- dev-confirm_email_to_provider
- dev-warren-dev2
- dev-providers_emails
- dev-dev_clovis
- dev-quentin-0305
- dev-dev-jehovany-2
- dev-warren-lib
- dev-dev-jehovany
- dev-dev-jehovany-generator
- dev-cms-mirko
- dev-test-warren
- dev-dev-jehovnay-phpgenerator
- dev-googledrive2
- dev-shop_excel
- dev-quentin-2804
- dev-googledrive
- dev-jehovany
- dev-task-cancel-delete
- dev-quentin-dev2
- dev-quentin-dev
- dev-notes-important
- dev-correcttypes-query
- dev-lowre-master-patch-34006
- dev-quentin
- dev-dev-quentin
- dev-lowre-master-patch-39218
- dev-lowre-master-patch-88098
- dev-i18n-mirko2
- dev-mirko-privileges
- dev-mirko-task-prices
- dev-i18n-mirko
- dev-providers-shipping
- dev-tasks_notes
- dev-thomas-dev-vue3
- dev-vcs-mirko3
- dev-vcs-mirko2
- dev-vcs-mirko
- dev-vcs-class
- dev-check_content_type_update_2
- dev-check_content_type_update
- dev-shop-transactionslist-mirko
- dev-sales-shipping-mirko
- dev-email-sales-mirko
- dev-added_published_to_getAll
- dev-transactions-mirko
- dev-fix_transactions_list
- dev-transactions
- dev-trans-add
- dev-media-group-order
- dev-shop-mirko
- dev-transactions_list_fix
- dev-clientclass
- dev-order_media_group_insert
- dev-added_link_medias
- dev-getTransactions
- dev-change_status_transaction
- dev-getTransactionsList
- dev-fixes_clients
- dev-fix
- dev-dev-lucas-note-feature
- dev-clearcache-cms
- dev-cms-cache
- dev-user-exceptions
- dev-fix_update
- dev-api-gitlab-mirko
- dev-product_update_fix
- dev-notifications-fixing
- dev-note-pinned
- dev-task-fixing-mirko
- dev-task-cfg-mirko
- dev-fixes_on_frontimg
- dev-check_media_content_typ
- dev-client_name
- dev-change-by-lory
- dev-shop-cart-shippingdetails
- dev-shop-changes2
- dev-shop-changes
- dev-hash-index-warning
- dev-task-cfg
- dev-updatemenus-numchanges-mirko
- dev-appui-import-menus-mirko
- dev-hrclass-mirko
- dev-cart-mirko
- dev-gitlab-issues-mirko
- dev-gitlab-mirko
- dev-task-mirko
- dev-gridcount-mirko
- dev-userpvtwidgets-mirko
- dev-user-phone-login-mirko
- dev-meeting-dev
- dev-cron-runner
- dev-meeting
- dev-replace_media
- dev-new-note-structure
- dev-mirko-dev
- dev-testing
- dev-php7.4
- dev-qr-dev
- dev-thomas-dev
- dev-development
- dev-thomas-dev-ide
- dev-release
- dev-mk-comment-db
- dev-db3
- dev-new-db
- dev-db2
- dev-php8
This package is auto-updated.
Last update: 2024-12-23 17:54:07 UTC
README
bbn
The PHP library used by app-UI
You can install the library through Composer
{ "require": { "bbn/bbn": "dev/master" } }
A library targeted at Single Page Applications that includes:
- An MVC framework
- A powerful ORM supporting database structure analysis and lots of return methods
- An options' class on which most app-UI features are based
- API classes for integrating external services (Virtualmin, Cloudmin, Github, Gitlab, Payments...)
- A History class allowing to store each change done in the database and revert them
- Files, Images, and PDF files manipulation classes
- Filesystems explorator
- An automated task management system
- A universal caching system
- HTML generation classes
- Users and groups management classes
- Parsers for PHP, Javascript and VueJS components
- Specific classes for app-UI features such as:
- Notes
- Medias
- Chat
- Clipboard
- Content Management System
- Dashboard
- Databases management system
- Databases synchronization system
- I.D.E.
- Automated mailings
- Internationalization
- Masking system for letters and texts
- A notification system
- Data's observers
- Passwords management
- Planning and events management
- Project management system
- A statistics system
- A general project and workflow management system
- Static methods for manipulating all kind of data and other useful functions
- And many other features!
The bbn framework works with a router and some configuration files. An installer will be released in 2022.
There is still a huge amount of work on code review, translation and documentation ahead.
Any help is welcome!
Typical installation structure:
- app-ui/
- data/
- src/
- cfg/
- environments.yml
- settings.yml
- custom2.php
- cli/
- components/
- lib/
- locale/
- mvc/
- css/
- html/
- js/
- model/
- private/
- public/
- plugins/
- cfg/
- router.php
- public_html/
- .htaccess
- index.php
By default the BBN framework returns a HTML document if there is no POST, and a JSON object otherwise.
The bbn-js and bbn-vue libraries are intimately related with this framework, and deal with its I/O.
They catch each local link clicked, send them as a POST request, then deal with the response.
The JSON object returned by clicking a link typically holds the following properties:
Life cycle of a typical request
The redirection
➡️ Call to https://myapp.com/just/testing (which does not exist)
➡️ An .htaccess file rewrites all the not found files to an index.php file
➡️ The index file chdir
in the app folder src/
which should be outside of the public root
➡️ It then includes the router which should be in the src/ directory (as a symlink towards vendor)
The routing
➡️ It recognizes the predefined configuration in which it stands through the hostname
and app_path
definitions from src/cfg/environment.yml
➡️ It defines constants and initializes autoload
➡️ It instantiates different classes depending on the configuration
➡️ It creates the MVC class, which will look for the right controller:
- It looks into
src/mvc/public/
for a controller corresponding to the pathjust/testing
:- If it is a landing page (no POST) the file should be:
src/mvc/public/just/testing/index.php
- Otherwise the file should be:
src/mvc/public/just/testing.php
- If it is a landing page (no POST) the file should be:
- while it doesn't find the file it goes backward in the directories:
- If it is a landing page (no POST) it looks for:
src/mvc/public/just/index.php
and finallysrc/mvc/public/index.php
- Otherwise it looks for:
src/mvc/public/just.php
then returns a404
if it doesn't find it
- If it is a landing page (no POST) it looks for:
The execution
➡️ An optional file src/custom1.php
is included with an object $bbn
available with property mvc
➡️ If we are not in CLI mode a session is started
➡️ Still not in CLI mode an optional file src/custom2.php
is included with an object $bbn
available with property mvc
, user
and session
depending on the configuration
➡️ The MVC includes the controller
The output
➡️ The output buffer becomes the content
property of the response object
➡️ An optional file src/custom3.php
is included with an object $bbn
available with the new property obj
which will be the output
➡️ If it is a landing page (no POST) the property content
will be returned with HTML headers
➡️ Otherwise the object mvc->obj
will be returned encoded with JSON headers
➡️ If there is no content
in obj
but there is file
or image
the response will be dealt accordingly with the corresponding headers
A few examples
ORM
<?php use bbn\X; /** @var bbn\Db $db */ // Returns an array with fields, cols and keys props which will give you all information about a table X::adump($db->modelize("my_table")); // Simple query X::adump($db->getRows("SELECT * FROM my_table WHERE status = ?", $var)); // Same query X::adump($db->select( "my_table", // table [], // all columns ["status" => $var] // WHERE )); // More arguments X::adump($db->rselectAll( "my_table", // table ["field1", "field2"], // columns [["id", "<", 25], ["name", "LIKE", "tri%"]], // WHERE ["date" => DESC, "name"], // ORDER 50, // LIMIT 20 // START )); // The full way X::adump($db->rselectAll([ 'tables' => ["my_table_name", "my_table_name2"], 'fields' => ["field1", "field2"], // all columns 'where' => [ 'logic' => 'OR', 'conditions' => [ 'user' => 'admin', 'conditions' => [ 'logic' => 'AND', 'conditions' => [ // Mixed mode allowed in filters [ 'field' => 'my_date', 'operator' => '<', 'exp' => 'NOW()' ], ["id", "<", 25] 'name' => 'tri%' ], ] ] ], 'join' => [ [ 'table' => 'my_table3', 'on' => [ [ 'field' => 'my_table3.uid', 'exp' => 'my_table.uid_table3' // Operator is = by default ] ] ] ], 'order' => ["date" => DESC, "name"], // ORDER 'group_by' => ['my_table.id'], 'limit' => 50, 'start' => 20 ]));
MVC
use bbn\X; /** @var bbn\Mvc\Controller $ctrl */ // the/path/to/the/controller X::adump($ctrl->getPath()); // The corresponding (= same path) model X::adump($ctrl->getModel()); // Another model to which we send data X::adump($ctrl->getModel('another/model', ['some' => 'data'])); X::adump( // HTML view with same path (in html) $ctrl->getView(), // with data sent to js $ctrl->getView('another/view', 'js', ['my_data' => 'my_value']), // encapsulated in a script tag $ctrl->getJs('another/view', ['my_data' => 'my_value']), // compiles and returns the Less code from the same path (in css) $ctrl->getLess(), // The post data $ctrl->post, // The get data $ctrl->get, // The files array (revisited) $ctrl->files, // an array of each bit of the path which are not part of (=after) the controller $ctrl->arguments, // an associative array that will be sent to the model if nothiung else is sent $ctrl->data, // Adds properties to $ctrl->data $ctrl->addData(['my' => 'var']) // Moves the request to another controller $ctrl->reroute('another/route') // Includes another controller $ctrl->add('another/controller', ['some' => 'data']), // Includes a private controller (unaccessible through URL) $ctrl->add('another/controller', [], true), // timer will be a property of the $ctrl->inc property, also available in the subsequent models $ctrl->addInc('timer', new bbn\Util\Timer()) ); // The most useful functions: // Fetches for everything related to the current controller (model, html, js, css) and combines the results into a single object ($ctrl->obj). That's the typical function for showing a page $ctrl->combo("My page title"); // Transform all input (get, post, files) data into a single data array // Fetches the corresponding model with this data // and returns its result as an object. // Typically used for write operations. $ctrl->action(); // The second parameter allows the javascript to access the model's data $ctrl->combo("My page title", true); // Here the second parameter is the data sent to javascript $ctrl->combo("My page title", ['my' => 'data']); ?>
Accessing the data through javascript
If the anonymous function returns a function, the data will be its second argument
(() => { return (container, data) => { if (data && data.success && data.color) { container.style.color = '#' + data.color; } }; })();
If the anonymous function returns an object, the data will reside in the source property
(() => { return { computed: { realColor() { return '#' + this.source.color } } }; })();
The HTML views are server-rendered and therefore can by default access all the data
Example of an HTML view
<div style="color: #{{color}}">Hello world</div>
Example of a PHP view
<div style="color: #<?= $color ?>"><?= _("Hello world") ?></div>
Option
The option system is built in a database with a table having the following structure:
The code
system allows us to find an option just by its codes path.
For example the sequence of codes permissions
, ide
, appui
targets:
- in the option which has code
appui
whose parent is theroot
- in the option which has code
ide
- the option which has code
permissions
The order is reversed to go from the most precise to the most general when in fact the sequence is:
root
➡️ appui
➡️ ide
➡️ permissions
use bbn\X; /** @var bbn\Appui\Option $option */ // Returns the option ID from its code sequence X::adump($option->fromCode('permissions', 'ide', 'appui')); // The whole option with the same arguments (which work for all fetching functions) X::adump($option->option('permissions', 'ide', 'appui')); // It works also with the ID: $id_option = $option->fromCode('permissions', 'ide', 'appui'); X::adump($option->option($id_option)); // ID is a 32 hex value, so a code shouldn't look like one // If the last parameter is an ID, it will take this ID as the root X::adump($option->option('test', 'page', $id_option)); // Is the same as X::adump($option->option('test', 'page', 'permissions', 'ide', 'appui')); // Then you can fetch options (i.e. the children of an option) in many different ways X::adump( // Only the IDs, in the right order if orderable $option->items($id_option), // Only the IDs, text, and code if applicable $option->options($id_option), // All the option properties (but cfg) $option->fullOptions($id_option), // Same as options but with an items property holding the lineage $option->tree($id_option), // Same as fullOptions but with an items property holding the lineage $option->fullTree($id_option), // Returns the code: permissions $option->code($id_option), // Returns the text $option->text($id_option), // You can insert whaever you like $option->add(['id_parent' => $id_option, 'text' => 'Hello', 'myProp' => 'myValue']) );