First Commit
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Jorge Patricio Castro Castillo
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice, other copyright notices and this permission notice
|
||||
shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "eftec/bladeone",
|
||||
"description": "The standalone version Blade Template Engine from Laravel in a single php file",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"blade",
|
||||
"template",
|
||||
"view",
|
||||
"php",
|
||||
"templating"
|
||||
],
|
||||
"homepage": "https://github.com/EFTEC/BladeOne",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jorge Patricio Castro Castillo",
|
||||
"email": "jcastro@eftec.cl"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.4",
|
||||
"ext-json": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "This extension is used if it's active",
|
||||
"eftec/bladeonehtml": "Extension to create forms"
|
||||
},
|
||||
"archive": {
|
||||
"exclude": [
|
||||
"/examples"
|
||||
]
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"eftec\\bladeone\\": "lib/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"eftec\\tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"bin": [
|
||||
"lib/bladeonecli"
|
||||
],
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5.23"
|
||||
}
|
||||
}
|
||||
+4675
File diff suppressed because it is too large
Load Diff
+333
@@ -0,0 +1,333 @@
|
||||
<?php /** @noinspection UnknownInspectionInspection */
|
||||
|
||||
|
||||
|
||||
/** @noinspection TypeUnsafeComparisonInspection */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace eftec\bladeone;
|
||||
|
||||
use Exception;
|
||||
use JsonException;
|
||||
use function fclose;
|
||||
use function file_put_contents;
|
||||
use function filemtime;
|
||||
use function filesize;
|
||||
use function fopen;
|
||||
use function fwrite;
|
||||
use function is_array;
|
||||
use function is_object;
|
||||
use function ob_get_contents;
|
||||
use function print_r;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
use function time;
|
||||
|
||||
/**
|
||||
* trait BladeOneCache
|
||||
* Copyright (c) 2016 Jorge Patricio Castro Castillo MIT License. Don't delete this comment, its part of the license.
|
||||
* Extends the tags of the class BladeOne. Its optional
|
||||
* It adds the next tags to the template
|
||||
* <code>
|
||||
* @ cache([cacheid],[duration=86400]). The id is optional. The duration of the cache is in seconds
|
||||
* // content here
|
||||
* @ endcache()
|
||||
* </code>
|
||||
* It also adds a new function (optional) to the business or logic layer
|
||||
* <code>
|
||||
* if ($blade->cacheExpired('hellocache',1,5)) { //'helloonecache' =template, =1 id cache, 5=duration (seconds)
|
||||
* // cache expired, so we should do some stuff (such as read from the database)
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @package BladeOneCache
|
||||
* @version 3.43 2024-03-02
|
||||
* @link https://github.com/EFTEC/BladeOne
|
||||
* @author Jorge Patricio Castro Castillo <jcastro arroba eftec dot cl>
|
||||
*/
|
||||
trait BladeOneCache
|
||||
{
|
||||
protected int $curCacheId = 0;
|
||||
protected int $curCacheDuration = 0;
|
||||
protected int $curCachePosition = 0;
|
||||
protected bool $cacheRunning = false;
|
||||
protected bool $cachePageRunning = false;
|
||||
/** @var string|null where the log file will be stored */
|
||||
protected ?string $cacheLog;
|
||||
/**
|
||||
* @var array avoids comparing the file different times. It also avoids race conditions.
|
||||
*/
|
||||
private array $cacheExpired = [];
|
||||
/**
|
||||
* @var string=['get','post','getpost','request',null][$i]
|
||||
*/
|
||||
private string $cacheStrategy;
|
||||
/** @var array|null */
|
||||
private ?array $cacheStrategyIndex;
|
||||
|
||||
/**
|
||||
* @return null|string $cacheStrategy=['get','post','getpost','request',null][$i]
|
||||
*/
|
||||
public function getCacheStrategy(): ?string
|
||||
{
|
||||
return $this->cacheStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* It sets the cache log. If not cache log then it does not generate a log file<br>
|
||||
* The cache log stores each time a template is created or expired.<br>
|
||||
*
|
||||
* @param string $file
|
||||
*/
|
||||
public function setCacheLog($file): void
|
||||
{
|
||||
$this->cacheLog=$file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function writeCacheLog($txt, $nivel): void
|
||||
{
|
||||
if (!$this->cacheLog) {
|
||||
return; // if there is not a file assigned then it skips saving.
|
||||
}
|
||||
$fz = @filesize($this->cacheLog);
|
||||
if (is_object($txt) || is_array($txt)) {
|
||||
$txt = print_r($txt, true);
|
||||
}
|
||||
// Rewrite file if more than 100000 bytes
|
||||
$mode=($fz > 100000) ? 'w':'a';
|
||||
$fp = fopen($this->cacheLog, $mode);
|
||||
if ($fp === false) {
|
||||
return;
|
||||
}
|
||||
switch ($nivel) {
|
||||
case 1:
|
||||
$txtNivel='expired';
|
||||
break;
|
||||
case 2:
|
||||
$txtNivel='new';
|
||||
break;
|
||||
default:
|
||||
$txtNivel='other';
|
||||
}
|
||||
$txtarg= json_encode($this->cacheUniqueGUID(false), JSON_THROW_ON_ERROR);
|
||||
fwrite($fp, date('c') . "\t$txt\t$txtNivel\t$txtarg\n");
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* It sets the strategy of the cache page.
|
||||
*
|
||||
* @param null|string $cacheStrategy =['get','post','getpost','request',null][$i]
|
||||
* @param array|null $index if null then it reads all indexes. If not, it reads an indexes.
|
||||
*/
|
||||
public function setCacheStrategy($cacheStrategy, $index = null): void
|
||||
{
|
||||
$this->cacheStrategy = $cacheStrategy;
|
||||
$this->cacheStrategyIndex = $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* It obtains a unique GUID based in:<br>
|
||||
* **get**= parameters from the url<br>
|
||||
* **post**= parameters sends via post<br>
|
||||
* **getpost** = a mix between get and post<br>
|
||||
* **request** = get, post and cookies (including sessions)<br>
|
||||
* MD5 could generate colisions (2^64 = 18,446,744,073,709,551,616) but the end hash is the sum of the hash of
|
||||
* the page + this GUID.
|
||||
*
|
||||
* @param bool $serialize if true then it serializes using md5
|
||||
* @return string|null
|
||||
*/
|
||||
private function cacheUniqueGUID($serialize = true): ?string
|
||||
{
|
||||
switch ($this->cacheStrategy) {
|
||||
case 'get':
|
||||
$r = $_GET;
|
||||
break;
|
||||
case 'post':
|
||||
$r = $_POST;
|
||||
break;
|
||||
case 'getpost':
|
||||
$arr = array_merge($_GET, $_POST);
|
||||
$r = $arr;
|
||||
break;
|
||||
case 'request':
|
||||
$r = $_REQUEST;
|
||||
break;
|
||||
default:
|
||||
$r = null;
|
||||
}
|
||||
if ($this->cacheStrategyIndex === null || !is_array($r)) {
|
||||
$r= serialize($r);
|
||||
} else {
|
||||
$copy=[];
|
||||
foreach ($r as $key => $item) {
|
||||
if (in_array($key, $this->cacheStrategyIndex, true)) {
|
||||
$copy[$key]=$item;
|
||||
}
|
||||
}
|
||||
$r=serialize($copy);
|
||||
}
|
||||
return $serialize===true ? md5($r): $r;
|
||||
}
|
||||
|
||||
public function compileCache($expression): string
|
||||
{
|
||||
// get id of template
|
||||
// if the file exists then
|
||||
// compare date.
|
||||
// if the date is too old then re-save.
|
||||
// else
|
||||
// save for the first time.
|
||||
|
||||
return $this->phpTag . "echo \$this->cacheStart$expression; if(!\$this->cacheRunning) { ?>";
|
||||
}
|
||||
|
||||
public function compileEndCache($expression): string
|
||||
{
|
||||
return $this->phpTag . "} // if cacheRunning\necho \$this->cacheEnd$expression; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* It gets the filename of the compiled file (cached). If cache is not enabled, then it
|
||||
* returns the regular file.
|
||||
*
|
||||
* @param string $view
|
||||
* @return string The full filename
|
||||
*/
|
||||
private function getCompiledFileCache($view): string
|
||||
{
|
||||
$id = $this->cacheUniqueGUID();
|
||||
if ($id !== null) {
|
||||
return str_replace($this->compileExtension, '_cache' . $id
|
||||
. $this->compileExtension, $this->getCompiledFile($view));
|
||||
}
|
||||
return $this->getCompiledFile($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* run the blade engine. It returns the result of the code.
|
||||
*
|
||||
* @param string $view The name of the cache. Ex: "folder.folder.view" ("/folder/folder/view.blade")
|
||||
* @param array $variables An associative arrays with the values to display.
|
||||
* @param int $ttl time to live (in second).
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function runCache($view, $variables = [], $ttl = 86400): string
|
||||
{
|
||||
$this->cachePageRunning = true;
|
||||
$cacheStatus=$this->cachePageExpired($view, $ttl);
|
||||
if ($cacheStatus!==0) {
|
||||
$this->writeCacheLog($view, $cacheStatus);
|
||||
$this->cacheStart('_page_', $ttl);
|
||||
$content = $this->run($view, $variables); // if no cache, then it runs normally.
|
||||
$this->fileName = $view; // sometimes the filename is replaced (@include), so we restore it
|
||||
$this->cacheEnd($content); // and it stores as a cache paged.
|
||||
} else {
|
||||
$content = $this->getFile($this->getCompiledFileCache($view));
|
||||
}
|
||||
$this->cachePageRunning = false;
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the block cache expired (or doesn't exist), otherwise false.
|
||||
*
|
||||
* @param string $templateName name of the template to use (such hello for template hello.blade.php)
|
||||
* @param string $id (id of cache, optional, if not id then it adds automatically a number)
|
||||
* @param int $cacheDuration (duration of the cache in seconds)
|
||||
* @return int 0=cache exists, 1= cache expired, 2=not exists, string= the cache file (if any)
|
||||
*/
|
||||
public function cacheExpired($templateName, $id, $cacheDuration): int
|
||||
{
|
||||
if ($this->getMode() & 1) {
|
||||
return 2; // forced mode, hence it always expires. (fast mode is ignored).
|
||||
}
|
||||
$compiledFile = $this->getCompiledFile($templateName) . '_cache' . $id;
|
||||
return $this->cacheExpiredInt($compiledFile, $cacheDuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns true if the whole page expired.
|
||||
*
|
||||
* @param string $templateName
|
||||
* @param int $cacheDuration is seconds.
|
||||
* @return int 0=cache exists, 1= cache expired, 2=not exists, string= the cache content (if any)
|
||||
*/
|
||||
public function cachePageExpired($templateName, $cacheDuration): int
|
||||
{
|
||||
if ($this->getMode() & 1) {
|
||||
return 2; // forced mode, hence it always expires. (fast mode is ignored).
|
||||
}
|
||||
$compiledFile = $this->getCompiledFileCache($templateName);
|
||||
return $this->CacheExpiredInt($compiledFile, $cacheDuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used by cacheExpired() and cachePageExpired()
|
||||
*
|
||||
* @param string $compiledFile
|
||||
* @param int $cacheDuration is seconds.
|
||||
* @return int|mixed 0=cache exists, 1= cache expired, 2=not exists, string= the cache content (if any)
|
||||
*/
|
||||
private function cacheExpiredInt($compiledFile, $cacheDuration)
|
||||
{
|
||||
if (isset($this->cacheExpired[$compiledFile])) {
|
||||
// if the information is already in the array then returns it.
|
||||
return $this->cacheExpired[$compiledFile];
|
||||
}
|
||||
$date = @filemtime($compiledFile);
|
||||
if ($date) {
|
||||
if ($date + $cacheDuration < time()) {
|
||||
$this->cacheExpired[$compiledFile] = 1;
|
||||
return 2; // time-out.
|
||||
}
|
||||
} else {
|
||||
$this->cacheExpired[$compiledFile] = 2;
|
||||
return 1; // no file
|
||||
}
|
||||
$this->cacheExpired[$compiledFile] = 0;
|
||||
return 0; // cache active.
|
||||
}
|
||||
|
||||
public function cacheStart($id = '', $cacheDuration = 86400): void
|
||||
{
|
||||
$this->curCacheId = ($id == '') ? ($this->curCacheId + 1) : $id;
|
||||
$this->curCacheDuration = $cacheDuration;
|
||||
$this->curCachePosition = strlen(ob_get_contents());
|
||||
if ($this->cachePageRunning) {
|
||||
$compiledFile = $this->getCompiledFileCache($this->fileName);
|
||||
} else {
|
||||
$compiledFile = $this->getCompiledFile() . '_cache' . $this->curCacheId;
|
||||
}
|
||||
|
||||
if ($this->cacheExpired('', $id, $cacheDuration) !==0) {
|
||||
$this->cacheRunning = false;
|
||||
} else {
|
||||
$this->cacheRunning = true;
|
||||
$content = $this->getFile($compiledFile);
|
||||
echo $content;
|
||||
}
|
||||
}
|
||||
|
||||
public function cacheEnd($txt = null): void
|
||||
{
|
||||
if (!$this->cacheRunning) {
|
||||
$txt = $txt ?? substr(ob_get_contents(), $this->curCachePosition);
|
||||
if ($this->cachePageRunning) {
|
||||
$compiledFile = $this->getCompiledFileCache($this->fileName);
|
||||
} else {
|
||||
$compiledFile = $this->getCompiledFile() . '_cache' . $this->curCacheId;
|
||||
}
|
||||
file_put_contents($compiledFile, $txt);
|
||||
}
|
||||
$this->cacheRunning = false;
|
||||
}
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace eftec\bladeone;
|
||||
|
||||
use Redis;
|
||||
use function class_exists;
|
||||
use function file_put_contents;
|
||||
use function filemtime;
|
||||
use function ob_get_contents;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
use function time;
|
||||
|
||||
/**
|
||||
* trait BladeOneCacheRedis
|
||||
* Copyright (c) 2016 Jorge Patricio Castro Castillo MIT License. Don't delete this comment, its part of the license.
|
||||
* Extends the tags of the class BladeOne. Its optional
|
||||
* It adds the next tags to the template
|
||||
* <code>
|
||||
* @ cache([cacheid],[duration=86400]). The id is optional. The duration of the cache is in seconds
|
||||
* // content here
|
||||
* @ endcache()
|
||||
* </code>
|
||||
* It also adds a new function (optional) to the business or logic layer
|
||||
* <code>
|
||||
* if ($blade->cacheExpired('hellocache',1,5)) { //'helloonecache' =template, =1 id cache, 5=duration (seconds)
|
||||
* // cache expired, so we should do some stuff (such as read from the database)
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @package BladeOneCacheRedis
|
||||
* @version 0.1 2017-12-15 NOT YET IMPLEMENTED, ITS A WIP!!!!!!!!
|
||||
* @link https://github.com/EFTEC/BladeOne
|
||||
* @author Jorge Patricio Castro Castillo <jcastro arroba eftec dot cl>
|
||||
*/
|
||||
const CACHEREDIS_SCOPEURL = 1;
|
||||
|
||||
trait BladeOneCacheRedis
|
||||
{
|
||||
protected $curCacheId = 0;
|
||||
protected $curCacheDuration = "";
|
||||
protected $curCachePosition = 0;
|
||||
protected $cacheRunning = false;
|
||||
/** @var \Redis $redis */
|
||||
protected $redis;
|
||||
protected $redisIP = '127.0.0.1';
|
||||
protected $redisPort = 6379;
|
||||
protected $redisTimeOut = 2.5;
|
||||
protected $redisConnected = false;
|
||||
protected $redisNamespace = 'bladeonecache:';
|
||||
protected $redisBase = 0;
|
||||
private $cacheExpired = []; // avoids to compare the file different times.
|
||||
|
||||
//<editor-fold desc="compile">
|
||||
public function compileCache($expression)
|
||||
{
|
||||
// get id of template
|
||||
// if the file exists then
|
||||
// compare date.
|
||||
// if the date is too old then re-save.
|
||||
// else
|
||||
// save for the first time.
|
||||
|
||||
return $this->phpTag . "echo \$this->cacheStart{$expression}; if(!\$this->cacheRunning) { ?>";
|
||||
}
|
||||
|
||||
public function compileEndCache($expression)
|
||||
{
|
||||
return $this->phpTag . "} // if cacheRunning\necho \$this->cacheEnd{$expression}; ?>";
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
public function connect($redisIP = null, $redisPort = null, $redisTimeOut = null)
|
||||
{
|
||||
if ($this->redisConnected) {
|
||||
return true;
|
||||
}
|
||||
if (!class_exists('Redis')) {
|
||||
return false; // it requires redis.
|
||||
}
|
||||
if ($redisIP !== null) {
|
||||
$this->redisIP = $redisIP;
|
||||
$this->redisPort = $redisPort;
|
||||
$this->redisTimeOut = $redisTimeOut;
|
||||
}
|
||||
$this->redis = new Redis();
|
||||
// 2.5 sec timeout.
|
||||
$this->redisConnected = $this->redis->connect($this->redisIP, $this->redisPort, $this->redisTimeOut);
|
||||
|
||||
return $this->redisConnected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the cache expired (or doesn't exist), otherwise false.
|
||||
*
|
||||
* @param string $templateName name of the template to use (such hello for template hello.blade.php)
|
||||
* @param string $id (id of cache, optional, if not id then it adds automatically a number)
|
||||
* @param int $scope scope of the cache.
|
||||
* @param int $cacheDuration (duration of the cache in seconds)
|
||||
* @return bool (return if the cache expired)
|
||||
*/
|
||||
public function cacheExpired($templateName, $id, $scope, $cacheDuration)
|
||||
{
|
||||
if ($this->getMode() & 1) {
|
||||
return true; // forced mode, hence it always expires. (fast mode is ignored).
|
||||
}
|
||||
$compiledFile = $this->getCompiledFile($templateName) . '_cache' . $id;
|
||||
if (isset($this->cacheExpired[$compiledFile])) {
|
||||
// if the information is already in the array then returns it.
|
||||
return $this->cacheExpired[$compiledFile];
|
||||
}
|
||||
$date = @filemtime($compiledFile);
|
||||
if ($date) {
|
||||
if ($date + $cacheDuration < time()) {
|
||||
$this->cacheExpired[$compiledFile] = true;
|
||||
return true; // time-out.
|
||||
}
|
||||
} else {
|
||||
$this->cacheExpired[$compiledFile] = true;
|
||||
return true; // no file
|
||||
}
|
||||
$this->cacheExpired[$compiledFile] = false;
|
||||
return false; // cache active.
|
||||
}
|
||||
|
||||
public function cacheStart($id = "", $cacheDuration = 86400)
|
||||
{
|
||||
$this->curCacheId = ($id == "") ? ($this->curCacheId + 1) : $id;
|
||||
$this->curCacheDuration = $cacheDuration;
|
||||
$this->curCachePosition = strlen(ob_get_contents());
|
||||
$compiledFile = $this->getCompiledFile() . '_cache' . $this->curCacheId;
|
||||
if ($this->cacheExpired('', $id, $cacheDuration)) {
|
||||
$this->cacheRunning = false;
|
||||
} else {
|
||||
$this->cacheRunning = true;
|
||||
$content = $this->getFile($compiledFile);
|
||||
echo $content;
|
||||
}
|
||||
// getFile($fileName)
|
||||
}
|
||||
|
||||
public function cacheEnd()
|
||||
{
|
||||
if (!$this->cacheRunning) {
|
||||
$txt = substr(ob_get_contents(), $this->curCachePosition);
|
||||
$compiledFile = $this->getCompiledFile() . '_cache' . $this->curCacheId;
|
||||
file_put_contents($compiledFile, $txt);
|
||||
}
|
||||
$this->cacheRunning = false;
|
||||
}
|
||||
|
||||
private function keyByScope($scope)
|
||||
{
|
||||
$key = '';
|
||||
if ($scope && CACHEREDIS_SCOPEURL) {
|
||||
$key .= $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
<?php /** @noinspection ReturnTypeCanBeDeclaredInspection */
|
||||
/** @noinspection PhpMissingReturnTypeInspection */
|
||||
/** @noinspection UnknownInspectionInspection */
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
|
||||
namespace eftec\bladeone;
|
||||
|
||||
/*
|
||||
* It's an example of a custom set of functions for bladeone.
|
||||
* in examples/TestCustom.php there is a working example
|
||||
*/
|
||||
|
||||
use function array_pop;
|
||||
|
||||
trait BladeOneCustom
|
||||
{
|
||||
private array $customItem = []; // indicates the type of the current tag. such as select/selectgroup/etc.
|
||||
|
||||
//<editor-fold desc="compile function">
|
||||
/**
|
||||
* Usage @panel('title',true,true).....@endpanel()
|
||||
*
|
||||
* @param $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compilePanel($expression)
|
||||
{
|
||||
$this->customItem[] = 'Panel';
|
||||
return $this->phpTag . "echo \$this->panel$expression; ?>";
|
||||
}
|
||||
|
||||
protected function compileEndPanel()
|
||||
{
|
||||
$r = @array_pop($this->customItem);
|
||||
if ($r === null) {
|
||||
$this->showError('@endpanel', 'Missing @compilepanel or so many @compilepanel', true);
|
||||
}
|
||||
return ' </div></section><!-- end panel -->'; // we don't need to create a function for this.
|
||||
}
|
||||
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold desc="used function">
|
||||
protected function panel($title = '', $toggle = true, $dismiss = true)
|
||||
{
|
||||
return "<section class='panel'>
|
||||
<header class='panel-heading'>
|
||||
<div class='panel-actions'>
|
||||
" . (($toggle) ? "<a href='#' class='panel-action panel-action-toggle' data-panel-toggle></a>" : '') . '
|
||||
' . (($dismiss) ? "<a href='#' class='panel-action panel-action-dismiss' data-panel-dismiss></a>" : '') . "
|
||||
</div>
|
||||
|
||||
<h2 class='panel-title'>$title</h2>
|
||||
</header>
|
||||
<div class='panel-body'>";
|
||||
}
|
||||
//</editor-fold>
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace eftec;
|
||||
|
||||
// this code only runs on CLI but only if bladeonecli.php is called directly and via command line.
|
||||
use eftec\bladeone\BladeOne;
|
||||
|
||||
if (!defined('PHPUNIT_COMPOSER_INSTALL') && !defined('__PHPUNIT_PHAR__')
|
||||
&& isset($_SERVER['PHP_SELF']) &&
|
||||
!http_response_code() &&
|
||||
(basename($_SERVER['PHP_SELF']) === 'bladeonecli.php' || basename($_SERVER['PHP_SELF']) === 'bladeonecli')
|
||||
) {
|
||||
// we also excluded it if it is called by phpunit.
|
||||
include_once __DIR__ . '/BladeOne.php';
|
||||
|
||||
$compilepath = BladeOne::getParameterCli('compilepath', null);
|
||||
$templatepath = BladeOne::getParameterCli('templatepath', null);
|
||||
if (!BladeOne::isAbsolutePath($compilepath)) {
|
||||
$compilepath = getcwd() . '/' . $compilepath;
|
||||
}
|
||||
if (!BladeOne::isAbsolutePath($templatepath)) {
|
||||
$templatepath = getcwd() . '/' . $templatepath;
|
||||
}
|
||||
$inst = new BladeOne($templatepath, $compilepath);
|
||||
$inst->cliEngine();
|
||||
} else {
|
||||
@http_response_code(404);
|
||||
}
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Escuela de Formación Técnica Chile SPA
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+983
@@ -0,0 +1,983 @@
|
||||
# BladeOneHtml
|
||||
It is a PHP library that allows to create forms (view) easily, cleanly and without killing the performance. It uses the library BladeOne to renders the view. This library only uses a single dependency, one file and nothing more.
|
||||
|
||||
This library works in two ways:
|
||||
|
||||
* It compiles a script (our view that use our tags), in a native PHP code.
|
||||
* And the next read, if the script exists, then it uses it (instead of re-compiling). And since the script is native code, then it is exactly like to work in vanilla-php,
|
||||
but it is way easy to write and to maintenance.
|
||||
|
||||
|
||||
|
||||
[](https://packagist.org/packages/eftec/bladeonehtml)
|
||||
[](https://packagist.org/packages/eftec/bladeonehtml)
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
|
||||
|
||||
<!-- TOC -->
|
||||
* [BladeOneHtml](#bladeonehtml)
|
||||
* [Usage](#usage)
|
||||
* [Template basic](#template-basic)
|
||||
* [Template usage](#template-usage)
|
||||
* [input](#input)
|
||||
* [hidden](#hidden)
|
||||
* [label](#label)
|
||||
* [image](#image)
|
||||
* [select](#select)
|
||||
* [item](#item)
|
||||
* [items](#items)
|
||||
* [optgroup](#optgroup)
|
||||
* [checkbox](#checkbox)
|
||||
* [radio](#radio)
|
||||
* [textarea](#textarea)
|
||||
* [button](#button)
|
||||
* [link](#link)
|
||||
* [checkboxes](#checkboxes)
|
||||
* [radios](#radios)
|
||||
* [file](#file)
|
||||
* [ul](#ul)
|
||||
* [ol](#ol)
|
||||
* [pagination](#pagination)
|
||||
* [table](#table)
|
||||
* [tablehead](#tablehead)
|
||||
* [tablebody](#tablebody)
|
||||
* [tablefooter](#tablefooter)
|
||||
* [tablerows](#tablerows)
|
||||
* [cells](#cells)
|
||||
* [cssbox](#cssbox)
|
||||
* [How to add a new css into the cssbox?](#how-to-add-a-new-css-into-the-cssbox)
|
||||
* [jsbox](#jsbox)
|
||||
* [How to add a new JavaScript into the cssbox?](#how-to-add-a-new-javascript-into-the-cssbox)
|
||||
* [jscodebox](#jscodebox)
|
||||
* [Template Customization](#template-customization)
|
||||
* [Set a default class](#set-a-default-class)
|
||||
* [Set a custom pattern](#set-a-custom-pattern)
|
||||
* [Pattern-Variables inside the code](#pattern-variables-inside-the-code)
|
||||
* [Custom attribute](#custom-attribute)
|
||||
* [Methods](#methods)
|
||||
* [useBootstrap5](#usebootstrap5)
|
||||
* [Note: If we want to use the css box, then we need to add to our view the next code](#note-if-we-want-to-use-the-css-box-then-we-need-to-add-to-our-view-the-next-code)
|
||||
* [useBootstrap4](#usebootstrap4)
|
||||
* [Note: If we want to use the css box, then we need to add to our view the next code](#note-if-we-want-to-use-the-css-box-then-we-need-to-add-to-our-view-the-next-code-1)
|
||||
* [useBootstrap3](#usebootstrap3)
|
||||
* [addCss](#addcss)
|
||||
* [addJS](#addjs)
|
||||
* [addJSCode](#addjscode)
|
||||
* [Public Fields](#public-fields)
|
||||
* [$pattern](#pattern)
|
||||
* [$defaultClass](#defaultclass)
|
||||
* [$customAttr](#customattr)
|
||||
* [Creating a new pattern](#creating-a-new-pattern)
|
||||
* [1- Adding a new pattern](#1--adding-a-new-pattern)
|
||||
* [2- Creating a new method](#2--creating-a-new-method)
|
||||
* [3- Creating a new parent Method (container method)](#3--creating-a-new-parent-method-container-method)
|
||||
* [4- Advanced](#4--advanced-)
|
||||
* [Version history](#version-history)
|
||||
<!-- TOC -->
|
||||
|
||||
## Usage
|
||||
|
||||
1. This library requires eftec/bladeone. You could install via Composer in the root folder of your project as
|
||||
|
||||
> composer require eftec/bladeonehtml
|
||||
|
||||
2. And you should extend the class as follows (BladeOneHtml is a Trait)
|
||||
|
||||
```php
|
||||
include "vendor/autoload.php";
|
||||
|
||||
use eftec\bladeone\BladeOne;
|
||||
use eftec\bladeonehtml\BladeOneHtml;
|
||||
|
||||
class myBlade extends BladeOne {
|
||||
use BladeOneHtml;
|
||||
}
|
||||
|
||||
$blade=new myBlade();
|
||||
|
||||
// for our example:
|
||||
$myvalue=@$_REQUEST['myform'];
|
||||
echo $blade->run("exampleview", ['myvalue'=>$myvalue]);
|
||||
```
|
||||
|
||||
3. Create a folders called 📁 "\views" and 📁 "\compiles"
|
||||
4. Inside views, creates the next file 📄 "\views\exampleview.blade.php"
|
||||
|
||||
```html
|
||||
<body>
|
||||
@form()
|
||||
@input(type="text" name="myform" value=$myvalue)
|
||||
@button(type="submit" value="Send")
|
||||
@endform()
|
||||
</body>
|
||||
```
|
||||
|
||||
$blade=new myBlade();
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## Template basic
|
||||
|
||||
This library adds a new set of tags for the template. The tags uses named arguments, so it is easily configurable.
|
||||
|
||||
> @<tag>(argument1="value" argument2='value' argument3=value argument4=$variable argument5=function(), argument6="aaa $aaa")
|
||||
|
||||
This library uses the native html arguments but some arguments are special
|
||||
|
||||
| Argument | Description | example |
|
||||
|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|
|
||||
| text | It adds a content between the tags. **The inner value is always un-quoted.** | @tag(text="hello") -> <tag>hello</tag> |
|
||||
| pre | It adds a content before the tag | @tag(pre="hello") -> hello<tag></tag> |
|
||||
| post | It adds a content after the tag | @tag(post="hello") -> <tag></tag>hello |
|
||||
| between | It adds a content between the tags (it works similar than text) | @tag(between="hello") -> <tag>hello</tag> |
|
||||
| value | Usually it works as the normal "**value**" of html but it also could works differently (in @textarea works like **text**) | @tag(value="hello") -> < tag value="hello"></tag> |
|
||||
| values | Some components needs a list of object/arrays. This argument is used to sets the list of values | @tag(values=$countries) |
|
||||
| alias | Some components needs or use a list of object/array. This argument is to reference any row inside the list. If **values** is set and **alias** is missing, then it creates a new alias called values+"Row". | @tag($values=$countries alias=$country)<br />@tag($values=$countries ) **it asumes alias=$countriesRow** |
|
||||
| optgroup | The tag @select could list grouped elements. This argument is used to set the grouping | @tag($values=$countries alias=$country @optgroup=$country->continent) |
|
||||
|
||||
Let's say the next example
|
||||
|
||||
```
|
||||
@input(value="hello world" type="text" )
|
||||
```
|
||||
|
||||
It is rendered as
|
||||
|
||||
```
|
||||
<input value="hello world" type="text" />
|
||||
```
|
||||
|
||||
If the tag uses a variable of function, then this view
|
||||
|
||||
```
|
||||
@input(value=$hello type="text" )
|
||||
```
|
||||
|
||||
Is converted into
|
||||
|
||||
``` // the
|
||||
<input value="<?php echo $this->e($hello);?>" type="text" />
|
||||
```
|
||||
|
||||
The method $this->e is used to escape the method.
|
||||
|
||||
> Note: This library allows any tag, even custom tags (but only if they don't enter in conflict with the special tags, see table)
|
||||
>
|
||||
> @input(value="hello world" type="text" mycustomtag="hi" )
|
||||
>
|
||||
> Is converted into
|
||||
````html
|
||||
<input value="hello world" type="text" mycustomtag="hi" />
|
||||
````
|
||||
|
||||
|
||||
|
||||
## Template usage
|
||||
|
||||
### input
|
||||
|
||||
It shows an input HTML.
|
||||
|
||||
Basic example:
|
||||
|
||||
```html
|
||||
@input(id="id1" value="hello world$somevar" type="text" )
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
### hidden
|
||||
|
||||
It generates a hidden field
|
||||
|
||||
Basic example:
|
||||
|
||||
```
|
||||
@hidden(name="id1" value="hello world$somevar" )
|
||||
```
|
||||
|
||||
### label
|
||||
|
||||
It shows a label html
|
||||
|
||||
```html
|
||||
@label(for="id1" text="hello world:")
|
||||
```
|
||||
|
||||

|
||||
|
||||
### image
|
||||
|
||||
It shows an image
|
||||
|
||||
```
|
||||
@image(src="https://via.placeholder.com/350x150")
|
||||
```
|
||||
|
||||

|
||||
|
||||
### select
|
||||
|
||||
It shows a select (dropdown list) html object
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
@select(id="aaa" value=$selection values=$countries alias=$country)
|
||||
@item(value='aaa' text='hello world')
|
||||
@item(value='aaa' text='hello world')
|
||||
@item(value='aaa' text='hello world')
|
||||
@items( id="chkx" value=$country->id text=$country->name)
|
||||
@endselect
|
||||
```
|
||||
|
||||
> Note 1: @items requires the arguments values in the parent (@select) and the arguments **value** (the selectable value) and **text** (the visible value)
|
||||
> Note 2: @items requires an **id**, assigned in the same tag or in the parent tag (in this case, the parent is @select)
|
||||
> Note 3: By standard, the argument **id** must be unique.
|
||||
|
||||

|
||||
|
||||
### item
|
||||
|
||||
**@item** is a utility tag used inside other tags. This behaves depending on of their parent tag. It adds a simple
|
||||
line/row to the parent object.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
@select()
|
||||
@item(value='aaa' text='hello world')
|
||||
@endselect
|
||||
|
||||
```
|
||||
|
||||
It renders
|
||||
|
||||
```
|
||||
<select>
|
||||
<option value="aaa">hello world</option>
|
||||
</select>
|
||||
```
|
||||
|
||||
### items
|
||||
|
||||
**@items** is a utilitarian tag used inside some tags. This behaves depending on of their parent tag. It adds a
|
||||
multiples lines/rows to the parent object using the tag **values**
|
||||
|
||||
> Note: This tag requires some arguments:
|
||||
>
|
||||
> * the parent(or this tag) requires the tag **values**
|
||||
> * the parent requires the tag **value** It indicates the current selection (if any)
|
||||
> * the parent(or this tag) requires the tag **alias** If alias is missing then it uses the name of values + "Row", i.e. values=product -> alias= productRow
|
||||
> * the parent(or this tag) requires the tag **id**
|
||||
> * The rendered "id" will be generated using this id+"_"+"id of the row". i.e. id="idproduct" => idproduct_0, idproduct_1
|
||||
> * Why? It is because the id must be unique (html specs)
|
||||
|
||||
Example, if $countries is a list of objects then :
|
||||
|
||||
```
|
||||
@select(id="aaa" value=$selection values=$countries alias=$country)
|
||||
@items( id="chkx" value=$country->id text=$country->name)
|
||||
@endselect
|
||||
```
|
||||
|
||||
If $countries is a list of arrays then:
|
||||
|
||||
```
|
||||
@select(id="aaa" value=$selection values=$countries alias=$country)
|
||||
@items( id="chkx" value=$country['id'] text=$country['name'])
|
||||
@endselect
|
||||
```
|
||||
|
||||
|
||||
|
||||
Inside the tag items, you could use the next variables
|
||||
|
||||
| variable (where values is the variable used) | Specification |
|
||||
|----------------------------------------------------------|-----------------------------------------------------------------------|
|
||||
| **$values**OptGroup | It stores the current optgroup (if any). Example: $productOptGroup |
|
||||
| **$values**Key | It indicates the current key of the current row. Example: $productKey |
|
||||
| $alias (if not alias is set then it uses **$values**Row) | The current row of the variable. Example: $productRow |
|
||||
|
||||
### optgroup
|
||||
|
||||
It starts an optional group (select)
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
@select(id="aaa" value=$selection values=$countries alias=$country)
|
||||
@optgroup(label="group1")
|
||||
@item(value='aaa' text='hello world')
|
||||
@item(value='aaa' text='hello world')
|
||||
@item(value='aaa' text='hello world')
|
||||
@endoptgroup
|
||||
@endselect
|
||||
```
|
||||
|
||||
> Note: this tag must be ended with the tag @endoptgroup
|
||||
|
||||

|
||||
|
||||
### checkbox
|
||||
|
||||
It adds a single checkbox
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
@checkbox(id="idsimple" value="1" checked="1" post="it is a selection")
|
||||
```
|
||||
|
||||

|
||||
|
||||
### radio
|
||||
|
||||
It adds a single radio button
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
@radio(id="idsimple" value="1" checked="1" post="it is a selection")
|
||||
```
|
||||
|
||||

|
||||
|
||||
### textarea
|
||||
|
||||
It draws a text area.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
@textarea(id="aaa" value="3333 3333 aaa3333 ")
|
||||
```
|
||||
|
||||

|
||||
|
||||
### button
|
||||
|
||||
It draws a button
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
@button(value="click me" type="submit" class="test" onclick='alert("ok")')
|
||||
```
|
||||
|
||||

|
||||
|
||||
### link
|
||||
|
||||
It adds a hyperlink
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
@link(href="https://www.google.cl" text="context")
|
||||
```
|
||||
|
||||

|
||||
|
||||
### checkboxes
|
||||
|
||||
It shows a list of checkboxes
|
||||
|
||||
```
|
||||
@checkboxes(id="checkbox1" value=$selection alias=$country)
|
||||
@item(id="aa1" value='aaa' text='hello world' post="<br>")
|
||||
@item(id="aa2" value='aaa' text='hello world2' post="<br>")
|
||||
@items(values=$countries value='id' text='name' post="<br>")
|
||||
@endcheckboxes
|
||||
```
|
||||
|
||||

|
||||
|
||||
### radios
|
||||
|
||||
It shows a list of radio buttons
|
||||
|
||||
```
|
||||
@radios(id="radios1" name="aaa" value=$selection alias=$country)
|
||||
@item(value='aaa' text='hello world' post="<br>")
|
||||
@item(value='aaa' text='hello world2' post="<br>")
|
||||
@items(values=$countries value='id' text='name' post="<br>")
|
||||
@endradios
|
||||
```
|
||||
|
||||

|
||||
|
||||
### file
|
||||
|
||||
It generates a file input value
|
||||
|
||||
```
|
||||
@file(name="file" value="123.jpg" post="hello world")
|
||||
```
|
||||
|
||||
> Note: it also renders a hidden file with name "name"+"_file" with the original value
|
||||
|
||||

|
||||
|
||||
### ul
|
||||
|
||||
It generates an unsorted list
|
||||
|
||||
```
|
||||
@ul(id="aaa" value=$selection values=$countries alias=$country)
|
||||
@item(value='aaa' text='hello world')
|
||||
@item(value='aaa' text='hello world')
|
||||
@item(value='aaa' text='hello world')
|
||||
@items(value=$country->id text=$country->name)
|
||||
@endul
|
||||
```
|
||||
|
||||

|
||||
|
||||
### ol
|
||||
|
||||
It generates a sorted list
|
||||
|
||||
```
|
||||
@ol(id="aaa" value=$selection values=$countries alias=$country)
|
||||
@item(value='aaa' text='hello world')
|
||||
@item(value='aaa' text='hello world')
|
||||
@item(value='aaa' text='hello world')
|
||||
@items(value=$country->id text=$country->name)
|
||||
@endol
|
||||
```
|
||||
|
||||

|
||||
|
||||
### pagination
|
||||
|
||||
It generates a pagination. It requires bootstrap3, bootstrap4 or bootstrap5.
|
||||
|
||||
You can find an example at [examples/examplepagination.php](examples/examplepagination.php)
|
||||
|
||||
PHP code
|
||||
|
||||
```php
|
||||
$current=isset($_GET['_page']) ? $_GET['_page'] : 1;
|
||||
echo $blade->run("examplepagination",
|
||||
['totalpages'=>count($products)
|
||||
,'current'=>$current
|
||||
,'pagesize'=>10
|
||||
,'products'=>$items
|
||||
]);
|
||||
```
|
||||
|
||||
Template
|
||||
|
||||
```html
|
||||
@pagination(numpages=$totalpages current=$current pagesize=$pagesize urlparam='_page')
|
||||
```
|
||||
|
||||
> Note: The page is base 1.
|
||||
> Note: the argument urlparam is used to build the link (domain.dom/web.php?_page=999)
|
||||
|
||||
You can change the name of the buttons **prev** and **next** as follows:
|
||||
|
||||
```php
|
||||
$this->setTranslation(['pagination'=>['prev'=>'<<>','next'=>'>']]);
|
||||
```
|
||||
|
||||

|
||||
|
||||
### table
|
||||
|
||||
It renders a table
|
||||
|
||||
```
|
||||
@table(class="table" values=$countries alias=$country border="1")
|
||||
@tablehead
|
||||
@cell(text="id")
|
||||
@cell(text="cod")
|
||||
@cell(text="name")
|
||||
@endtablehead
|
||||
@tablebody(id='hello world' )
|
||||
@tablerows(style="background-color:azure")
|
||||
@cell(text=$country->id style="background-color:orange")
|
||||
@cell(text=$country->cod )
|
||||
@cell(text=$country->name)
|
||||
@endtablerows
|
||||
@endtablebody
|
||||
@tablefooter
|
||||
@cell(text="id" colspan="3")
|
||||
@endtablefooter
|
||||
@endtable
|
||||
```
|
||||
|
||||

|
||||
|
||||
#### tablehead
|
||||
|
||||
It renders the header of the table (optional). Each cell added inside it, is rendered as "th" HTML tag
|
||||
|
||||
#### tablebody
|
||||
|
||||
It renders the body of the table (optional). Each cell added inside the table is rendered as "td" HTML tag
|
||||
|
||||
#### tablefooter
|
||||
|
||||
It renders the footer of the table (optional). Each cell added inside it, is rendered as "th" HTML tag
|
||||
|
||||
#### tablerows
|
||||
|
||||
It generates a row inside the body
|
||||
|
||||
#### cells
|
||||
|
||||
It renders a cell inside the tablehead,tablebody (tablerows) or tablefooter
|
||||
|
||||
### cssbox
|
||||
|
||||
It renders and css added into the box
|
||||
|
||||
```html
|
||||
<head>
|
||||
@cssbox
|
||||
</head>
|
||||
```
|
||||
|
||||
#### How to add a new css into the cssbox?
|
||||
|
||||
Using the method addCss($css,$name)
|
||||
|
||||
```php
|
||||
$this->addCss('<link rel="stylesheet" href="mystyle.css">','mystyle');
|
||||
$this->addCss('css/stylename.css');
|
||||
```
|
||||
|
||||
**$css** could be a link or a link tag
|
||||
|
||||
**$name** is optional but it avoids to add duplicates. If we add a new CSS with the same name as
|
||||
a previous one, then it is ignored.
|
||||
|
||||
### jsbox
|
||||
|
||||
It renders all JavaScript links added to the box
|
||||
|
||||
```html
|
||||
<body>
|
||||
<!-- our page -->
|
||||
@jsbox
|
||||
</body>
|
||||
```
|
||||
|
||||
#### How to add a new JavaScript into the cssbox?
|
||||
|
||||
Using the method addJs($script,$name)
|
||||
|
||||
```php
|
||||
$this->addJs('<script src="js/jquery.js"></script>','jquery');
|
||||
```
|
||||
|
||||
### jscodebox
|
||||
|
||||
```html
|
||||
<body>
|
||||
<!-- our page -->
|
||||
@jsbox <!-- we could load jquery here -->
|
||||
@jscodebox(ready)
|
||||
</body>
|
||||
```
|
||||
|
||||
This code adds the tags < script > automatically.
|
||||
|
||||
The argument **ready** indicates if we want to execute the function when the document is ready.
|
||||
|
||||
How to add a new JavaScript code into the **jscodebox**?
|
||||
|
||||
```php
|
||||
$blade->addJsCode('alert("hello");');
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Template Customization
|
||||
|
||||
**BladeOneHtml** allows to modify the tags used and to set a default classes for each class.
|
||||
|
||||
You can set a default class and tags for Bootstrap 3/4/5 using the next method (pick only one).
|
||||
|
||||
```php
|
||||
// if true then it loads the css and js from a cdn into the css and jsbox so it requires @cssbox and @jsbox
|
||||
$blade->useBootstrap5(true);
|
||||
// if true then it loads the css and js from a cdn into the css and jsbox so it requires @cssbox and @jsbox
|
||||
$blade->useBootstrap4(true);
|
||||
// if true then it loads the css and js from a cdn into the css and jsbox so it requires @cssbox and @jsbox
|
||||
$blade->useBootstrap3(true);
|
||||
```
|
||||
|
||||
|
||||
|
||||
Or you could create your own tags and classes
|
||||
|
||||
### Set a default class
|
||||
|
||||
```php
|
||||
$blade->defaultClass[$tagname]='default class';
|
||||
```
|
||||
|
||||
### Set a custom pattern
|
||||
|
||||
```php
|
||||
$blade->pattern['nametag']='pattern';
|
||||
```
|
||||
|
||||
Where nametag could be as follows
|
||||
|
||||
| Name | Description | Example | Code |
|
||||
|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|------------------------------------------------------|
|
||||
| nametag | It uses the pattern to use when the tag is used | input | {{pre}}<input{{inner}} >{{between}}< /input>{{post}} |
|
||||
| nametag_empty | The system uses this pattern if the content (between/text) is empty or not set (a self close tag). If not set, then the system uses **nametag** even if the content is empty | input_empty | {{pre}}< input{{inner}} />{{post}} |
|
||||
| nametag_item | The system uses this pattern for tags @item and @items | select_item | < option{{inner}} >{{between}}< /option> |
|
||||
| nametag_end | It uses this pattern when the tag must be closed | form_end | < /form> |
|
||||
|
||||
#### Pattern-Variables inside the code
|
||||
|
||||
| variable | explanation | Escaped (*) |
|
||||
|-------------|--------------------------------------------------------------------------------------|-------------------------------------------------------------------|
|
||||
| {{pre}} | The code before the tag : **pre** <tag ></tag> | no |
|
||||
| {{post}} | The code after the tag : < tag ></tag> **post** | no |
|
||||
| {{inner}} | The attributes inside the tag : < tag **inside** > </tag> | yes |
|
||||
| {{between}} | The content between the tag : < tag >**between**</tag> | By default this value is escaped <br />but it could be un-escaped |
|
||||
| {{id}} | The id attribute (it is also included in {{inner}}): < tag **id** > </tag> | yes |
|
||||
| {{name}} | The name attribute (it is also included in {{inner}}): < tag **name** > </tag> | yes |
|
||||
|
||||
Example of a normal tag:
|
||||
|
||||
```php
|
||||
$blade->pattern['input']='{{pre}}<input{{inner}} >{{between}}</input>{{post}}';
|
||||
```
|
||||
|
||||
> Note :(*) What is escaped?. For example the text "<hello world>", if it escaped, it is displayed as "&lt;hello&gt;"
|
||||
|
||||
#### Custom attribute
|
||||
|
||||
It is possible to add a custom attribute that it could be used inside a pattern.
|
||||
|
||||
For example, let's add the custom tag called **customtag**
|
||||
|
||||
```php
|
||||
$blade->customAttr['customtag']='This attr is missing!';
|
||||
$blade->pattern['alert']='{{pre}}<div {{inner}}><h1>{{customtag}}</h1>{{between}}</div>{{post}}';
|
||||
```
|
||||
|
||||
And in the view
|
||||
|
||||
```html
|
||||
@alert(text="hi there" class="alert-danger" customtag="it is a custom tag")<br>
|
||||
@alert(text="hi there" class="alert-danger" )<br>
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
The library has a lit of methods that they could be used to initialize and configure the library. They are optionals.
|
||||
|
||||
### useBootstrap5
|
||||
|
||||
It sets the patterns and classes to be compatible with bootstrap 4.
|
||||
|
||||
if argument is true, then it adds the CSS to the **css box** from the CDN
|
||||
|
||||
Our code
|
||||
|
||||
```php
|
||||
$blade->useBootstrap5(true);
|
||||
```
|
||||
|
||||
#### Note: If we want to use the css box, then we need to add to our view the next code
|
||||
|
||||
```html
|
||||
<header>
|
||||
@cssbox
|
||||
</header>
|
||||
```
|
||||
|
||||
|
||||
|
||||
### useBootstrap4
|
||||
|
||||
It sets the patterns and classes to be compatible with bootstrap 4.
|
||||
|
||||
if argument is true, then it adds the CSS to the **css box** from the CDN
|
||||
|
||||
Our code
|
||||
|
||||
```php
|
||||
$blade->useBootstrap4(true);
|
||||
```
|
||||
|
||||
#### Note: If we want to use the css box, then we need to add to our view the next code
|
||||
|
||||
```html
|
||||
<header>
|
||||
@cssbox
|
||||
</header>
|
||||
```
|
||||
|
||||
|
||||
|
||||
### useBootstrap3
|
||||
|
||||
It sets the patterns and classes to be compatible with bootstrap 3.
|
||||
|
||||
if argument is true, then it adds the CSS to the **css box** from the CDN
|
||||
|
||||
```php
|
||||
$blade->useBootstrap3(true);
|
||||
```
|
||||
|
||||
### addCss
|
||||
|
||||
It adds a CSS to the **css box**
|
||||
|
||||
```php
|
||||
$this->addCss('css/datepicker.css','datepicker');
|
||||
```
|
||||
|
||||
### addJS
|
||||
|
||||
It adds a javascript link to the **js box**
|
||||
|
||||
```php
|
||||
$this->addJs('<script src="js/jquery.js"></script>','jquery');
|
||||
```
|
||||
|
||||
### addJSCode
|
||||
|
||||
It adds a javascript code to the **js box**
|
||||
|
||||
```php
|
||||
$blade->addJsCode('alert("hello");');
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Public Fields
|
||||
|
||||
It is the list of public fields of the class. The fields are public because for performance purpose (versus to use setter and getters)
|
||||
|
||||
### $pattern
|
||||
|
||||
It stores the list of patterns used by the code
|
||||
|
||||
```php
|
||||
$this->pattern['sometag']='{{pre}}<tag {{inner}}>{{between}}</tag>{{post}}';
|
||||
|
||||
```
|
||||
|
||||
> Note: see "Pattern-Variable inside the code" to see the list of pattern-variables
|
||||
|
||||
### $defaultClass
|
||||
|
||||
The default CSS class added to a specific tag.
|
||||
|
||||
```php
|
||||
$this->defaultClass['sometag']='classred classbackgroundblue';
|
||||
```
|
||||
|
||||
### $customAttr
|
||||
|
||||
It adds a custom adds that it could be used together with $this->pattern
|
||||
|
||||
```php
|
||||
$this->customAttr['customtag']='XXXXX'; // So we could use the tag {{customtag}}. 'XXXXX' is the default value
|
||||
```
|
||||
|
||||
> The custom attribute always removes the quotes and double quotes, so if our value is "hello" -> hello
|
||||
|
||||
## Creating a new pattern
|
||||
|
||||
It is possible to add a new pattern by extending the PHP class.
|
||||
|
||||
#### 1- Adding a new pattern
|
||||
|
||||
```
|
||||
$this->pattern['mynewtag']='<mycustomtag {{inner}}>{{between}}</mycustomtag>';
|
||||
```
|
||||
|
||||
#### 2- Creating a new method
|
||||
|
||||
You could create a new PHP class or trait and extend our class. Inside this new structure, you must add a new method with the next structure
|
||||
|
||||
Using a new class
|
||||
|
||||
```php
|
||||
use eftec\bladeone\BladeOne;
|
||||
use eftec\bladeonehtml\BladeOneHtml;
|
||||
|
||||
class MyBlade extends BladeOne {
|
||||
use BladeOneHtml;
|
||||
}
|
||||
class MyClass extends MyBlade {
|
||||
protected function compileMyNewTag($expression) { // the method must be called "compile" + your name of tag.
|
||||
$args = $this->getArgs($expression); // it separates the values of the tags
|
||||
$result = ['', '', '', '']; // inner, between, pre, post
|
||||
// your custom code here
|
||||
return $this->render($args, 'mynewtag', $result); // we should indicate to use our pattern.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Using a trait (recommended, why? It is because trait are more flexible)
|
||||
|
||||
```php
|
||||
trait MyTrait {
|
||||
protected function compileMyNewTag($expression) { // the method must be called "compile" + your name of tag.
|
||||
$args = $this->getArgs($expression); // it separates the values of the tags
|
||||
$result = ['', '', '', '']; // inner, between, pre, post
|
||||
// your custom code here
|
||||
return $this->render($args, 'mynewtag', $result); // we should indicate to use our pattern.
|
||||
}
|
||||
}
|
||||
|
||||
class MyClass extends BladeOne {
|
||||
use BladeOneHtml;
|
||||
use MyTrait; // <-- our trait
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 3- Creating a new parent Method (container method)
|
||||
|
||||
For creating a parent method, you must push a new value inside $this->htmlItem. You can store whatever you want to.
|
||||
|
||||
```php
|
||||
$this->pattern['mynewtag']='<mycustomtag {{inner}}>{{between}}';
|
||||
```
|
||||
|
||||
```php
|
||||
protected function compileMyNewTag($expression) {
|
||||
$args = $this->getArgs($expression); // it loads and separates the arguments.
|
||||
$this->htmlItem[] = ['type' => 'mynewtag','value' => @$args['value']
|
||||
];
|
||||
$result = ['', '', '', '']; // inner, between, pre, post
|
||||
//unset($args['value']); // we could unset values that we don't want to be rendered.
|
||||
return $this->render($args, 'select', $result);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
> Our objective is to render PHP code, not to evaluate a code. For example, if $args['somearg']=$variable, then our value is $variable (as text), no matter the real value of the variable.
|
||||
|
||||
You must also create a method to end the container, and we must also add a new pattern.
|
||||
|
||||
```php
|
||||
$this->pattern['mynewtag_end']='</mycustomtag>';
|
||||
```
|
||||
|
||||
```php
|
||||
protected function compileEndNewTag() {
|
||||
$parent = @\array_pop($this->htmlItem); // remove the element from the stack
|
||||
if (\is_null($parent) || $parent['type']!=='newtag') { // if no element in the stack or it's a wrong one then error
|
||||
$this->showError("@endnewtag", "Missing @initial tag", true);
|
||||
}
|
||||
// our code
|
||||
return $this->pattern[$parent['type'] . '_end']; // renders the element of the stack
|
||||
}
|
||||
```
|
||||
|
||||
Our items could know if they are inside a tag with the next operation
|
||||
|
||||
```php
|
||||
$parent = \end($this->htmlItem);
|
||||
```
|
||||
|
||||
#### 4- Advanced
|
||||
|
||||
We could create a component that requires CSS and JavaScript.
|
||||
|
||||
For example a date picker.
|
||||
|
||||
```php
|
||||
protected function compileDatePicker($expression) {
|
||||
$args = $this->getArgs($expression); // it loads and separates the arguments.
|
||||
\array_push($this->htmlItem, ['type' => 'mynewtag','value' => @$args['value']]);
|
||||
$result = ['', '', '', '']; // inner, between, pre, post
|
||||
if(!isset($args['id'])) {
|
||||
$this->showError("@datepicker", "Missing @id tag", true);
|
||||
}
|
||||
$this->addJs('<script src="js/jquery.js"></script>','jquery'); // our script needs jquery (if it is not loaded)
|
||||
$this->addCss('css/datepicker.css','datepicker');
|
||||
$this->addjscode('$(.'.$args['id'].').datepicker();');
|
||||
|
||||
//unset($args['value']); // we could unset values that we don't want to be rendered.
|
||||
return $this->render($args, 'select', $result);
|
||||
}
|
||||
```
|
||||
|
||||
> Note: It's better to add the library of jQuery and date picker once in our code
|
||||
|
||||
|
||||
|
||||
## Version history
|
||||
* 2.5 2024-12-31
|
||||
* Updated to PHP 8.4
|
||||
* 2.4 2024-03-02
|
||||
* Updating dependency to PHP 7.4. The extended support of PHP 7.2 ended 3 years ago.
|
||||
* Added more type hinting in the code
|
||||
* 2.3.2 2023-01-31
|
||||
* a typo in pagination
|
||||
* 2.3.1 2023-01-31
|
||||
* fixed a problem with pagination.
|
||||
* some cleanups
|
||||
* update dependencies.
|
||||
* 2.3 2022-02-04
|
||||
* Now this library is compatible with PHP 7.2 and higher.
|
||||
* Some cleanups and type hinting (return methods)
|
||||
* 2.2 2021-12-11
|
||||
* fixed a problem with optgroup and when the argument is an associative array.
|
||||
* 2.1 2021-10-01
|
||||
* Added support for Bootstrap 5.0
|
||||
* Updated Bootstrap CDNs
|
||||
* added tags @container, @row, @col
|
||||
* 2.0 2021-09-24
|
||||
* Dropped support for PHP 5.x. Updated support for BladeOne 4.0
|
||||
* 1.8.1 2021/07/03
|
||||
* It solves a problem when the argument is defined as id="somevalue$id"
|
||||
* 1.8 2021/06/09
|
||||
* @checkbox and @radio now works with variables. The element is checked only if the value is not null, empty or zero.
|
||||
* 1.7.1 2021/02/06
|
||||
* @item now marks the value "checked" or "selected" if the values is equals to the current value of the parent object
|
||||
* Bootstrap 4 **CDN** now it uses the version 4.6
|
||||
* for @item and @items, the field name and **idname** are created automatically. If id is set, then it uses it.
|
||||
* 1.7 2021/01/12
|
||||
* @button now considers value as the value of argument while text the visual content.
|
||||
* It also uses in_array instead of isset().
|
||||
* Compatible with PHP 8.x
|
||||
* 1.6.1 2020/08/31
|
||||
* Pagination now it has "first" and "last" buttons.
|
||||
* 1.6 2020/08/30
|
||||
* Added tag @pagination
|
||||
* Added the method setTranslationControl() and getTranslationControl()
|
||||
* 1.5 2020/06/07
|
||||
* Added a new optional argument to processArgs() and render();
|
||||
* Added unit test.
|
||||
* 1.4 2020/05/02
|
||||
* now it allows empty arguments. It requires BladeOne 3.43 or higher.
|
||||
* added unit test.
|
||||
* 1.3 2020/04/22
|
||||
* added method useBootstrap3()
|
||||
* added default class for textarea in useBootstrap4()
|
||||
* 1.2 2020/04/21
|
||||
* tag @@alert()
|
||||
* fixed: @@items() now it keeps the selection
|
||||
* tag @@cssbox, @@jsbox and @jscodebox
|
||||
* method useBootstrap4($cdn=false) has a new argument
|
||||
* 1.1 2020/04/21
|
||||
* Method isVariablePHP() moved to BladeOne
|
||||
* Update LICENSE.
|
||||
* Added more documentation.
|
||||
* 1.0 2020-04-20 First version
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "eftec/bladeonehtml",
|
||||
"description": "The standalone version Blade Template Engine from Laravel in a single php file",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"blade",
|
||||
"template",
|
||||
"view",
|
||||
"php",
|
||||
"templating"
|
||||
],
|
||||
"homepage": "https://github.com/EFTEC/BladeOneHtml",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jorge Patricio Castro Castillo",
|
||||
"email": "jcastro@eftec.cl"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.4",
|
||||
"ext-json": "*",
|
||||
"eftec/bladeone": "^4.12",
|
||||
"eftec/messagecontainer": "^2.8"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"eftec\\bladeonehtml\\": "lib/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"eftec\\tests\\": "test/"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5.11"
|
||||
}
|
||||
}
|
||||
+1226
File diff suppressed because it is too large
Load Diff
+3
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
include __DIR__."/../vendor/autoload.php";
|
||||
+282
@@ -0,0 +1,282 @@
|
||||
<?php /** @noinspection PhpUnhandledExceptionInspection */
|
||||
/** @noinspection HtmlDeprecatedAttribute */
|
||||
/** @noinspection HtmlExtraClosingTag */
|
||||
/** @noinspection HtmlRequiredAltAttribute */
|
||||
/** @noinspection HtmlUnknownAttribute */
|
||||
/** @noinspection HtmlUnknownTarget */
|
||||
|
||||
/** @noinspection CheckTagEmptyBody */
|
||||
|
||||
namespace eftec\tests;
|
||||
|
||||
use eftec\bladeone\BladeOne;
|
||||
|
||||
use eftec\bladeonehtml\BladeOneHtml;
|
||||
use eftec\MessageContainer;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class myBlade extends BladeOne {
|
||||
use BladeOneHtml;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class clientTest
|
||||
* @package eftec\tests
|
||||
* @copyright Jorge Castro Castillo
|
||||
* 2020-05-02
|
||||
*/
|
||||
class clientTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var myBlade
|
||||
*/
|
||||
private $myBlade;
|
||||
|
||||
public function assertEqualsNR($expected, $v): void
|
||||
{
|
||||
$expected=str_replace(["\r\n","\n"],["",""],$expected);
|
||||
$v=str_replace(["\r\n","\n"],["",""],$v);
|
||||
self::assertEquals($expected,$v);
|
||||
}
|
||||
|
||||
|
||||
public function setUp() : void
|
||||
{
|
||||
$this->myBlade=new myBlade();
|
||||
$this->myBlade->setMode(BladeOne::MODE_DEBUG);
|
||||
|
||||
}
|
||||
|
||||
public function testBox(): void
|
||||
{
|
||||
$this->myBlade->addJs('<script src="domain.dom/js.js">','alert');
|
||||
$this->myBlade->addJs('<script src="domain.dom/js.js">','alert');
|
||||
$this->myBlade->addJsCode('alert(2);');
|
||||
$this->myBlade->addCss('style123');
|
||||
$template='@jsbox
|
||||
@jscodebox(ready)
|
||||
@cssbox';
|
||||
|
||||
$html='<script src="domain.dom/js.js">
|
||||
<script>
|
||||
alert(2);</script>
|
||||
|
||||
<link rel="stylesheet" href="./style123">';
|
||||
$this->assertEqualsNR( $html,$this->myBlade->runString($template));
|
||||
}
|
||||
|
||||
|
||||
public function testarguments(): void
|
||||
{
|
||||
|
||||
|
||||
$r = 'a1=1 a2="hello world" a2b="hello=world" a3=\'hello world\' a4=$a5 ';
|
||||
self::assertEquals(
|
||||
['a1' => 1, 'a2' => '"hello world"', 'a2b' => '"hello=world"', 'a3' => '\'hello world\'', 'a4' => '$a5']
|
||||
, $this->myBlade->getArgsProxy($r));
|
||||
$r = '1 "hello world" "hello=world" \'hello world\' $a5';
|
||||
self::assertEquals(
|
||||
['1' => null, '"hello world"' => null, '"hello=world"' => null, '\'hello world\'' => null, '$a5' => null]
|
||||
, $this->myBlade->getArgsProxy($r));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function testBasic1(): void
|
||||
{
|
||||
self::assertEquals('abc:<input type="text" idname="hi" id="hi" name="hi" />'
|
||||
,$this->myBlade->runString('@input(type="text" idname="hi" pre="abc:")'));
|
||||
self::assertEquals('<input type="text" />'
|
||||
,$this->myBlade->runString('@input(type="text")'));
|
||||
self::assertEquals('<input type="text" abc="123" cde=\'123\' efg hij="" />'
|
||||
,$this->myBlade->runString('@input(type="text" abc="123" cde=\'123\' efg hij="")'));
|
||||
}
|
||||
public function testCheckbox(): void
|
||||
{
|
||||
$template='@checkbox(id="idsimple" value="1" checked="1" post="it is a selection")';
|
||||
$html='<input type="checkbox" id="idsimple" value="1" checked ></input>it is a selection';
|
||||
self::assertEquals($html,$this->myBlade->runString($template));
|
||||
|
||||
$template='@checkboxes(id="checkbox1" value=$selection alias=$country)
|
||||
@item(id="aa1" value=\'aaa\' text=\'hello world\' post="<br>")
|
||||
@item(id="aa2" value=\'aaa\' text=\'hello world2\' post="<br>")
|
||||
@items(values=$countries value=\'id\' text=\'name\' post="<br>")
|
||||
@endcheckboxes';
|
||||
$html='<div id="checkbox1" value="" >
|
||||
<input type="checkbox" id="aa1" value=\'aaa\' name="aa1" idname="aa1" >hello world</input><br>
|
||||
<input type="checkbox" id="aa2" value=\'aaa\' name="aa2" idname="aa2" >hello world2</input><br>
|
||||
|
||||
</div>';
|
||||
self::assertEquals($html,$this->myBlade->runString($template));
|
||||
}
|
||||
public function testRadio(): void
|
||||
{
|
||||
$template='@radio(id="idsimple" value="1" checked="1" post="it is a selection")';
|
||||
$html='<input type="radio" id="idsimple" value="1" checked ></input>it is a selection';
|
||||
self::assertEquals($html,$this->myBlade->runString($template));
|
||||
|
||||
$template='@radios(id="radios1" name="aaa" value=$selection alias=$country)
|
||||
@item(value=\'aaa\' text=\'hello world\' post="<br>")
|
||||
@item(value=\'aaa\' text=\'hello world2\' post="<br>")
|
||||
@items(values=$countries value=\'id\' text=\'name\' post="<br>")
|
||||
@endradios';
|
||||
$html='<div id="radios1" name="aaa" value="" >
|
||||
<input type="radio" value=\'aaa\' id="radios1" name="radios1" idname="radios1" >hello world</input><br>
|
||||
<input type="radio" value=\'aaa\' id="radios1" name="radios1" idname="radios1" >hello world2</input><br>
|
||||
|
||||
</div>';
|
||||
self::assertEquals($html,$this->myBlade->runString($template));
|
||||
}
|
||||
public function testMisc(): void
|
||||
{
|
||||
$template='@ul(id="aaa" value=$selection values=$countries alias=$country)
|
||||
@item(value=\'aaa\' text=\'hello world\')
|
||||
@items(value=$country->id text=$country->name)
|
||||
@endul
|
||||
@image(src="https://via.placeholder.com/350x150")
|
||||
@label(for="id1" text="hello world:")
|
||||
@hidden(name="id1" value="hello world$somevar" )
|
||||
@alert(text="hi there" class="alert-danger" customtag="it is a custom tag")<br>';
|
||||
$html='<ul id="aaa" value="" >
|
||||
<li value=\'aaa\' id="aaa" name="aaa" idname="aaa" >hello world</li>
|
||||
|
||||
</ul>
|
||||
<img src="https://via.placeholder.com/350x150" ></img>
|
||||
<label for="id1" >hello world:</label>
|
||||
<input name="id1" value="hello world" type=hidden />
|
||||
<div class="alert-danger" customtag="it is a custom tag">hi there</div><br>';
|
||||
self::assertEquals($html,$this->myBlade->runString($template));
|
||||
}
|
||||
public function testTextArea(): void
|
||||
{
|
||||
$template='@textarea(id="aaa" value="3333 3333 aaa3333")';
|
||||
$html='<textarea id="aaa" >3333 3333 aaa3333</textarea>';
|
||||
self::assertEquals($html,$this->myBlade->runString($template));
|
||||
}
|
||||
public function testTable(): void
|
||||
{
|
||||
$template='@table(class="table" values=$countries alias=$country border="1")
|
||||
@tablehead
|
||||
@cell(text="id")
|
||||
@cell(text="cod")
|
||||
@cell(text="name")
|
||||
@endtablehead
|
||||
@tablebody(id=\'hello world\' )
|
||||
@tablerows(style="background-color:azure")
|
||||
@cell(text=$country->id style="background-color:orange")
|
||||
@cell(text=$country->cod )
|
||||
@cell(text=$country->name)
|
||||
@endtablerows
|
||||
@endtablebody
|
||||
@tablefooter
|
||||
@cell(text="id" colspan="3")
|
||||
@endtablefooter
|
||||
@endtable';
|
||||
$html='<table class="table" border="1" >
|
||||
<thead><tr >
|
||||
<th >id</th>
|
||||
<th >cod</th>
|
||||
<th >name</th>
|
||||
</tr></thead>
|
||||
<tbody id=\'hello world\' ></tbody>
|
||||
<tfoot><tr >
|
||||
<td colspan="3" >id</td>
|
||||
</tr></tfoot>
|
||||
</table>';
|
||||
self::assertEquals($html,$this->myBlade->runString($template));
|
||||
}
|
||||
public function testButton(): void
|
||||
{
|
||||
$template='<body>
|
||||
@form()
|
||||
@input(type="text" name="myform" value=$myvalue)
|
||||
@button(type="submit" text="Send")
|
||||
@link(href="https://www.google.cl" text="context")
|
||||
@endform()
|
||||
</body>';
|
||||
$html='<body>
|
||||
<form >
|
||||
<input type="text" name="myform" value="" />
|
||||
<button type="submit" >Send</button>
|
||||
<a href="https://www.google.cl" >context</a>
|
||||
</form>
|
||||
</body>';
|
||||
self::assertEquals($html,$this->myBlade->runString($template));
|
||||
}
|
||||
|
||||
public function testNewVarSelect(): void
|
||||
{
|
||||
self::assertEquals('<select id="aaa" value="" >
|
||||
<option value=\'aaa\' id="aaa" name="aaa" idname="aaa" >hello world</option>
|
||||
<option value=\'aaa\' id="aaa" name="aaa" idname="aaa" >hello world</option>
|
||||
<option value=\'aaa\' id="aaa" name="aaa" idname="aaa" >hello world</option>
|
||||
|
||||
</select>
|
||||
',$this->myBlade->runString('@select(id="aaa" value=$selection values=$countries alias=$country)
|
||||
@item(value=\'aaa\' text=\'hello world\')
|
||||
@item(value=\'aaa\' text=\'hello world\')
|
||||
@item(value=\'aaa\' text=\'hello world\')
|
||||
@items( id="chkx" value=$country->id text=$country->name)
|
||||
@endselect
|
||||
'));
|
||||
}
|
||||
public function testNewVarSelect2(): void
|
||||
{
|
||||
|
||||
self::assertEquals('<select name="frm_Cham__idSensorxyz" label="Sensorxyz" id="frm_Cham__idSensorxyz" value="" >
|
||||
<option value=\'aaa\' id="frm_Cham__idSensorxyz" name="frm_Cham__idSensorxyz" idname="frm_Cham__idSensorxyz" >hello world</option>
|
||||
<option value=\'aaa\' id="frm_Cham__idSensorxyz" name="frm_Cham__idSensorxyz" idname="frm_Cham__idSensorxyz" >hello world</option>
|
||||
<option value=\'aaa\' id="frm_Cham__idSensorxyz" name="frm_Cham__idSensorxyz" idname="frm_Cham__idSensorxyz" >hello world</option>
|
||||
|
||||
</select>
|
||||
',$this->myBlade->runString('@select(name="frm_Cham__idSensor$x" label="Sensor$x" id="frm_Cham__idSensor$x"
|
||||
value=$selection values=$countries alias=$country)
|
||||
@item(value=\'aaa\' text=\'hello world\')
|
||||
@item(value=\'aaa\' text=\'hello world\')
|
||||
@item(value=\'aaa\' text=\'hello world\')
|
||||
@items( id="chkx" value=$country->id text=$country->name)
|
||||
@endselect
|
||||
',['x'=>'xyz']));
|
||||
}
|
||||
public function testNewVar3(): void
|
||||
{
|
||||
$this->myBlade->useBootstrap3();
|
||||
$this->myBlade->useBootstrap3(true);
|
||||
self::assertEquals('<input type="text" class="form-control" />'
|
||||
,$this->myBlade->runString('@input(type="text")'));
|
||||
self::assertEquals('<input type="text" abc="123" cde=\'123\' efg hij="" class="form-control" />'
|
||||
,$this->myBlade->runString('@input(type="text" abc="123" cde=\'123\' efg hij="")'));
|
||||
}
|
||||
|
||||
public function testNewVar4(): void
|
||||
{
|
||||
$this->myBlade->useBootstrap4();
|
||||
$this->myBlade->useBootstrap4(true);
|
||||
self::assertEquals('<input type="text" class="form-control" />'
|
||||
,$this->myBlade->runString('@input(type="text")'));
|
||||
self::assertEquals('<input type="text" abc="123" cde=\'123\' efg hij="" class="form-control" />'
|
||||
,$this->myBlade->runString('@input(type="text" abc="123" cde=\'123\' efg hij="")'));
|
||||
}
|
||||
public function testtc(): void
|
||||
{
|
||||
$pagarray=array('pagination'=>array( 'first' => 'First',
|
||||
'prev' => 'Previous',
|
||||
'next' => 'Next',
|
||||
'last' => 'Last'));
|
||||
self::assertEquals($pagarray,$this->myBlade->getTranslationControl());
|
||||
$this->myBlade->setTranslationControl($pagarray);
|
||||
self::assertEquals($pagarray,$this->myBlade->getTranslationControl());
|
||||
|
||||
|
||||
}
|
||||
public function testmsg(): void
|
||||
{
|
||||
$mc=new MessageContainer();
|
||||
$mc->addItem('msg1','there is an error');
|
||||
$this->myBlade->message($mc);
|
||||
self::assertEquals("<span default='' >there is an error</span>",$this->myBlade->runString("@message(id='msg1' level='error' default='')"));
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Escuela de Formación Técnica Chile SPA
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+864
@@ -0,0 +1,864 @@
|
||||
# MessageContainer
|
||||
It is a Message Container for PHP, similar in functionality **MessageBag** for Laravel. However, this is aimed for
|
||||
speed and usability, and it doesn't have any dependency.
|
||||
|
||||
This class is simple: 2 classes, no dependency and nothing more. You can use in any PHP project.
|
||||
|
||||
[](https://packagist.org/packages/eftec/MessageContainer)
|
||||
[](https://packagist.org/packages/eftec/MessageContainer)
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
|
||||
|
||||
|
||||
## What is the objective?
|
||||
|
||||
This library stores messages (strings) in different lockers and each locker could contain different messages with different levels (error, warning, info and success). The goal of this library:
|
||||
|
||||
* It stores messages depending on an "id", including the severity and message (a simple text).
|
||||
* **The library does not generate an error if the value we want to read does not exist**, So we don't need to use of **isset()** in our code. It also avoids the use of **count()** and **is_array()** in our code, this library already does it for us.
|
||||
* It returns an empty value (not null) if the message does not exist or if there is no message.
|
||||
* It returns an empty array (not null) if the list of messages does not exist
|
||||
* It returns an empty locker (not null) if the locker does not exist.
|
||||
* It is possible to returns the first error or warning at the same time. In this case, if the locker stores an error and a warning, then it returns the error (it has priority).
|
||||
* It is able to return:
|
||||
* all messages stored in some locker or container.
|
||||
* the first message (with or without some level)
|
||||
* the number of messages (for some level)
|
||||
* if the container of locker has error or warning.
|
||||
* **It is as fast as possible**
|
||||
|
||||
It is an example from where we could use it, the validation of a form (this library does not validate or show values it only stores the information)
|
||||
|
||||

|
||||
|
||||
In this example, we have :
|
||||
|
||||
* one **container** (the form)
|
||||
* multiples textboxes (each one is a **locker**)
|
||||
* and each textbox (our lockers) could contain one of more **messages** with different levels (in this case, success or error).
|
||||
|
||||
If we use plain-PHP, we could show some messages of the password:
|
||||
|
||||
```php
|
||||
echo $container['password']['error'];
|
||||
```
|
||||
|
||||
But what if the id password does not contain any message, or if there is no error? of if there is more than error?
|
||||
|
||||
So we could re-define something like that: (but it will still fail if there is more than one error)
|
||||
|
||||
Vanilla PHP:
|
||||
|
||||
```php
|
||||
if (isset($container['password'])) {
|
||||
if(isset($container['password']['error'])) {
|
||||
echo $container['password']['error'];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And with our library
|
||||
|
||||
```php
|
||||
// We could show the first error (or empty if none):
|
||||
echo $container->getLocker('password')->firstError();
|
||||
|
||||
// it shows all errors (or nothing if none):
|
||||
foreach($container->getLocker('password')->allError() as $msg) {
|
||||
echo $msg;
|
||||
}
|
||||
```
|
||||
|
||||
## How to use it
|
||||
|
||||
```php
|
||||
use eftec\MessageContainer;
|
||||
$container=new MessageContainer(); // we create the full lockers
|
||||
$container->addItem('locker1','It is a message','warning'); // we store a message inside "id1"
|
||||
$container->addItem('locker1','It is a message','error'); // we store another message inside "id1"
|
||||
|
||||
// And later, you can process it
|
||||
|
||||
$lastErrorsOrWarnings=$container->get('locker1')->allErrorOrWarning();
|
||||
// it will not crash even if the locker2 does not exists.
|
||||
$lastErrorsOrWarnings2=$container->get('locker2')->allErrorOrWarning();
|
||||
|
||||
```
|
||||
|
||||
## Definitions
|
||||
|
||||
Let's say the next example of container that shows every part of the Container.
|
||||
|
||||

|
||||
|
||||
We have 3 levels of spaces.
|
||||
|
||||
* **Container**. Usually it is unique, and it is defined by our instance of **MessageContainer**.
|
||||
The container could contain from zero to multiples lockers. Each locker is identified by a unique "id".
|
||||
* **Locker**. Every time we add an item, we could create or update a new container.
|
||||
Every locker could contain from zero to many error, warning, info or success and each one could
|
||||
contain from zero to many messages.
|
||||
* Our **messages** or **items** are categorized in 4 levels, error, warning, info and success.
|
||||
Each level could contain one or many messages (or none)
|
||||
|
||||
Messages are leveled as follows
|
||||
|
||||
| id | Description | Example |
|
||||
|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------|
|
||||
| error | The message is an error, and it must be solved. It is our show stopper. | Database is down |
|
||||
| warning | The message is a warning that maybe it could be ignored. However, the class **MessageContainer** could allow to group Error and Warning as the same. | The registry was stored but with warnings |
|
||||
| info | The message is information. For example, to log or debug an operation. | Log is stored |
|
||||
| success | The message is a successful operation | Order Accepted |
|
||||
|
||||
Example #2
|
||||
|
||||
Example of form and MessageContainer
|
||||
|
||||
[examples/formexample.php](examples/formexample.php)
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
Example #3:
|
||||
|
||||
```php
|
||||
$container=new MessageContainer();
|
||||
$container->addItem('id1','some msg 1','error');
|
||||
$container->addItem('id1','some msg 2','error');
|
||||
$container->addItem('id1','some msg 1','warning');
|
||||
|
||||
$container->addItem('id2','some msg 1','info');
|
||||
$container->addItem('id2','some msg 1','success');
|
||||
|
||||
$container->addItem('id33','some msg 1','error');
|
||||
$container->addItem('id33','some msg 2','error');
|
||||
$container->addItem('id33','some msg 1','success');
|
||||
$container->addItem('id33','some msg 2','success');
|
||||
$container->addItem('id33','some msg 2','success');
|
||||
|
||||
// obtaining information per locker
|
||||
$msg=$container->getLocker('id1')->firstErrorOrWarning(); // returns if the locker id1 has an error or warning
|
||||
$msg2=$container->getLocker('id2')->allInfo(); // returns all info store in locker id2 ["some msg1","some msg2"]
|
||||
$msg3=$container->getLocker('id3')->allInfo(); // (note this locker is not defined so it returns an empty array.
|
||||
$msg4=$container->getLocker('id33')->hasError(); // returns true if there is an error.
|
||||
$msg5=$container->getLocker('id33')->countError(); // returns the number of errors (or zero if none).
|
||||
|
||||
// obtaining information globally (all lockers)
|
||||
$msg7=$container->hasError(); // returns true if there is an error in any locker.
|
||||
$msg8=$container->allErrorArray(true); // returns all errors and warnings presents in any locker.
|
||||
```
|
||||
|
||||
## Adding a new message
|
||||
|
||||
To add a new message inside a locker, we use the method **addItem()**
|
||||
|
||||
```php
|
||||
$container->addItem(<idlocker>,<message>,<level>,<context array>);
|
||||
```
|
||||
|
||||
Where
|
||||
|
||||
* **idlocker** is the identifier of the locker to where we will store our message.
|
||||
* **message** is the string of the message.
|
||||
* The message could show variables using the syntax: **{{variablename}}**. Example **"The value <u>{{variable}}</u> is not valid"**
|
||||
* We could show the id of the locker using the syntax **{{_idlocker}}**. Example: **"The variable <u>{{_idlocker}}</u> is empty"**
|
||||
* **level** is the level of message. It could be error, warning, info and success. By default, this value is **"error"**
|
||||
* **context** (optional) is an associative array used to show a message with a variable. The context is set only once per **locker**.
|
||||
|
||||
```php
|
||||
// without context:
|
||||
$container->addItem('locker1','The variable price must be higher than 200','warning');
|
||||
|
||||
// with context:
|
||||
// The variable price must be higher than 200
|
||||
$container->addItem('locker2'
|
||||
,'The variable {{var1}} must be higher than {{var2}}'
|
||||
,'warning'
|
||||
,['var1'=>'price','var2'=>200]);
|
||||
// The variable price must be higher than 200 (not 500, the context is not updated this second time)
|
||||
$container->addItem('locker2'
|
||||
,'The variable {{var1}} must be higher than {{var2}}'
|
||||
,'warning'
|
||||
,['var1'=>'price','var2'=>500]);
|
||||
// The variable price must be higher than 200 (we use the previous context)
|
||||
$container->addItem('locker2'
|
||||
,'The variable {{var1}} must be higher than {{var2}}'
|
||||
,'warning');
|
||||
|
||||
```
|
||||
|
||||
> Note: We could add one or many messages to a locker. In the later example, the locker **locker2** stores 3 messages.
|
||||
>
|
||||
> Note: The message is evaluated when we call the method **addItem()**
|
||||
|
||||
## Getting the messages
|
||||
|
||||
**MessageContainer** stores a list of lockers of messages. It's aimed at convenience, so it features many methods to access
|
||||
the information in different ways.
|
||||
|
||||
Messages are ranked as follows
|
||||
|
||||
| id | Description | Example |
|
||||
|---------|-----------------------------------------------------------------------|-------------------------------------------|
|
||||
| error | The message is an error, and it must be solved. It is a show stopper. | Database is down |
|
||||
| warning | The message is a warning that maybe it could be ignored. | The registry was stored but with warnings |
|
||||
| info | The message is information | Log is stored |
|
||||
| success | The message is a successful operation | Order Accepted |
|
||||
|
||||
|
||||
Sometimes, both errors are warning are considered as equals. So the system allows reading an error or warning.
|
||||
|
||||
Error always has the priority, then warning, info and success. If you want to read the first message, then it starts
|
||||
searching for errors.
|
||||
|
||||
You can obtain a message as an array of objects of the type **MessageLocker**, as an array of string, or as a single string
|
||||
(first message)
|
||||
|
||||
```php
|
||||
$container->get('idfield'); // container idfield
|
||||
$container->get('idfield2'); // container idfield2
|
||||
|
||||
if($container->hasError()) {
|
||||
// Error: we do something here.
|
||||
echo "we found ".$container->errorCount()." errors in all lockers";
|
||||
}
|
||||
|
||||
// using messageList
|
||||
if($container->hasError()) {
|
||||
// Error: we do something here.
|
||||
echo "we found ".$container->errorcount." errors in all lockers";
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### MessageContainer
|
||||
|
||||
#### Count of messages of all lockers
|
||||
|
||||
| Name of the field | Type | Description |
|
||||
|-------------------|------|-----------------------------------------------------|
|
||||
| $errorCount | int | Get the number of errors in all lockers |
|
||||
| $warningCount | int | Get the number of warnings in all lockers |
|
||||
| $errorOrWarning | int | Get the number of errors or warnings in all lockers |
|
||||
| $infoCount | int | Get the number of information messages. |
|
||||
| $successCount | int | Get the number of success messages. |
|
||||
|
||||
Example:
|
||||
|
||||
```php
|
||||
if ($container->errorcount>0) {
|
||||
// some error
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Obtain messages or text of all lockers
|
||||
|
||||
| Name | Type | Description | Example of result |
|
||||
|--------------------|--------|--------------------------------------------------------------------------------------------|-------------------------------------------|
|
||||
| firstErrorText() | method | Returns the first message of error of all lockers | "Error in field" |
|
||||
| firstWarningText() | method | Returns the first message of warning of all lockers | "warning in field" |
|
||||
| firstInfoText() | method | Returns the first message of info of all lockers | "info: log" |
|
||||
| firstSuccessText() | method | Returns the first message of success of all lockers | "Operation successful" |
|
||||
| lastErrorText() | method | Returns the last message of error of all lockers | "Error in field" |
|
||||
| lastWarningText() | method | Returns the last message of warning of all lockers | "warning in field" |
|
||||
| lastInfoText() | method | Returns the last message of info of all lockers | "info: log" |
|
||||
| lastSuccessText() | method | Returns the last message of success of all lockers | "Operation successful" |
|
||||
| allError() | method | Returns all errors of all lockers (as an array of objects of the type **MessageLocker**) | **MessageLocker**[] |
|
||||
| allWarning() | method | Returns all warning of all lockers (as an array of objects of the type **MessageLocker**) | **MessageLocker**[] |
|
||||
| allInfo() | method | Returns all info of all lockers (as an array of objects of the type **MessageLocker**) | **MessageLocker**[] |
|
||||
| allSuccess() | method | Returns all success of all lockers (as an array of objects of the type **MessageLocker**) | **MessageLocker**[] |
|
||||
| allErrorArray() | method | Returns all errors of all lockers (as an array of texts) | ["Error in field1","Error in field2"] |
|
||||
| allWarningArray() | method | Returns all warning of all lockers (as an array of texts) | ["Warning in field1","Warning in field2"] |
|
||||
| allInfoArray() | method | Returns all info of all lockers (as an array of texts) | ["Info in field1","Info in field2"] |
|
||||
| allSuccessArray | method | Returns all success of all lockers (as an array of texts) | ["Info in field1","Info in field2"] |
|
||||
|
||||
```php
|
||||
echo $container->firstErrorText(); // returns first error if any
|
||||
$array=$container->allError(); // MessageLocker[]
|
||||
echo $array[0]->firstError();
|
||||
$array=$container->allErrorArray(); // string[]
|
||||
echo $array[0];
|
||||
```
|
||||
|
||||
#### Css for a specific container
|
||||
|
||||
It is possible to obtain a CSS class based in the current level or state of a container.
|
||||
|
||||
* **$cssClasses** (field) is an associative array to use with the method cssClass()
|
||||
|
||||
* **cssClasses**() is method that returns a class based in the type of level of the container
|
||||
|
||||
```php
|
||||
$css=$this-messageList->cssClasses('container1');
|
||||
```
|
||||
|
||||
#### Misc
|
||||
|
||||
| Name | Type | Description |
|
||||
|------------|--------|-------------------------------------------------------------------------------------------------------|
|
||||
| $items | field | We get all lockers (array of the type **MessageLocker**). Each container could contain many messages. |
|
||||
| resetAll() | method | $array=$this-messageList->items; $this-messageList->items['id'];Delete all lockers and reset counters |
|
||||
| addItem() | method | It adds a new message to a container |
|
||||
| allIds() | method | Get all the id of the lockers |
|
||||
| get() | method | Get a container (as an object of the type **MessageLocker**). You can also use items[] |
|
||||
| hasError() | method | Returns true if there is an error. |
|
||||
|
||||
```php
|
||||
echo $container->resetAll(); // resets all lockers
|
||||
$container->addItem('containerid','it is a message','error'); // we add an error in the container with #id containerid
|
||||
$array=$container->allIds(); // ['containerid']
|
||||
var_dump($validation->get('containerid')); // object MessageLocker
|
||||
|
||||
$array=$this-messageList->items;
|
||||
var_dump($this-messageList->items['containerid']); // object MessageLocker
|
||||
|
||||
if($container->hasError()) { // $validation->hasError() does the same
|
||||
echo "there is an error";
|
||||
}
|
||||
```
|
||||
|
||||
### MessageLocker
|
||||
|
||||
Inside **MessageContainer** we could have one or many lockers( **MessageLocker** ).
|
||||
|
||||
#### Obtain messages of a specific container
|
||||
|
||||
| Name | Type | Description | Example of result |
|
||||
|--------------------|--------|-----------------------------------------------------------|-------------------------------------------|
|
||||
| firstErrorText() | method | Returns the first message of error of a container | "Error in field" |
|
||||
| firstWarningText() | method | Returns the first message of warning of a container | "warning in field" |
|
||||
| firstInfoText() | method | Returns the first message of info of a container | "info: log" |
|
||||
| firstSuccessText() | method | Returns the first message of success of a container | "Operation successful" |
|
||||
| lastErrorText() | method | Returns the last message of error of a container | "Error in field" |
|
||||
| lastWarningText() | method | Returns the last message of warning of a container | "warning in field" |
|
||||
| lastInfoText() | method | Returns the last message of info of a container | "info: log" |
|
||||
| lastSuccessText() | method | Returns the last message of success of a container | "Operation successful" |
|
||||
| allError() | method | Returns all errors of a container (as an array of texts) | ["Error in field1","Error in field2"] |
|
||||
| allWarning() | method | Returns all warning of a container (as an array of texts) | ["Warning in field1","Warning in field2"] |
|
||||
| allInfo() | method | Returns all info of a container (as an array of texts) | ["Info in field1","Info in field2"] |
|
||||
| allSuccess() | method | Returns all success of a container (as an array of texts) | ["Info in field1","Info in field2"] |
|
||||
|
||||
```php
|
||||
$container->get('idfield'); // container idfield
|
||||
|
||||
echo $container->firstErrorText(); // we show the first error (if any) in the container
|
||||
var_dump($container->allError); // we show the all errors
|
||||
```
|
||||
|
||||
## Definitions of the classes
|
||||
|
||||
# Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
* [MessageContainer](#messagecontainer)
|
||||
* [What is the objective?](#what-is-the-objective)
|
||||
* [How to use it](#how-to-use-it)
|
||||
* [Definitions](#definitions)
|
||||
* [Adding a new message](#adding-a-new-message)
|
||||
* [Getting the messages](#getting-the-messages)
|
||||
* [MessageContainer](#messagecontainer-1)
|
||||
* [Count of messages of all lockers](#count-of-messages-of-all-lockers)
|
||||
* [Obtain messages or text of all lockers](#obtain-messages-or-text-of-all-lockers)
|
||||
* [Css for a specific container](#css-for-a-specific-container)
|
||||
* [Misc](#misc)
|
||||
* [MessageLocker](#messagelocker)
|
||||
* [Obtain messages of a specific container](#obtain-messages-of-a-specific-container)
|
||||
* [Definitions of the classes](#definitions-of-the-classes)
|
||||
* [Table of contents](#table-of-contents)
|
||||
* [MessageContainer](#messagecontainer-2)
|
||||
* [Field items (MessageLocker[])](#field-items-messagelocker)
|
||||
* [Field errorCount (int)](#field-errorcount-int)
|
||||
* [Field warningCount (int)](#field-warningcount-int)
|
||||
* [Field errorOrWarningCount (int)](#field-errororwarningcount-int)
|
||||
* [Field infoCount (int)](#field-infocount-int)
|
||||
* [Field successCount (int)](#field-successcount-int)
|
||||
* [Field cssClasses (string[])](#field-cssclasses-string)
|
||||
* [Method __construct()](#method-__construct)
|
||||
* [Method resetAll()](#method-resetall)
|
||||
* [Method addItem()](#method-additem)
|
||||
* [Parameters:](#parameters)
|
||||
* [Method allIds()](#method-allids)
|
||||
* [Method get()](#method-get)
|
||||
* [Parameters:](#parameters-1)
|
||||
* [Method getLocker()](#method-getlocker)
|
||||
* [Parameters:](#parameters-2)
|
||||
* [Method cssClass()](#method-cssclass)
|
||||
* [Parameters:](#parameters-3)
|
||||
* [Method firstErrorOrWarning()](#method-firsterrororwarning)
|
||||
* [Parameters:](#parameters-4)
|
||||
* [Method firstErrorText()](#method-firsterrortext)
|
||||
* [Parameters:](#parameters-5)
|
||||
* [Method firstWarningText()](#method-firstwarningtext)
|
||||
* [Parameters:](#parameters-6)
|
||||
* [Method firstInfoText()](#method-firstinfotext)
|
||||
* [Parameters:](#parameters-7)
|
||||
* [Method firstSuccessText()](#method-firstsuccesstext)
|
||||
* [Parameters:](#parameters-8)
|
||||
* [Method lastErrorOrWarning()](#method-lasterrororwarning)
|
||||
* [Parameters:](#parameters-9)
|
||||
* [Method lastErrorText()](#method-lasterrortext)
|
||||
* [Parameters:](#parameters-10)
|
||||
* [Method lastWarningText()](#method-lastwarningtext)
|
||||
* [Parameters:](#parameters-11)
|
||||
* [Method lastInfoText()](#method-lastinfotext)
|
||||
* [Parameters:](#parameters-12)
|
||||
* [Method lastSuccessText()](#method-lastsuccesstext)
|
||||
* [Parameters:](#parameters-13)
|
||||
* [Method allArray()](#method-allarray)
|
||||
* [Parameters:](#parameters-14)
|
||||
* [Method allErrorArray()](#method-allerrorarray)
|
||||
* [Parameters:](#parameters-15)
|
||||
* [Method allWarningArray()](#method-allwarningarray)
|
||||
* [Method allErrorOrWarningArray()](#method-allerrororwarningarray)
|
||||
* [Method allInfoArray()](#method-allinfoarray)
|
||||
* [Method AllSuccessArray()](#method-allsuccessarray)
|
||||
* [Method allAssocArray()](#method-allassocarray)
|
||||
* [Parameters:](#parameters-16)
|
||||
* [Method hasError()](#method-haserror)
|
||||
* [Parameters:](#parameters-17)
|
||||
* [MessageLocker](#messagelocker-1)
|
||||
* [Method __construct()](#method-__construct-1)
|
||||
* [Parameters:](#parameters-18)
|
||||
* [Method setContext()](#method-setcontext)
|
||||
* [Parameters:](#parameters-19)
|
||||
* [Method addError()](#method-adderror)
|
||||
* [Parameters:](#parameters-20)
|
||||
* [Method replaceCurlyVariable()](#method-replacecurlyvariable)
|
||||
* [Parameters:](#parameters-21)
|
||||
* [Method addWarning()](#method-addwarning)
|
||||
* [Parameters:](#parameters-22)
|
||||
* [Method addInfo()](#method-addinfo)
|
||||
* [Parameters:](#parameters-23)
|
||||
* [Method addSuccess()](#method-addsuccess)
|
||||
* [Parameters:](#parameters-24)
|
||||
* [Method countErrorOrWarning()](#method-counterrororwarning)
|
||||
* [Method countError()](#method-counterror)
|
||||
* [Method countWarning()](#method-countwarning)
|
||||
* [Method countInfo()](#method-countinfo)
|
||||
* [Method countSuccess()](#method-countsuccess)
|
||||
* [Method first()](#method-first)
|
||||
* [Parameters:](#parameters-25)
|
||||
* [Method firstError()](#method-firsterror)
|
||||
* [Parameters:](#parameters-26)
|
||||
* [Method firstWarning()](#method-firstwarning)
|
||||
* [Parameters:](#parameters-27)
|
||||
* [Method firstErrorOrWarning()](#method-firsterrororwarning-1)
|
||||
* [Parameters:](#parameters-28)
|
||||
* [Method firstInfo()](#method-firstinfo)
|
||||
* [Parameters:](#parameters-29)
|
||||
* [Method firstSuccess()](#method-firstsuccess)
|
||||
* [Parameters:](#parameters-30)
|
||||
* [Method last()](#method-last)
|
||||
* [Parameters:](#parameters-31)
|
||||
* [Method lastError()](#method-lasterror)
|
||||
* [Parameters:](#parameters-32)
|
||||
* [Method lastWarning()](#method-lastwarning)
|
||||
* [Parameters:](#parameters-33)
|
||||
* [Method lastErrorOrWarning()](#method-lasterrororwarning-1)
|
||||
* [Parameters:](#parameters-34)
|
||||
* [Method lastInfo()](#method-lastinfo)
|
||||
* [Parameters:](#parameters-35)
|
||||
* [Method lastSuccess()](#method-lastsuccess)
|
||||
* [Parameters:](#parameters-36)
|
||||
* [Method all()](#method-all)
|
||||
* [Parameters:](#parameters-37)
|
||||
* [Method allError()](#method-allerror)
|
||||
* [Method allWarning()](#method-allwarning)
|
||||
* [Method allErrorOrWarning()](#method-allerrororwarning)
|
||||
* [Method allInfo()](#method-allinfo)
|
||||
* [Method allSuccess()](#method-allsuccess)
|
||||
* [Method allAssocArray()](#method-allassocarray-1)
|
||||
* [Parameters:](#parameters-38)
|
||||
* [Method hasError()](#method-haserror-1)
|
||||
* [Parameters:](#parameters-39)
|
||||
* [Method throwOnError()](#method-throwonerror)
|
||||
* [Parameters:](#parameters-40)
|
||||
* [changelog](#changelog)
|
||||
<!-- TOC -->
|
||||
|
||||
------
|
||||
|
||||
## MessageContainer
|
||||
Class MessageList
|
||||
### Field items (MessageLocker[])
|
||||
Array of containers
|
||||
### Field errorCount (int)
|
||||
Number of errors stored globally
|
||||
### Field warningCount (int)
|
||||
Number of warnings stored globally
|
||||
### Field errorOrWarningCount (int)
|
||||
Number of errors or warning stored globally
|
||||
### Field infoCount (int)
|
||||
Number of information stored globally
|
||||
### Field successCount (int)
|
||||
Number of success stored globally
|
||||
### Field cssClasses (string[])
|
||||
Used to convert a type of message to a css class
|
||||
|
||||
### Method __construct()
|
||||
MessageList constructor.
|
||||
|
||||
### Method resetAll()
|
||||
It resets all the container and flush all the results.
|
||||
|
||||
### Method addItem()
|
||||
You could add a message (including errors,warning..) and store it in a $idLocker
|
||||
#### Parameters:
|
||||
* **$idLocker** Identified of the locker (where the message will be stored) (string)
|
||||
* **$message** message to show. Example: 'the value is incorrect' (string)
|
||||
* **$level** =['error','warning','info','success']\[$i] (string)
|
||||
* **$context** [optional] it is an associative array with the values of the item<br>
|
||||
For optimization, the context is not update if exists another context. (array)
|
||||
|
||||
### Method allIds()
|
||||
It obtains all the ids for all the lockers.
|
||||
|
||||
### Method get()
|
||||
Alias of $this->getMessage()
|
||||
#### Parameters:
|
||||
* **$idLocker** ID of the locker (string)
|
||||
|
||||
### Method getLocker()
|
||||
It returns a MessageLocker containing a locker.<br>
|
||||
<b>If the locker doesn't exist then it returns an empty object (not null)</b>
|
||||
#### Parameters:
|
||||
* **$idLocker** ID of the locker (string)
|
||||
|
||||
### Method cssClass()
|
||||
It returns a css class associated with the type of errors inside a locker<br>
|
||||
If the locker contains more than one message, then it uses the most severe one (error,warning,etc.)<br>
|
||||
The method uses the field <b>$this->cssClasses</b>, so you can change the CSS classes.
|
||||
<pre>
|
||||
$this->clsssClasses=['error'=>'class-red','warning'=>'class-yellow','info'=>'class-green','success'=>'class-blue'];
|
||||
$css=$this->cssClass('customerId');
|
||||
</pre>
|
||||
#### Parameters:
|
||||
* **$idLocker** ID of the locker (string)
|
||||
|
||||
### Method firstErrorOrWarning()
|
||||
It returns the first message of error or empty if none<br>
|
||||
If not, then it returns the first message of warning or empty if none
|
||||
#### Parameters:
|
||||
* **$default** if not message is found, then it returns this value (string)
|
||||
|
||||
### Method firstErrorText()
|
||||
It returns the first message of error or empty if none
|
||||
#### Parameters:
|
||||
* **$default** if not message is found, then it returns this value. (string)
|
||||
* **$includeWarning** if true then it also includes warning but any error has priority. (bool)
|
||||
|
||||
### Method firstWarningText()
|
||||
It returns the first message of warning or empty if none
|
||||
#### Parameters:
|
||||
* **$default** if not message is found, then it returns this value (string)
|
||||
|
||||
### Method firstInfoText()
|
||||
It returns the first message of information or empty if none
|
||||
#### Parameters:
|
||||
* **$default** if not message is found, then it returns this value (string)
|
||||
|
||||
### Method firstSuccessText()
|
||||
It returns the first message of success or empty if none
|
||||
#### Parameters:
|
||||
* **$default** if not message is found, then it returns this value (string)
|
||||
|
||||
### Method lastErrorOrWarning()
|
||||
It returns the last message of error or empty if none<br>
|
||||
If not, then it returns the last message of warning or empty if none
|
||||
#### Parameters:
|
||||
* **$default** if not message is found, then it returns this value (string)
|
||||
|
||||
### Method lastErrorText()
|
||||
It returns the last message of error or empty if none
|
||||
#### Parameters:
|
||||
* **$default** if not message is found, then it returns this value. (string)
|
||||
* **$includeWarning** if true then it also includes warning but any error has priority. (bool)
|
||||
|
||||
### Method lastWarningText()
|
||||
It returns the last message of warning or empty if none
|
||||
#### Parameters:
|
||||
* **$default** if not message is found, then it returns this value (string)
|
||||
|
||||
### Method lastInfoText()
|
||||
It returns the last message of information or empty if none
|
||||
#### Parameters:
|
||||
* **$default** if not message is found, then it returns this value (string)
|
||||
|
||||
### Method lastSuccessText()
|
||||
It returns the last message of success or empty if none
|
||||
#### Parameters:
|
||||
* **$default** if not message is found, then it returns this value (string)
|
||||
|
||||
### Method allArray()
|
||||
It returns an array with all messages of any type of all lockers
|
||||
#### Parameters:
|
||||
* **$level** =[null,'error','warning','errorwarning','info','success']\[$i] the level to show.<br>
|
||||
Null means it shows all errors (null|string)
|
||||
|
||||
### Method allErrorArray()
|
||||
It returns an array with all messages of error of all lockers.
|
||||
#### Parameters:
|
||||
* **$includeWarning** if true then it also includes warnings. (bool)
|
||||
|
||||
### Method allWarningArray()
|
||||
It returns an array with all messages of warning of all lockers.
|
||||
|
||||
### Method allErrorOrWarningArray()
|
||||
It returns an array with all messages of errors and warnings of all lockers.
|
||||
|
||||
### Method allInfoArray()
|
||||
It returns an array with all messages of info of all lockers.
|
||||
|
||||
### Method AllSuccessArray()
|
||||
It returns an array with all messages of success of all lockers.
|
||||
|
||||
### Method allAssocArray()
|
||||
It returns an associative array of the form <br>
|
||||
<pre>
|
||||
[
|
||||
['id'=>'', // id of the locker
|
||||
'level'=>'' // level of message (error, warning, info or success)
|
||||
'msg'=>'' // the message to show
|
||||
]
|
||||
]
|
||||
</pre>
|
||||
#### Parameters:
|
||||
* **$level** param null|string $level (null|string)
|
||||
|
||||
### Method hasError()
|
||||
It returns true if there is an error (or error and warning).
|
||||
#### Parameters:
|
||||
* **$includeWarning** If true then it also returns if there is a warning (bool)
|
||||
|
||||
------
|
||||
|
||||
## MessageLocker
|
||||
Class MessageLocker
|
||||
|
||||
### Method __construct()
|
||||
MessageLocker constructor.
|
||||
#### Parameters:
|
||||
* **$idLocker** param null|string $idLocker (null|string)
|
||||
* **$context** param array|null $context (array|null)
|
||||
|
||||
### Method setContext()
|
||||
We set the context only if the current context is null.
|
||||
#### Parameters:
|
||||
* **$context** The new context. (array|null)
|
||||
|
||||
### Method addError()
|
||||
It adds an error to the locker.
|
||||
#### Parameters:
|
||||
* **$msg** The message to store (mixed)
|
||||
|
||||
### Method replaceCurlyVariable()
|
||||
Replaces all variables defined between {{ }} by a variable inside the dictionary of values.<br>
|
||||
Example:<br>
|
||||
replaceCurlyVariable('hello={{var}}',['var'=>'world']) // hello=world<br>
|
||||
replaceCurlyVariable('hello={{var}}',['varx'=>'world']) // hello=<br>
|
||||
replaceCurlyVariable('hello={{var}}',['varx'=>'world'],true) // hello={{var}}<br>
|
||||
#### Parameters:
|
||||
* **$string** The input value. It could contain variables defined as {{namevar}} (string)
|
||||
|
||||
### Method addWarning()
|
||||
It adds a warning to the locker.
|
||||
#### Parameters:
|
||||
* **$msg** The message to store (mixed)
|
||||
|
||||
### Method addInfo()
|
||||
It adds an information to the locker.
|
||||
#### Parameters:
|
||||
* **$msg** The message to store (mixed)
|
||||
|
||||
### Method addSuccess()
|
||||
It adds a success to the locker.
|
||||
#### Parameters:
|
||||
* **$msg** The message to store (mixed)
|
||||
|
||||
### Method countErrorOrWarning()
|
||||
It returns the number of errors or warnings contained in the locker
|
||||
|
||||
### Method countError()
|
||||
It returns the number of errors contained in the locker
|
||||
|
||||
### Method countWarning()
|
||||
It returns the number of warnings contained in the locker
|
||||
|
||||
### Method countInfo()
|
||||
It returns the number of infos contained in the locker
|
||||
|
||||
### Method countSuccess()
|
||||
It returns the number of successes contained in the locker
|
||||
|
||||
### Method first()
|
||||
It returns the first message of any kind.<br>
|
||||
If error then it returns the first message of error<br>
|
||||
If not, if warning then it returns the first message of warning<br>
|
||||
If not, then it shows the first info message (if any)<br>
|
||||
If not, then it shows the first success message (if any)<br>
|
||||
If not, then it shows the default message.
|
||||
#### Parameters:
|
||||
* **$defaultMsg** param string $defaultMsg (string)
|
||||
* **$level** =[null,'error','warning','errorwarning','info','success']\[$i] the level to show (by
|
||||
default it shows the first message of any level
|
||||
, starting with error) (null|string)
|
||||
|
||||
### Method firstError()
|
||||
It returns the first message of error, if any. Otherwise, it returns the default value
|
||||
#### Parameters:
|
||||
* **$default** param string $default (string)
|
||||
|
||||
### Method firstWarning()
|
||||
It returns the first message of warning, if any. Otherwise, it returns the default value
|
||||
#### Parameters:
|
||||
* **$default** param string $default (string)
|
||||
|
||||
### Method firstErrorOrWarning()
|
||||
It returns the first message of error or warning (in this order), if any. Otherwise, it returns the default value
|
||||
#### Parameters:
|
||||
* **$default** param string $default (string)
|
||||
|
||||
### Method firstInfo()
|
||||
It returns the first message of info, if any. Otherwise, it returns the default value
|
||||
#### Parameters:
|
||||
* **$default** param string $default (string)
|
||||
|
||||
### Method firstSuccess()
|
||||
It returns the first message of success, if any. Otherwise, it returns the default value
|
||||
#### Parameters:
|
||||
* **$default** param string $default (string)
|
||||
|
||||
### Method last()
|
||||
It returns the last message of any kind.<br>
|
||||
If error then it returns the last message of error<br>
|
||||
If not, if warning then it returns the last message of warning<br>
|
||||
If not, then it shows the last info message (if any)<br>
|
||||
If not, then it shows the last success message (if any)<br>
|
||||
If not, then it shows the default message.
|
||||
#### Parameters:
|
||||
* **$defaultMsg** param string $defaultMsg (string)
|
||||
* **$level** =[null,'error','warning','errorwarning','info','success']\[$i] the level to show (by
|
||||
default it shows the last message of any level
|
||||
, starting with error) (null|string)
|
||||
|
||||
### Method lastError()
|
||||
It returns the last message of error, if any. Otherwise, it returns the default value
|
||||
#### Parameters:
|
||||
* **$default** param string $default (string)
|
||||
|
||||
### Method lastWarning()
|
||||
It returns the last message of warning, if any. Otherwise, it returns the default value
|
||||
#### Parameters:
|
||||
* **$default** param string $default (string)
|
||||
|
||||
### Method lastErrorOrWarning()
|
||||
It returns the last message of error or warning (in this order), if any. Otherwise, it returns the default value
|
||||
#### Parameters:
|
||||
* **$default** param string $default (string)
|
||||
|
||||
### Method lastInfo()
|
||||
It returns the last message of info, if any. Otherwise, it returns the default value
|
||||
#### Parameters:
|
||||
* **$default** param string $default (string)
|
||||
|
||||
### Method lastSuccess()
|
||||
It returns the last message of success, if any. Otherwise, it returns the default value
|
||||
#### Parameters:
|
||||
* **$default** param string $default (string)
|
||||
|
||||
### Method all()
|
||||
Returns all messages or an empty array if none.
|
||||
#### Parameters:
|
||||
* **$level** =[null,'error','warning','errorwarning','info','success']\[$i] the level to show. Null
|
||||
means it shows all errors (null|string)
|
||||
|
||||
### Method allError()
|
||||
Returns all messages of errors (as an array of string), or an empty array if none.
|
||||
|
||||
### Method allWarning()
|
||||
Returns all messages of warning, or an empty array if none.
|
||||
|
||||
### Method allErrorOrWarning()
|
||||
Returns all messages of errors or warnings, or an empty array if none
|
||||
|
||||
### Method allInfo()
|
||||
Returns all messages of info, or an empty array if none.
|
||||
|
||||
### Method allSuccess()
|
||||
Returns all messages of success, or an empty array if none.
|
||||
|
||||
### Method allAssocArray()
|
||||
It returns an associative array of the form:<br>
|
||||
<pre>
|
||||
[
|
||||
['id'=>'', // id of the locker
|
||||
'level'=>'' // level of message (error, warning, info or success)
|
||||
'msg'=>'' // the message to show
|
||||
]
|
||||
]
|
||||
</pre>
|
||||
#### Parameters:
|
||||
* **$level** =[null,'error','warning','errorwarning','info','success']\[$i] the level to show.
|
||||
Null means it shows all messages regardless of the level (starting with error) (null|string)
|
||||
|
||||
### Method hasError()
|
||||
It returns true if there is an error (or error and warning).
|
||||
#### Parameters:
|
||||
* **$includeWarning** If true then it also returns if there is a warning (bool)
|
||||
|
||||
### Method throwOnError()
|
||||
If we store an error then we also throw a PHP exception.
|
||||
#### Parameters:
|
||||
* **$throwOnError** if true (default), then it throws an excepcion every time we store an error.
|
||||
* **$includeWarning** If true then it also includes warnings.
|
||||
|
||||
------
|
||||
|
||||
## changelog
|
||||
* 2.9 2024-03-02 * Updating dependency to PHP 7.4. The extended support of PHP 7.2 ended 3 years ago.
|
||||
* Added more type hinting in the code.
|
||||
* 2.8 2023-01-28
|
||||
* **[new]** function getLog(),setLogFilename(),backupLog(),restoreLog()
|
||||
* 2.7 2023-01-28
|
||||
* Now it is possible to log every message when it is an error,warning,info or success.
|
||||
* **[new]** function setLog(),log(),getLogFilename() and count()
|
||||
* 2.6 2023-01-26
|
||||
* Fixed some typos.
|
||||
* 2.5 2022-03-22
|
||||
* **[new]** Added type hinting to the library
|
||||
* **[fix]** Added a description to composer.json
|
||||
* 2.4 2022-02-06
|
||||
* **[new]** **[container]** new methods resetLocker() and hasLocker()
|
||||
* **[new]** **[locker]** new method resetAll()
|
||||
* 2.3 2022-02-05
|
||||
* Added the right version in the documentation. No other change is done.
|
||||
|
||||
* 2.2 2022-02-05
|
||||
* **[new]** Now it is possible to read the last message (error, warning, info, all) in the container and in the locker
|
||||
* **[new]** MessageLocker does not store the first message anymore as a private field, it is now calculated each time.
|
||||
* **[new]** Method logOnError() that calls to error_log() when we generate an error or warning.
|
||||
* **[new]** Method ::instance() allows to get an instance of the container (singleton), if not, then it is created.
|
||||
* **[new]** Construct by default replaces the instance, however, you can set to not to replace it. It is useful if you want to have more than one instance.
|
||||
* 2.1 2022-02-05
|
||||
* **[fix]** Update dependency. Now, it only works with PHP 7.2 and higher. It is also tested for PHP 8.1
|
||||
* **[fix]** Update PHPUnit dependency.
|
||||
* **[new]** Now methods have type hinting (return values)
|
||||
* 2.0.1 2022-01-29
|
||||
* [fix] some cleanups
|
||||
* [new] added method throwOnError(). So it is possible to throw an exception when we store an error and/or warning.
|
||||
* It only throws if the error or warning is throw via the container.
|
||||
* 2.0 2022-01-15
|
||||
* Dropping PHP 5.X. Now it requires PHP 7.1 or higher
|
||||
* 1.2 2021-03-21 Added new methods.
|
||||
* Optionally, messages could use variables obtained from a context. The context is per locker. Example "it is a {{variable}}"
|
||||
* 1.1 2021-03-17 some cleanups
|
||||
* 1.0 2021-03-17 first version
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "eftec/messagecontainer",
|
||||
"description": "MessageContainer is a simple a minimalist message-system where messages (strings) could be stored in a tree-like structure",
|
||||
"homepage": "https://github.com/EFTEC/MessageContainer",
|
||||
"support": {
|
||||
"issues": "https://github.com/EFTEC/MessageContainer/issues"
|
||||
},
|
||||
"type": "library",
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jorge Castro",
|
||||
"email": "jcastro@eftec.cl"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.4",
|
||||
"ext-ctype": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"eftec\\": "lib/"
|
||||
}
|
||||
}
|
||||
}
|
||||
+758
@@ -0,0 +1,758 @@
|
||||
<?php /** @noinspection UnknownInspectionInspection */
|
||||
/** @noinspection SlowArrayOperationsInLoopInspection */
|
||||
/** @noinspection PhpUnused */
|
||||
|
||||
namespace eftec;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class MessageList
|
||||
*
|
||||
* @package eftec
|
||||
* @author Jorge Castro Castillo
|
||||
* @version 2.9 2024-03-02
|
||||
* @copyright (c) Jorge Castro C. mit License https://github.com/EFTEC/MessageContainer
|
||||
* @see https://github.com/EFTEC/MessageContainer
|
||||
*/
|
||||
class MessageContainer
|
||||
{
|
||||
/** @var MessageLocker[] Array of containers */
|
||||
public array $items = [];
|
||||
/** @var int Number of errors stored globally */
|
||||
public int $errorCount = 0;
|
||||
/** @var int Number of warnings stored globally */
|
||||
public int $warningCount = 0;
|
||||
/** @var int Number of errors or warning stored globally */
|
||||
public int $errorOrWarningCount = 0;
|
||||
/** @var int Number of information stored globally */
|
||||
public int $infoCount = 0;
|
||||
/** @var int Number of success stored globally */
|
||||
public int $successCount = 0;
|
||||
/** @var string[] Used to convert a type of message to a css class */
|
||||
public array $cssClasses = ['error' => 'danger', 'warning' => 'warning', 'info' => 'info', 'success' => 'success'];
|
||||
protected bool $throwOnError = false;
|
||||
protected bool $throwOnWarning = false;
|
||||
protected bool $logOnError = false;
|
||||
protected bool $logOnWarning = false;
|
||||
protected bool $logOnInfo = false;
|
||||
protected bool $logOnSuccess = false;
|
||||
/** @var string|null the filename to log. If no file, then it uses the default file specified on error_log */
|
||||
protected ?string $logFilename = null;
|
||||
protected array $backupLog = [false, false, false, false];
|
||||
/** @var null|MessageContainer singleton */
|
||||
protected static ?MessageContainer $instance = null;
|
||||
|
||||
/**
|
||||
* MessageList constructor.
|
||||
*/
|
||||
public function __construct($setSingleton = true)
|
||||
{
|
||||
$this->items = [];
|
||||
if ($setSingleton) {
|
||||
self::$instance = $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the singleton and if it doesn't exist, then it is created.
|
||||
* @return MessageContainer
|
||||
*/
|
||||
public static function instance(): MessageContainer
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new MessageContainer(false);
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* It resets all the container and flush all the results.
|
||||
*/
|
||||
public function resetAll(): void
|
||||
{
|
||||
$this->errorCount = 0;
|
||||
$this->warningCount = 0;
|
||||
$this->errorOrWarningCount = 0;
|
||||
$this->infoCount = 0;
|
||||
$this->successCount = 0;
|
||||
$this->items = [];
|
||||
$this->throwOnError = false;
|
||||
$this->throwOnWarning = false;
|
||||
$this->logOnError = false;
|
||||
$this->logOnWarning = false;
|
||||
$this->logOnInfo = false;
|
||||
$this->logOnSuccess = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* It resets (clear the messages) of a specific locker by deleting all the messages and keeping
|
||||
* the count of them.<br>
|
||||
* @param string $idLocker If the locker doesn't exist, it does nothing.
|
||||
* @return void
|
||||
*/
|
||||
public function resetLocker(string $idLocker): void
|
||||
{
|
||||
if (!$this->hasLocker($idLocker)) {
|
||||
return;
|
||||
}
|
||||
$locker = $this->get($idLocker);
|
||||
$this->errorCount -= $locker->countError();
|
||||
$this->warningCount -= $locker->countWarning();
|
||||
$this->infoCount -= $locker->countInfo();
|
||||
$this->successCount -= $locker->countSuccess();
|
||||
$locker->resetAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a message using the error_log system.<br>
|
||||
* If level is error, then it logs directly<br>
|
||||
* If level is not error, then it logs in a different file (a file with a prefix)<br>
|
||||
* The filename is determined using the current error_log file.<br>
|
||||
* If it is unable to determine, then it stores in /var/log (Linux/MacOs) or in session.save_path (Windows)
|
||||
* @param string $level =['error','warning','info','success'][$i]
|
||||
* @param string|null $txt The message to log
|
||||
* @return bool
|
||||
* @noinspection ForgottenDebugOutputInspection
|
||||
*/
|
||||
public function log(string $level, ?string $txt): bool
|
||||
{
|
||||
if ($level === 'error') {
|
||||
return error_log($txt);
|
||||
}
|
||||
return error_log('[' . date("d-M-Y H:i:s e") . "] " . $txt . "\n", 3, $this->getLogFilename($level));
|
||||
}
|
||||
|
||||
/**
|
||||
* It sets the filename to log file.
|
||||
* @param string $filename
|
||||
* @return void
|
||||
*/
|
||||
public function setLogFilename(string $filename): MessageContainer
|
||||
{
|
||||
$this->logFilename = $filename;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLogFilename(string $level = 'error'): string
|
||||
{
|
||||
$original = $this->logFilename ?? ini_get('error_log'); // by default this value is empty.
|
||||
$postfix = ($level === 'error') ? '' : '_' . $level; // error does not generate a postfix
|
||||
if ($original) { // php has a log file set
|
||||
$pos = strrpos($original, '.');
|
||||
if ($pos !== false) {
|
||||
$original = substr_replace($original, $postfix . '.', $pos, strlen('.'));
|
||||
} else {
|
||||
$original .= $postfix;
|
||||
}
|
||||
return $original;
|
||||
}
|
||||
// php does not have a log file, so we use a default path. On Windows, we use the session path.
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
$path = ini_get('session.save_path');
|
||||
if (!$path) {
|
||||
$path = $_SERVER['APPDATA'];
|
||||
}
|
||||
} else {
|
||||
$path = '/var/log';
|
||||
}
|
||||
return $path . "/php_error$postfix.log";
|
||||
}
|
||||
|
||||
/**
|
||||
* If we store an error then we also throw a PHP exception.
|
||||
*
|
||||
* @param bool $throwOnError if true (default), then it throws an excepcion every time
|
||||
* we store an error.
|
||||
* @param boolean $includeWarning If true then it also includes warnings.
|
||||
* @return MessageContainer
|
||||
*/
|
||||
public function throwOnError(bool $throwOnError = true, bool $includeWarning = false): MessageContainer
|
||||
{
|
||||
$this->throwOnError = $throwOnError;
|
||||
$this->throwOnWarning = $includeWarning;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If we store a message then we also could write the information in a file using error_log
|
||||
*
|
||||
* @param bool $logOnError if true (default), then it saves the log file (using error_log)
|
||||
* @param boolean $logOnWarning If true then it also includes the log with warnings (default false).
|
||||
* @param bool $logOnInfo If true then it also includes the log with info (default false).
|
||||
* @param bool $logOnSuccess If true then it also includes the log with success (default false).
|
||||
* @return MessageContainer
|
||||
*/
|
||||
public function LogOnError(bool $logOnError = true, bool $logOnWarning = false
|
||||
, bool $logOnInfo = false, bool $logOnSuccess = false): MessageContainer
|
||||
{
|
||||
$this->logOnError = $logOnError;
|
||||
$this->logOnWarning = $logOnWarning;
|
||||
$this->logOnInfo = $logOnInfo;
|
||||
$this->logOnSuccess = $logOnSuccess;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of LongOnError()
|
||||
* @param bool $logOnError if true (default), then it saves the log file (using error_log)
|
||||
* @param boolean $logOnWarning If true then it also includes the log with warnings (default false).
|
||||
* @param bool $logOnInfo If true then it also includes the log with info (default false).
|
||||
* @param bool $logOnSuccess If true then it also includes the log with success (default false).
|
||||
* @return $this
|
||||
* @see MessageContainer::LogOnError
|
||||
*/
|
||||
public function setLog(bool $logOnError = true, bool $logOnWarning = false
|
||||
, bool $logOnInfo = false, bool $logOnSuccess = false): self
|
||||
{
|
||||
return $this->logOnError($logOnError, $logOnWarning, $logOnInfo, $logOnSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns an indexed array with the values of when the library must logs.
|
||||
* @return array [logOnError,logOnWarning,logOnInfo,logOnSuccess]
|
||||
*/
|
||||
public function getLog(): array
|
||||
{
|
||||
return [$this->logOnError, $this->logOnWarning, $this->logOnInfo, $this->logOnSuccess];
|
||||
}
|
||||
|
||||
public function backupLog(): MessageContainer
|
||||
{
|
||||
$this->backupLog = $this->getLog();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function restoreLog(): MessageContainer
|
||||
{
|
||||
$this->setLog(...$this->backupLog);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* You could add a message (including errors,warning, etc.) and store it in a $idLocker
|
||||
*
|
||||
* @param string $idLocker Identified of the locker (where the message will be stored)
|
||||
* @param string $message message to show. Example: 'the value is incorrect'.<br>
|
||||
* You can also use variables (if you are set a context). Ex: {{var1}} <br>
|
||||
* You can also show the idlocker. Ex: {{_idlocker}}<br>
|
||||
* @param string $level =['error','warning','info','success'][$i]
|
||||
* @param array|null $context [optional] it is an associative array with the values of the item<br>
|
||||
* For optimization, the context is not update if exists another context.
|
||||
*/
|
||||
public function addItem(string $idLocker, string $message, string $level = 'error', ?array $context = null): void
|
||||
{
|
||||
$idLocker = ($idLocker === '') ? '0' : $idLocker;
|
||||
if (!isset($this->items[$idLocker])) {
|
||||
$this->items[$idLocker] = new MessageLocker($idLocker, $context);
|
||||
} else {
|
||||
$this->items[$idLocker]->setContext($context);
|
||||
}
|
||||
// if the message contains a curly braces, then it is convert using the context.
|
||||
switch ($level) {
|
||||
case 'error':
|
||||
$this->errorCount++;
|
||||
$this->errorOrWarningCount++;
|
||||
$lastmsg = $this->items[$idLocker]->addError($message);
|
||||
if ($this->logOnError) {
|
||||
$this->log($level, $lastmsg);
|
||||
}
|
||||
if ($this->throwOnError) {
|
||||
throw new RuntimeException($lastmsg, 1);
|
||||
}
|
||||
break;
|
||||
case 'warning':
|
||||
$this->warningCount++;
|
||||
$this->errorOrWarningCount++;
|
||||
$this->items[$idLocker]->addWarning($message);
|
||||
if ($this->logOnWarning) {
|
||||
$this->log($level, $message);
|
||||
}
|
||||
if ($this->throwOnWarning) {
|
||||
throw new RuntimeException($message, 2);
|
||||
}
|
||||
break;
|
||||
case 'info':
|
||||
$this->infoCount++;
|
||||
$lastmsg = $this->items[$idLocker]->addInfo($message);
|
||||
if ($this->logOnInfo) {
|
||||
$this->log($level, $lastmsg);
|
||||
}
|
||||
break;
|
||||
case 'success':
|
||||
$this->successCount++;
|
||||
$lastmsg = $this->items[$idLocker]->addSuccess($message);
|
||||
if ($this->logOnSuccess) {
|
||||
$this->log($level, $lastmsg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It obtains all the ids for all the lockers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function allIds(): array
|
||||
{
|
||||
return array_keys($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of $this->getMessage()
|
||||
* @param string $idLocker ID of the locker
|
||||
* @return MessageLocker
|
||||
*/
|
||||
public function get(string $idLocker): MessageLocker
|
||||
{
|
||||
return $this->getLocker($idLocker);
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns a MessageLocker containing a locker.<br>
|
||||
* <b>If the locker doesn't exist then it returns an empty object (not null)</b>
|
||||
*
|
||||
* @param string $idLocker ID of the locker
|
||||
*
|
||||
* @return MessageLocker
|
||||
*/
|
||||
public function getLocker(string $idLocker = ''): MessageLocker
|
||||
{
|
||||
$idLocker = ($idLocker === '') ? '0' : $idLocker;
|
||||
return $this->items[$idLocker] ?? new MessageLocker($idLocker);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if the locker is defined
|
||||
* @param string $idLocker
|
||||
* @return bool
|
||||
*/
|
||||
public function hasLocker(string $idLocker): bool
|
||||
{
|
||||
return isset($this->items[$idLocker]);
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns a css class associated with the type of errors inside a locker<br>
|
||||
* If the locker contains more than one message, then it uses the most severe one (error,warning,etc.)<br>
|
||||
* The method uses the field <b>$this->cssClasses</b>, so you can change the CSS classes.
|
||||
* <pre>
|
||||
* $this->clsssClasses=['error'=>'class-red','warning'=>'class-yellow','info'=>'class-green','success'=>'class-blue'];
|
||||
* $css=$this->cssClass('customerId');
|
||||
* </pre>
|
||||
*
|
||||
* @param string $idLocker ID of the locker
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function cssClass(string $idLocker): string
|
||||
{
|
||||
$idLocker = ($idLocker === '') ? '0' : $idLocker;
|
||||
if (!isset($this->items[$idLocker])) {
|
||||
return '';
|
||||
}
|
||||
if (@$this->items[$idLocker]->countError()) {
|
||||
return $this->cssClasses['error'];
|
||||
}
|
||||
if ($this->items[$idLocker]->countWarning()) {
|
||||
return $this->cssClasses['warning'];
|
||||
}
|
||||
if ($this->items[$idLocker]->countInfo()) {
|
||||
return $this->cssClasses['info'];
|
||||
}
|
||||
if ($this->items[$idLocker]->countSuccess()) {
|
||||
return $this->cssClasses['success'];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the first message of error or empty if none<br>
|
||||
* If not, then it returns the first message of warning or empty if none
|
||||
*
|
||||
* @param string $default if not message is found, then it returns this value
|
||||
* @return string empty if there is none
|
||||
* @see MessageContainer::firstErrorText
|
||||
*/
|
||||
public function firstErrorOrWarning(string $default = ''): string
|
||||
{
|
||||
return $this->firstErrorText($default, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the first message of error or empty if none<br>
|
||||
* If not, then it returns the first message of warning or empty if none
|
||||
*
|
||||
* @param string $default if not message is found, then it returns this value
|
||||
* @return string empty if there is none
|
||||
* @see MessageContainer::firstErrorText
|
||||
*/
|
||||
public function lastErrorOrWarning(string $default = ''): string
|
||||
{
|
||||
$r = $this->allErrorArray(true, 'last');
|
||||
return $r[0] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the first message of error (as text) or empty if none
|
||||
*
|
||||
* @param string $default if not message is found, then it returns this value.
|
||||
* @param bool $includeWarning if true then it also includes warning but any error has priority.
|
||||
* @return string empty or default if there is none
|
||||
*/
|
||||
public function firstErrorText(string $default = '', bool $includeWarning = false): string
|
||||
{
|
||||
$r = $this->allErrorArray($includeWarning, 'first');
|
||||
return $r[0] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the last message of error (as text) or empty if none
|
||||
*
|
||||
* @param string $default if not message is found, then it returns this value.
|
||||
* @param bool $includeWarning if true then it also includes warning but any error has priority.
|
||||
* @return string empty (or default if there is none
|
||||
*/
|
||||
public function lastErrorText(string $default = '', bool $includeWarning = false): string
|
||||
{
|
||||
$r = $this->allErrorArray($includeWarning, 'last');
|
||||
return $r[0] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the first message of warning or empty if none
|
||||
*
|
||||
* @param string $default if not message is found, then it returns this value
|
||||
* @return string empty if there is none
|
||||
*/
|
||||
public function firstWarningText(string $default = ''): string
|
||||
{
|
||||
$r = $this->allWarningArray('first');
|
||||
return $r[0] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the last message of warning or empty if none
|
||||
*
|
||||
* @param string $default if not message is found, then it returns this value
|
||||
* @return string empty if there is none
|
||||
*/
|
||||
public function lastWarningText(string $default = ''): string
|
||||
{
|
||||
$r = $this->allWarningArray('last');
|
||||
return $r[0] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the first message of information or empty if none
|
||||
*
|
||||
* @param string $default if not message is found, then it returns this value
|
||||
* @return string empty if there is none
|
||||
*/
|
||||
public function firstInfoText(string $default = ''): string
|
||||
{
|
||||
$r = $this->allInfoArray('first');
|
||||
return $r[0] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the last message of information or empty if none
|
||||
*
|
||||
* @param string $default if not message is found, then it returns this value
|
||||
* @return string empty if there is none
|
||||
*/
|
||||
public function lastInfoText(string $default = ''): string
|
||||
{
|
||||
$r = $this->allInfoArray('last');
|
||||
return $r[0] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the first message of success or empty if none
|
||||
*
|
||||
* @param string $default if not message is found, then it returns this value
|
||||
* @return string empty if there is none
|
||||
*/
|
||||
public function firstSuccessText(string $default = ''): string
|
||||
{
|
||||
$r = $this->allSuccessArray('first');
|
||||
return $r[0] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the last message of success or empty if none
|
||||
*
|
||||
* @param string $default if not message is found, then it returns this value
|
||||
* @return string empty if there is none
|
||||
*/
|
||||
public function lastSuccessText(string $default = ''): string
|
||||
{
|
||||
$r = $this->allSuccessArray('last');
|
||||
return $r[0] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns an array with all messages of any type of all lockers
|
||||
*
|
||||
* @param string|null $level =[null,'error','warning','errorwarning','info','success'][$i] the level to show.<br>
|
||||
* Null means it shows all errors
|
||||
* @return string[] empty array if there is none
|
||||
*/
|
||||
public function allArray(?string $level = null): array
|
||||
{
|
||||
switch ($level) {
|
||||
case 'error':
|
||||
return $this->allErrorArray();
|
||||
case 'warning':
|
||||
return $this->allWarningArray();
|
||||
case 'errorwarning':
|
||||
return $this->allErrorOrWarningArray();
|
||||
case 'info':
|
||||
return $this->allInfoArray();
|
||||
case 'success':
|
||||
return $this->allSuccessArray();
|
||||
}
|
||||
$r = [];
|
||||
foreach ($this->items as $v) {
|
||||
$r = array_merge($r, $v->allError());
|
||||
$r = array_merge($r, $v->allWarning());
|
||||
$r = array_merge($r, $v->allInfo());
|
||||
$r = array_merge($r, $v->allSuccess());
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns an array with all messages of error of all lockers.
|
||||
*
|
||||
* @param bool $includeWarning if true then it also includes warnings.
|
||||
* @param string $position =['*','first','last'][$i] the value to read<br>
|
||||
* * = reads all the errors (or warnings)<br>
|
||||
* first = reads the first error (or warning)<br>
|
||||
* last = reads the last error (or warning)<br>
|
||||
*
|
||||
* @return array empty if there is none
|
||||
*/
|
||||
public function allErrorArray(bool $includeWarning = false, string $position = '*'): array
|
||||
{
|
||||
$r = [];
|
||||
if ($includeWarning) {
|
||||
foreach ($this->items as $v) {
|
||||
switch ($position) {
|
||||
case '*':
|
||||
$r = array_merge($r, $v->allErrorOrWarning());
|
||||
break;
|
||||
case 'first':
|
||||
$tmp = $v->firstErrorOrWarning();
|
||||
if ($tmp !== null) {
|
||||
return [$tmp];
|
||||
}
|
||||
break;
|
||||
case 'last':
|
||||
$tmp = $v->lastErrorOrWarning();
|
||||
if ($tmp !== null) {
|
||||
$r[] = $tmp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("MessageContainer::allErrorArray unknow type $position", 3);
|
||||
}
|
||||
}
|
||||
if ($position === 'last') {
|
||||
return end($r) ? [end($r)] : [];
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
foreach ($this->items as $v) {
|
||||
switch ($position) {
|
||||
case '*':
|
||||
$r = array_merge($r, $v->allError());
|
||||
break;
|
||||
case 'first':
|
||||
$tmp = $v->firstError();
|
||||
if ($tmp !== null) {
|
||||
return [$tmp];
|
||||
}
|
||||
break;
|
||||
case 'last':
|
||||
$tmp = $v->lastError();
|
||||
if ($tmp !== null) {
|
||||
$r[] = $tmp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("MessageContainer::allErrorArray unknow type $position", 4);
|
||||
}
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns an array with all messages of warning of all lockers.
|
||||
*
|
||||
* @return string[] empty array if there is none
|
||||
*/
|
||||
public function allWarningArray($position = '*'): array
|
||||
{
|
||||
$r = [];
|
||||
foreach ($this->items as $v) {
|
||||
switch ($position) {
|
||||
case '*':
|
||||
$r = array_merge($r, $v->allWarning());
|
||||
break;
|
||||
case 'first':
|
||||
$tmp = $v->firstWarning();
|
||||
if ($tmp !== null) {
|
||||
return [$tmp];
|
||||
}
|
||||
break;
|
||||
case 'last':
|
||||
$tmp = $v->lastWarning();
|
||||
if ($tmp !== null) {
|
||||
$r[] = $tmp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("MessageContainer::allWarningArray unknow type $position", 5);
|
||||
}
|
||||
}
|
||||
if ($position === 'last') {
|
||||
return end($r) ? [end($r)] : [];
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns an array with all messages of errors and warnings of all lockers.
|
||||
*
|
||||
* @return string[] empty array if there is none
|
||||
* @see MessageContainer::allErrorArray
|
||||
*/
|
||||
public function allErrorOrWarningArray(): array
|
||||
{
|
||||
return $this->allErrorArray(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns an array with all messages of info of all lockers.
|
||||
*
|
||||
* @return string[] empty array if there is none
|
||||
*/
|
||||
public function allInfoArray($position = '*'): array
|
||||
{
|
||||
$r = [];
|
||||
foreach ($this->items as $v) {
|
||||
switch ($position) {
|
||||
case '*':
|
||||
$r = array_merge($r, $v->allInfo());
|
||||
break;
|
||||
case 'first':
|
||||
$tmp = $v->firstInfo();
|
||||
if ($tmp !== null) {
|
||||
return [$tmp];
|
||||
}
|
||||
break;
|
||||
case 'last':
|
||||
$tmp = $v->lastInfo();
|
||||
if ($tmp !== null) {
|
||||
$r[] = $tmp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("MessageContainer::allInfoArray unknow type $position", 6);
|
||||
}
|
||||
}
|
||||
if ($position === 'last') {
|
||||
return end($r) ? [end($r)] : [];
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns an array with all messages of success of all lockers.
|
||||
*
|
||||
* @return string[] empty array if there is none
|
||||
*/
|
||||
public function allSuccessArray($position = '*'): array
|
||||
{
|
||||
$r = [];
|
||||
foreach ($this->items as $v) {
|
||||
switch ($position) {
|
||||
case '*':
|
||||
$r = array_merge($r, $v->allSuccess());
|
||||
break;
|
||||
case 'first':
|
||||
$tmp = $v->firstSuccess();
|
||||
if ($tmp !== null) {
|
||||
return [$tmp];
|
||||
}
|
||||
break;
|
||||
case 'last':
|
||||
$tmp = $v->lastSuccess();
|
||||
if ($tmp !== null) {
|
||||
$r[] = $tmp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("MessageContainer::allSuccessArray unknow type $position", 7);
|
||||
}
|
||||
}
|
||||
if ($position === 'last') {
|
||||
return end($r) ? [end($r)] : [];
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns an associative array of the form <br>
|
||||
* <pre>
|
||||
* [
|
||||
* ['id'=>'', // ID of the locker
|
||||
* 'level'=>'' // level of message (error, warning, info or success)
|
||||
* 'msg'=>'' // the message to show
|
||||
* ]
|
||||
* ]
|
||||
* </pre>
|
||||
*
|
||||
* @param string $level =['*','error','warning','errorwarning','info','success'][$i] '*' (default means all levels).
|
||||
* @return array
|
||||
*/
|
||||
public function allAssocArray(string $level = '*'): array
|
||||
{
|
||||
$result = [];
|
||||
foreach ($this->items as $v) {
|
||||
if ($level === 'error' || $level === 'errorwarning' || $level === '*') {
|
||||
$tmp = $v->allAssocArray('error');
|
||||
$result = array_merge($result, $tmp);
|
||||
}
|
||||
if ($level === 'warning' || $level === 'errorwarning' || $level === '*') {
|
||||
$tmp = $v->allAssocArray('warning');
|
||||
$result = array_merge($result, $tmp);
|
||||
}
|
||||
if ($level === 'info' || $level === '*') {
|
||||
$tmp = $v->allAssocArray('info');
|
||||
$result = array_merge($result, $tmp);
|
||||
}
|
||||
if ($level === 'success' || $level === '*') {
|
||||
$tmp = $v->allAssocArray('success');
|
||||
$result = array_merge($result, $tmp);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns true if there is an error (or error and warning).
|
||||
*
|
||||
* @param bool $includeWarning If true then it also returns if there is a warning
|
||||
* @return bool
|
||||
*/
|
||||
public function hasError(bool $includeWarning = false): bool
|
||||
{
|
||||
$tmp = $includeWarning
|
||||
? $this->errorCount
|
||||
: $this->errorOrWarningCount;
|
||||
return $tmp !== 0;
|
||||
}
|
||||
}
|
||||
+570
@@ -0,0 +1,570 @@
|
||||
<?php
|
||||
/** @noinspection UnknownInspectionInspection
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
|
||||
namespace eftec;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class MessageLocker
|
||||
*
|
||||
* @package eftec
|
||||
* @author Jorge Castro Castillo
|
||||
* @version 2.8 2024-03-02
|
||||
* @copyright (c) Jorge Castro C. MIT License https://github.com/EFTEC/MessageContainer
|
||||
* @see https://github.com/EFTEC/MessageContainer
|
||||
*/
|
||||
class MessageLocker
|
||||
{
|
||||
/**
|
||||
* @var array|null It is an associative array with the context of the locker.<br>
|
||||
* The context is only set once, it is for optimization. So, if the contexts contains information
|
||||
* (not null) then it is not updated.
|
||||
*/
|
||||
private ?array $context = null;
|
||||
/** @var mixed|null The id of the locker */
|
||||
private $idLocker;
|
||||
/** @var string[] */
|
||||
private array $errorMsg = [];
|
||||
/** @var string[] */
|
||||
private array $warningMsg = [];
|
||||
/** @var string[] */
|
||||
private array $infoMsg = [];
|
||||
/** @var string[] */
|
||||
private array $successMsg = [];
|
||||
|
||||
/**
|
||||
* MessageLocker constructor.
|
||||
* @param null|string $idLocker
|
||||
* @param array|null $context
|
||||
*/
|
||||
public function __construct(?string $idLocker = null, ?array &$context = null)
|
||||
{
|
||||
$this->idLocker = $idLocker;
|
||||
$this->resetAll();
|
||||
$this->setContext($context);
|
||||
}
|
||||
|
||||
/**
|
||||
* It clears all the messages. However, it doesn't recounter the MessageContainer
|
||||
* @return void
|
||||
*/
|
||||
public function resetAll(): void
|
||||
{
|
||||
$this->errorMsg = [];
|
||||
$this->warningMsg = [];
|
||||
$this->infoMsg = [];
|
||||
$this->successMsg = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* We set the context only if the current context is null.
|
||||
*
|
||||
* @param array|null $context The new context.
|
||||
*/
|
||||
public function setContext(?array &$context): void
|
||||
{
|
||||
if ($this->context === null) {
|
||||
$this->context =& $context;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It adds an error to the locker.
|
||||
*
|
||||
* @param string|null $msg The message to store
|
||||
* @return string|null returns the last message (processed)
|
||||
*/
|
||||
public function addError(?string $msg): ?string
|
||||
{
|
||||
$msg = $this->replaceCurlyVariable($msg);
|
||||
$this->errorMsg[] = $msg;
|
||||
return $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all variables defined between {{ }} by a variable inside the dictionary of values.<br>
|
||||
* Example:<br>
|
||||
* replaceCurlyVariable('hello={{var}}',['var'=>'world']) // hello=world<br>
|
||||
* replaceCurlyVariable('hello={{var}}',['varx'=>'world']) // hello=<br>
|
||||
* replaceCurlyVariable('hello={{var}}',['varx'=>'world'],true) // hello={{var}}<br>
|
||||
*
|
||||
* @param string|null $string The input value. It could contain variables defined as {{namevar}}
|
||||
* @return string|null
|
||||
* @see https://github.com/EFTEC/mapache-commons
|
||||
*/
|
||||
public function replaceCurlyVariable(?string $string): ?string
|
||||
{
|
||||
if($string===null) {
|
||||
return null;
|
||||
}
|
||||
if (strpos($string, '{{') === false) {
|
||||
return $string; // nothing to replace.
|
||||
}
|
||||
$string = str_replace('{{_idlocker}}', $this->idLocker, $string);
|
||||
return preg_replace_callback('/{{\s?(\w+)\s?}}/u', function ($matches) {
|
||||
if (is_array($matches)) {
|
||||
$item = substr($matches[0], 2, -2); // removes {{ and }}
|
||||
return $this->context[$item] ?? '';
|
||||
}
|
||||
$item = substr($matches, 2, -2); // removes {{ and }}
|
||||
return $this->context[$item] ?? '';
|
||||
}, $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* It adds a warning to the locker.
|
||||
*
|
||||
* @param string|null $msg The message to store
|
||||
* @return string|null returns the last message (processed)
|
||||
*/
|
||||
public function addWarning(?string $msg): ?string
|
||||
{
|
||||
$msg = $this->replaceCurlyVariable($msg);
|
||||
$this->warningMsg[] = $msg;
|
||||
return $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* It adds an information to the locker.
|
||||
*
|
||||
* @param string|null $msg The message to store
|
||||
* @return string|null returns the last message (processed)
|
||||
*/
|
||||
public function addInfo(?string $msg): ?string
|
||||
{
|
||||
$this->infoMsg[] = $this->replaceCurlyVariable($msg);
|
||||
return $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* It adds a success to the locker.
|
||||
*
|
||||
* @param string|null $msg The message to store
|
||||
* @return string|null returns the last message (processed)
|
||||
*/
|
||||
public function addSuccess(?string $msg): ?string
|
||||
{
|
||||
$this->successMsg[] = $this->replaceCurlyVariable($msg);
|
||||
return $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the number of errors or warnings contained in the locker
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countErrorOrWarning(): int
|
||||
{
|
||||
return $this->countError() + $this->countWarning();
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the number of errors contained in the locker
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countError(): int
|
||||
{
|
||||
return count($this->errorMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the number of warnings contained in the locker
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countWarning(): int
|
||||
{
|
||||
return count($this->warningMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the number of infos contained in the locker
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countInfo(): int
|
||||
{
|
||||
return count($this->infoMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the number of successes contained in the locker
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countSuccess(): int
|
||||
{
|
||||
return count($this->successMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of messages per level.
|
||||
* @param string $level =['*','error','warning','errorwarning','info','success'][$i]
|
||||
* @return int
|
||||
*/
|
||||
public function count(string $level):int
|
||||
{
|
||||
switch ($level) {
|
||||
case '*':
|
||||
return $this->countError()+$this->countWarning()+$this->countInfo()+$this->countSuccess();
|
||||
case 'error':
|
||||
return $this->countError();
|
||||
case 'errorwarning':
|
||||
return $this->countErrorOrWarning();
|
||||
case 'warning':
|
||||
return $this->countWarning();
|
||||
case 'info':
|
||||
return $this->countInfo();
|
||||
case 'success':
|
||||
return $this->countSuccess();
|
||||
}
|
||||
throw new RuntimeException("count with wrong type [$level]",22);
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the first message of any kind.<br>
|
||||
* If error then it returns the first message of error<br>
|
||||
* If not, if warning then it returns the first message of warning<br>
|
||||
* If not, then it shows the first info message (if any)<br>
|
||||
* If not, then it shows the first success message (if any)<br>
|
||||
* If not, then it shows the default message.
|
||||
*
|
||||
* @param string $defaultMsg
|
||||
* @param null|string $level =[null,'error','warning','errorwarning','info','success'][$i] the level to show,by
|
||||
* default it shows the first message of any level
|
||||
* , starting with error.
|
||||
* @return string
|
||||
*/
|
||||
public function first(string $defaultMsg = '', ?string $level = null): ?string
|
||||
{
|
||||
switch ($level) {
|
||||
case 'error':
|
||||
return $this->firstError($defaultMsg);
|
||||
case 'warning':
|
||||
return $this->firstWarning($defaultMsg);
|
||||
case 'errorwarning':
|
||||
return $this->firstErrorOrWarning($defaultMsg);
|
||||
case 'info':
|
||||
return $this->firstInfo($defaultMsg);
|
||||
case 'success':
|
||||
return $this->firstSuccess($defaultMsg);
|
||||
}
|
||||
$r = $this->firstErrorOrWarning();
|
||||
if ($r !== null) {
|
||||
return $r;
|
||||
}
|
||||
$r = $this->firstInfo();
|
||||
if ($r !== null) {
|
||||
return $r;
|
||||
}
|
||||
$r = $this->firstSuccess();
|
||||
return $r ?? $defaultMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the last message of any kind.<br>
|
||||
* If error then it returns the last message of error<br>
|
||||
* If not, if warning then it returns the last message of warning<br>
|
||||
* If not, then it shows the last info message (if any)<br>
|
||||
* If not, then it shows the last success message (if any)<br>
|
||||
* If not, then it shows the default message.
|
||||
*
|
||||
* @param string $defaultMsg
|
||||
* @param string $level =['*','error','warning','errorwarning','info','success'][$i]<br>
|
||||
* The level to show.<br>
|
||||
* By default it shows the last message of any level, starting with error.
|
||||
* @return string
|
||||
*/
|
||||
public function last(string $defaultMsg = '', string $level = '*'): ?string
|
||||
{
|
||||
switch ($level) {
|
||||
case 'error':
|
||||
return $this->lastError($defaultMsg);
|
||||
case 'warning':
|
||||
return $this->lastWarning($defaultMsg);
|
||||
case 'errorwarning':
|
||||
return $this->lastErrorOrWarning($defaultMsg);
|
||||
case 'info':
|
||||
return $this->lastInfo($defaultMsg);
|
||||
case 'success':
|
||||
return $this->lastSuccess($defaultMsg);
|
||||
case '*':
|
||||
$r = $this->lastErrorOrWarning();
|
||||
if ($r !== null) {
|
||||
return $r;
|
||||
}
|
||||
$r = $this->lastInfo();
|
||||
if ($r !== null) {
|
||||
return $r;
|
||||
}
|
||||
$r = $this->lastSuccess();
|
||||
return $r ?? $defaultMsg;
|
||||
}
|
||||
throw new RuntimeException("MessageLocker::last, method $level not defined",8);
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the first message of error, if any. Otherwise, it returns the default value
|
||||
*
|
||||
* @param string|null $default (optional) The default value is not found
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function firstError(?string $default = null): ?string
|
||||
{
|
||||
return $this->errorMsg[0] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the last message of error, if any. Otherwise, it returns the default value
|
||||
*
|
||||
* @param string|null $default (optional) The default value is not found
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function lastError(?string $default = null): ?string
|
||||
{
|
||||
return end($this->errorMsg) ?: $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the first message of warning, if any. Otherwise, it returns the default value
|
||||
*
|
||||
* @param string|null $default (optional) The default value is not found
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function firstWarning(?string $default = null): ?string
|
||||
{
|
||||
return $this->warningMsg[0] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the last message of error, if any. Otherwise, it returns the default value
|
||||
*
|
||||
* @param string|null $default (optional) The default value is not found
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function lastWarning(?string $default = null): ?string
|
||||
{
|
||||
return end($this->warningMsg) ?: $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the first message of error or warning (in this order), if any. Otherwise, it returns the default value
|
||||
*
|
||||
* @param string|null $default (optional) The default value is not found
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function firstErrorOrWarning(?string $default = null): ?string
|
||||
{
|
||||
$r = $this->firstError();
|
||||
if ($r === null) {
|
||||
$r = $this->firstWarning();
|
||||
}
|
||||
return $r ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the first message of error or warning (in this order), if any. Otherwise, it returns the default value
|
||||
*
|
||||
* @param string|null $default (optional) The default value is not found
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function lastErrorOrWarning(?string $default = null): ?string
|
||||
{
|
||||
$r = $this->lastError();
|
||||
if ($r === null) {
|
||||
$r = $this->lastWarning();
|
||||
}
|
||||
return $r ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the first message of info, if any. Otherwise, it returns the default value
|
||||
*
|
||||
* @param string|null $default (optional) The default value is not found
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function firstInfo(?string $default = null): ?string
|
||||
{
|
||||
return $this->infoMsg[0] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the last message of error, if any. Otherwise, it returns the default value
|
||||
*
|
||||
* @param string|null $default (optional) The default value is not found
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function lastInfo(?string $default = null): ?string
|
||||
{
|
||||
return end($this->infoMsg) ?: $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the first message of success, if any. Otherwise, it returns the default value
|
||||
*
|
||||
* @param string|null $default (optional) The default value is not found
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function firstSuccess(?string $default = null): ?string
|
||||
{
|
||||
return $this->successMsg[0] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the last message of error, if any. Otherwise, it returns the default value
|
||||
*
|
||||
* @param string|null $default (optional) The default value is not found
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function lastSuccess(?string $default = null): ?string
|
||||
{
|
||||
return end($this->successMsg) ?: $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all messages or an empty array if none.
|
||||
*
|
||||
* @param null|string $level =[null,'error','warning','errorwarning','info','success'][$i] the level to show. Null
|
||||
* means it shows all errors
|
||||
* @return string[]
|
||||
*/
|
||||
public function all(?string $level = null): array
|
||||
{
|
||||
switch ($level) {
|
||||
case 'error':
|
||||
return $this->allError();
|
||||
case 'warning':
|
||||
return $this->allWarning();
|
||||
case 'errorwarning':
|
||||
return $this->allErrorOrWarning();
|
||||
case 'info':
|
||||
return $this->allInfo();
|
||||
case 'success':
|
||||
return $this->allSuccess();
|
||||
}
|
||||
return @array_merge($this->errorMsg, $this->warningMsg, $this->infoMsg, $this->successMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all messages of errors (as an array of string), or an empty array if none.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function allError(): array
|
||||
{
|
||||
return $this->errorMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all messages of warning, or an empty array if none.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function allWarning(): array
|
||||
{
|
||||
return $this->warningMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all messages of errors or warnings, or an empty array if none
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function allErrorOrWarning(): array
|
||||
{
|
||||
return @array_merge($this->errorMsg, $this->warningMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all messages of info, or an empty array if none.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function allInfo(): array
|
||||
{
|
||||
return $this->infoMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all messages of success, or an empty array if none.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function allSuccess(): array
|
||||
{
|
||||
return $this->successMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns an associative array of the form:<br>
|
||||
* <pre>
|
||||
* [
|
||||
* ['id'=>'', // id of the locker
|
||||
* 'level'=>'' // level of message (error, warning, info or success)
|
||||
* 'msg'=>'' // the message to show
|
||||
* ]
|
||||
* ]
|
||||
* </pre>
|
||||
*
|
||||
* @param null|string $level =[null,'error','warning','errorwarning','info','success'][$i] the level to show.
|
||||
* Null means it shows all messages regardless of the level (starting with error)
|
||||
* @return array
|
||||
*/
|
||||
public function allAssocArray(?string $level = null): array
|
||||
{
|
||||
$result = [];
|
||||
if ($level === 'error' || $level === 'errorwarning' || $level === null) {
|
||||
$tmp = $this->allError();
|
||||
foreach ($tmp as $vmsg) {
|
||||
$result[] = ['id' => $this->idLocker, 'level' => 'error', 'msg' => $vmsg];
|
||||
}
|
||||
}
|
||||
if ($level === 'warning' || $level === 'errorwarning' || $level === null) {
|
||||
$tmp = $this->allWarning();
|
||||
foreach ($tmp as $vmsg) {
|
||||
$result[] = ['id' => $this->idLocker, 'level' => 'warning', 'msg' => $vmsg];
|
||||
}
|
||||
}
|
||||
if ($level === 'info' || $level === null) {
|
||||
$tmp = $this->allInfo();
|
||||
foreach ($tmp as $vmsg) {
|
||||
$result[] = ['id' => $this->idLocker, 'level' => 'info', 'msg' => $vmsg];
|
||||
}
|
||||
}
|
||||
if ($level === 'success' || $level === null) {
|
||||
$tmp = $this->allSuccess();
|
||||
foreach ($tmp as $vmsg) {
|
||||
$result[] = ['id' => $this->idLocker, 'level' => 'success', 'msg' => $vmsg];
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns true if there is an error (or error and warning).
|
||||
*
|
||||
* @param bool $includeWarning If true then it also returns if there is a warning
|
||||
* @return bool
|
||||
*/
|
||||
public function hasError(bool $includeWarning = false): bool
|
||||
{
|
||||
$tmp = $includeWarning
|
||||
? count($this->errorMsg)
|
||||
: count($this->errorMsg) + count($this->warningMsg);
|
||||
return $tmp !== 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user