PHP Classes

File: src/App/View/Helper/HtmlAttrHelper.php

Recommend this page to a friend!
  Packages of Thierry Feuzeu   Jaxon   src/App/View/Helper/HtmlAttrHelper.php   Download  
File: src/App/View/Helper/HtmlAttrHelper.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Jaxon
Call PHP classes from JavaScript using AJAX
Author: By
Last change:
Date: 4 months ago
Size: 5,379 bytes
 

Contents

Class file image Download
<?php

namespace Jaxon\App\View\Helper;

/**
 * HtmlAttrHelper.php
 *
 * Formatter for Jaxon custom HTML attributes.
 *
 * @package jaxon-core
 * @author Thierry Feuzeu
 * @copyright 2024 Thierry Feuzeu <thierry.feuzeu@gmail.com>
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
 * @link https://github.com/jaxon-php/jaxon-core
 */

use Jaxon\App\Component\Pagination;
use
Jaxon\App\NodeComponent;
use
Jaxon\Di\ComponentContainer;
use
Jaxon\Script\JsExpr;
use
Jaxon\Script\Call\JxnCall;

use function
array_reduce;
use function
count;
use function
htmlentities;
use function
is_a;
use function
is_string;
use function
Jaxon\rq;
use function
json_encode;
use function
trim;

class
HtmlAttrHelper
{
   
/**
     * @var string|null
     */
   
private string|null $sPaginationComponent = null;

   
/**
     * The constructor
     *
     * @param ComponentContainer $cdi
     */
   
public function __construct(protected ComponentContainer $cdi)
    {}

   
/**
     * Get the component HTML code
     *
     * @param JxnCall $xJsCall
     *
     * @return string
     */
   
public function html(JxnCall $xJsCall): string
   
{
       
$sClassName = $xJsCall->_class();
        if(!
$sClassName)
        {
            return
'';
        }

       
$xComponent = $this->cdi->makeComponent($sClassName);
        return
is_a($xComponent, NodeComponent::class) ?
            (string)
$xComponent->html() : '';
    }

   
/**
     * Attach a component to a DOM node
     *
     * @param JxnCall $xJsCall
     * @param string $item
     *
     * @return string
     */
   
public function bind(JxnCall $xJsCall, string $item = ''): string
   
{
       
$item = trim($item);
        return
'jxn-bind="' . $xJsCall->_class() . (!$item ? '"' : '" jxn-item="' . $item . '"');
    }

   
/**
     * Attach the pagination component to a DOM node
     *
     * @param JxnCall $xJsCall
     *
     * @return string
     */
   
public function pagination(JxnCall $xJsCall): string
   
{
       
// The pagination is always rendered with the same Pagination component.
       
$sComponent = $this->sPaginationComponent ?:
            (
$this->sPaginationComponent = rq(Pagination::class)->_class());
       
$sItem = $xJsCall->_class();
        return
"jxn-bind=\"$sComponent\" jxn-item=\"$sItem\"";
    }

   
/**
     * Set a selector for the next event handler
     *
     * @param string $sSelector
     *
     * @return EventAttr
     */
   
public function select(string $sSelector): EventAttr
   
{
        return new
EventAttr($sSelector);
    }

   
/**
     * Set an event handler
     *
     * @param string $event
     * @param JsExpr $xJsExpr
     *
     * @return string
     */
   
public function on(string $event, JsExpr $xJsExpr): string
   
{
       
$event = trim($event);
       
$sCall = htmlentities(json_encode($xJsExpr->jsonSerialize()));
        return
"jxn-on=\"$event\" jxn-call=\"$sCall\"";
    }

   
/**
     * Shortcut to set a click event handler
     *
     * @param JsExpr $xJsExpr
     *
     * @return string
     */
   
public function click(JsExpr $xJsExpr): string
   
{
        return
$this->on('click', $xJsExpr);
    }

   
/**
     * @param array $aHandler
     *
     * @return bool
     */
   
private function eventIsValid(array $aHandler): bool
   
{
        return
count($aHandler) === 3 &&
            isset(
$aHandler[0]) && isset($aHandler[1]) && isset($aHandler[2]) &&
           
is_string($aHandler[0]) && is_string($aHandler[1]) &&
           
is_a($aHandler[2], JsExpr::class);
    }

   
/**
     * @param array $aHandler
     * @param EventAttr|null $xAttr
     *
     * @return EventAttr|null
     */
   
private function setEventHandler(array $aHandler, ?EventAttr $xAttr = null): EventAttr|null
   
{
        if(!
$this->eventIsValid($aHandler))
        {
            return
$xAttr;
        }
       
// The array content is valid.
       
[$sSelector, $sEvent, $xJsExpr] = $aHandler;
        return !
$xAttr ?
           
$this->select($sSelector)->on($sEvent, $xJsExpr) :
           
$xAttr->select($sSelector)->on($sEvent, $xJsExpr);
    }

   
/**
     * Set an event handler
     *
     * @param array $aHandler
     *
     * @return string
     */
   
public function event(array $aHandler): string
   
{
        return
$this->setEventHandler($aHandler)?->__toString() ?? '';
    }

   
/**
     * Set event handlers
     *
     * @param array $aHandlers
     *
     * @return string
     */
   
public function events(array $aHandlers): string
   
{
        return
array_reduce($aHandlers, fn(EventAttr|null $xAttr, array $aHandler)
            =>
$this->setEventHandler($aHandler, $xAttr), null)?->__toString() ?? '';
    }

   
/**
     * Get the HTML or Javascript ready code for a package
     *
     * @param string $sClass
     * @param string $sType
     *
     * @return string
     */
   
public function package(string $sClass, string $sType = 'html'): string
   
{
       
$sCode = match($sType) {
           
'html' => jaxon()->package($sClass)?->getHtml() ?? '',
           
'ready' => jaxon()->package($sClass)?->getReadyScript() ?? '',
            default =>
''
       
};
       
$sCode = trim($sCode);

        return
$sType !== 'ready' || $sCode === '' ? $sCode :
           
// Call the ready code with the jaxon.dom.ready function.
           
"jaxon.dom.ready(() => $sCode)";
    }
}