PHP code example of arrilot / bitrix-models

1. Go to this page and download the library: Download arrilot/bitrix-models library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

arrilot / bitrix-models example snippets


Arrilot\BitrixModels\Models\ElementModel
Arrilot\BitrixModels\Models\SectionModel
Arrilot\BitrixModels\Models\UserModel
Arrilot\BitrixModels\Models\D7Model



use Arrilot\BitrixModels\Models\ElementModel;

class Product extends ElementModel
{
    /**
     * Corresponding iblock id.
     *
     * @return int
     */
    const IBLOCK_ID = 1;
}

// $fields - массив, аналогичный передаваемому в CIblockElement::Add(), но IBLOCK_ID в нём можно не указывать.
$product = Product::create($fields);

$product = Product::create($fields)
$product->refresh();

// вариант 1
$product['NAME'] = 'Новое имя продукта';
$product->save();

// вариант 2
$product->update(['NAME' => 'Новое имя продукта']);

$product = new Product($id);

//теперь есть возможно работать с моделью, допустим
$product->deactivate();

$product = new Product($id);

// метод `load` обращается к базе, только если информация еще не была получена.
$product->load();

// Если мы хотим принудительно обновить информацию из базы даже если она уже была получена ранее
$product->refresh();

// После любого из этих методов, мы можем работать с полученными полями (`echo $product['CODE'];`)

//Для текущего пользователья есть отдельный хэлпер
$user = User::current();
// В итоге мы получаем инстанс User с заполненными полями. 
// Сколько бы раз мы не вызывали `User::current()` в рамках работы скрипта, запрос в базу происходит только один раз - первый.
// `User::freshCurrent()` - то же самое, но получает данные из базы каждый раз.

$product->load();
if ($product['CODE'] === 'test') {
    $product->deactivate();
}

$array = $product->toArray();
$json = $product->toJson();

$products = Product::query()->select('ID')->getList();

$products = Product::select('ID')->getList();

        public static $fetchUsing = 'GetNext';
    
        // полная форма, если нужно менять параметры.
        public static $fetchUsing = [
            'method' => 'GetNext',
            'params' => [true, true],
        ];
    

         Products::query()->filter(['ACTIVE' => 'Y'])->fetchUsing('GetNext')->getList()`
         // вместо строки `'GetNext'` можно как и в первом случае использовать массив.
    

    /**
     * Scope to get only active items.
     *
     * @param BaseQuery $query
     *
     * @return BaseQuery
     */
    public function scopeActive($query)
    {
        $query->filter['ACTIVE'] = 'Y';
    
        return $query;
    }

...

$products = Product::filter(['SECTION_ID' => $secId])
                    ->active()
                    ->getList();


    /**
     * @param ElementQuery $query
     * @param string|array $category
     *
     * @return ElementQuery
     */
    public function scopeFromSectionWithCode($query, $category)
    {
        $query->filter['SECTION_CODE'] = $category;

        return $query;
    }

...
$users = Product::fromSectionWithCode('sale')->getList();

    public function scopeFromCategory($query, $category)
    {
        if (!$category) {
            return false;
        }
        
        $query->filter['SECTION_CODE'] = $category;

        return $query;
    }
...


    public function getXmlIdAttribute($value)
    {
        return (int) $value;  
    }
    
    // теперь в $product['XML_ID'] всегда будет целочисленное значение
    

    public function getFullNameAttribute()
    {
        return $this['NAME']." ".$this['LAST_NAME'];
    }
    
    ...
    
    echo $user['NAME']; // John
    echo $user['LAST_NAME']; // Doe
    echo $user['FULL_NAME']; // John Doe

    protected $appends = ['FULL_NAME'];

class News extends ElementModel
{
    /**
     * Hook into before item create or update.
     *
     * @return mixed
     */
    protected function onBeforeSave()
    {
        $this['CODE'] = CUtil::translit($this['NAME'], "ru");
    }

    /**
     * Hook into after item create or update.
     *
     * @param bool $result
     *
     * @return void
     */
    protected function onAfterSave($result)
    {
        //
    }
}

class Subscriber extends D7Model
{
    public static function tableClass()
    {
        $hlBlock = HighloadBlockTable::getRowById(1);
    
        return HighloadBlockTable::compileEntity($hlBlock)->getDataClass();
    }
}

class Subscriber extends D7Model
{
    public static function tableClass()
    {
        return highloadblock_class('app_subscribers');
    }
}

$subscribers = Subscriber::query()->cache(5)->filter(['=NAME'=>'John])->getList();

/**
 * static int count()
 *
 * D7Query methods
 * @method static D7Query runtime(array|\Bitrix\Main\Entity\ExpressionField $fields)
 * @method static D7Query enableDataDoubling()
 * @method static D7Query disableDataDoubling()
 * @method static D7Query cacheJoins(bool $value)
 *
 * BaseQuery methods
 * @method static Collection getList()
 * @method static D7Model first()
 * @method static D7Model getById(int $id)
 * @method static D7Query sort(string|array $by, string $order='ASC')
 * @method static D7Query order(string|array $by, string $order='ASC') // same as sort()
 * @method static D7Query filter(array $filter)
 * @method static D7Query addFilter(array $filters)
 * @method static D7Query resetFilter()
 * @method static D7Query navigation(array $filter)
 * @method static D7Query select($value)
 * @method static D7Query keyBy(string $value)
 * @method static D7Query limit(int $value)
 * @method static D7Query offset(int $value)
 * @method static D7Query page(int $num)
 * @method static D7Query take(int $value) // same as limit()
 * @method static D7Query forPage(int $page, int $perPage=15)
 * @method static \Illuminate\Pagination\LengthAwarePaginator paginate(int $perPage = 15, string $pageName = 'page')
 * @method static \Illuminate\Pagination\Paginator simplePaginate(int $perPage = 15, string $pageName = 'page')
 * @method static D7Query stopQuery()
 * @method static D7Query cache(float|int $minutes)
 */

/**
 * Class Product
 *
 * @property Brand $brand
 * @property ProductQuestion $questions
 * @property Storage $storages
 */
class Product extends ElementModel
{
    ...
    
    /**
     * ID Brand записан в текущую модель в свойтво PROPERTY_BRAND_VALUE (не множественное)
     * (у товара может быть только один бренд, но у бренда много товаров)
     */
    public function brand()
    {
        return $this->hasOne(Brand::class, 'ID', 'PROPERTY_BRAND_VALUE');
    }
    
    /**
     * У ProductQuestion в свойтве PROPERTY_PRODUCT_VALUE записан ID текущей модели
     * (у товара может быть много вопросов, но вопрос относится только к одному товару)
     *
     * Но это будет так же работать, если PROPERTY_PRODUCT_VALUE будет множественным
     */
    public function questions()
    {
        return $this->hasMany(ProductQuestion::class, 'PROPERTY_PRODUCT_VALUE', 'ID');
    }
    
    /**
     * ID Storage записан в текущую модель в свойтво PROPERTY_STORAGE_VALUE (множественное)
     * (у товара может быть много складов, на складе может быть много товаров)
     */
    public function storages()
    {
        return $this->hasMany(Storage::class, 'ID', 'PROPERTY_STORAGE_VALUE');

    }
}

$product = Product::getById(1);

// В этот момент используются магические методы и выполняются sql запросы в БД за данными.
$product->brand; // Объект класса Brand
$product->questions; // Collection объектов класса ProductQuestion

// Запросы в базу выполняются лишь один раз. При повторном обращении к переменной возвращаются данные получененные при первом запросе. 
$product->brand;
$product->questions;

$products = Product::getList();

foreach($products as $product) {
    // Выполняется запрос
    $product->brand;
}

// Выполняется один дополнительный запрос который получит все бренды для всех полученных продуктов.
$products = Product::query()->with('brand')->getList();

foreach($products as $product) {
    // Запрос не выполняется
    $product->brand;
}

->with([
    'questions' => function ($query) {
        $query->filter(['ACTIVE' => 'Y'])
    },
    'questions.answers'
])



use Arrilot\BitrixModels\Models\EloquentModel;

class Product extends EloquentModel
{
    protected $table = 'app_products';
}



use Arrilot\BitrixModels\Models\EloquentModel;

class Brand extends EloquentModel
{
    public $timestamps = false;
}

$brand = new Brand();
$brand['UF_NAME'] = 'Nike';
$brand->save();

// либо даже такого если настроены $fillable поля.
$brand = Brand::create(['UF_NAME' => 'Nike']);

DB::table('brands')->insert(['UF_NAME' => 'Nike']);

'connections' => [
    'value' => [
        'default' => [
            'className' => '\\Bitrix\\Main\\DB\\MysqliConnection',
            'host' => 'localhost',
            'database' => 'db',
            'login' => 'login',
            'password' => 'password',
            'options' => 2,
        ],
    ],
    'readonly' => true,
]

[
    ...
    'bitrix-models.illuminate-database' => [
        'value' => [
                'default' => 'mysql',
                'connections' => [
                    'mysql' => [
                        'driver' => 'mysql',
                        'url' => getenv('DB_MYSQL_URL'),
                        'host' => getenv('DB_MYSQL_HOST'),
                        'port' => getenv('DB_MYSQL_PORT'),
                        'database' => getenv('DB_MYSQL_DATABASE'),
                        'username' => getenv('DB_MYSQL_USERNAME'),
                        'password' => getenv('DB_MYSQL_PASSWORD'),
                        'unix_socket' => getenv('DB_MYSQL_SOCKET'),
                        'charset' => 'utf8',
                        'collation' => 'utf8_unicode_ci',
                        'prefix' => '',
                        'prefix_indexes' => true,
                        'strict' => false,
                        'engine' => null,
                        'options' => [],
                    ],
                    'mysql_2' => [
                        ...
                    ],
                ],
            ],
        'readonly' => true,
    ],
]

// используем далее $section['UF_TITLE'];
public function getUfTitleAttribute()
{
    return $this['UF_TITLE_' . strtoupper(LANGUAGE_ID)];
}

// используем далее $element['PROPERTY_TITLE'];
public function getPropertyTitleAttribute()
{
    return $this['PROPERTY_TITLE_' . strtoupper(LANGUAGE_ID) . '_VALUE'];
}