HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux dev1 5.15.83-1-pve #1 SMP PVE 5.15.83-1 (2022-12-15T00:00Z) x86_64
User: safarimaris (1000)
PHP: 7.2.34-54+ubuntu22.04.1+deb.sury.org+1
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,
Upload Files
File: /home/safarimaris/home/safarimaris/common/models/Product.php
<?php

namespace common\models;

use Yii;
use yii\data\ArrayDataProvider;
use yii\helpers\ArrayHelper;
use yii\helpers\Url;

/**
 * This is the model class for table "product".
 *
 * @property integer $id
 * @property integer $entityId
 * @property string $name
 * @property string $slug
 * @property string $descr
 * @property string $include
 * @property string $notInclude
 * @property string $additionalCost
 * @property string $itinerary
 * @property string $departurePort
 * @property string $arrivalPort
 * @property integer $transferType
 * @property string $transferFrom
 * @property string $transferTo
 * @property string $checkInOut
 * @property integer $countDive
 * @property integer $minCertificate
 * @property integer $minDive
 * @property string $logo
 * @property string $notice
 * @property integer $divebookerId
 * @property string $seoUrl
 * @property string $seoTitle
 * @property string $seoDescription
 * @property boolean $main
 * @property boolean $showTours
 * @property string $benefits
 *
 * @property Entity $entity
 * @property ProductSite[] $productSites
 * @property Site[] $sites
 * @property ProductFeature[] $productFeatures
 * @property Feature[] $features
 * @property ProductTag[] $productTags
 * @property Tag[] $tags
 * @property TourOpen[] $tourOpens
 * @property Feature[] $feature_ids
 * @property Tag[] $tag_ids
 * @property Site[] $site_ids
 * @property Days[] $days
 */
class Product extends \yii\db\ActiveRecord
{
    private $_url;
    public $ym;

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'product';
    }

    public function behaviors()
    {
        return [
            [
                'class' => \mongosoft\file\UploadImageBehavior::className(),
                'attribute' => 'logo',
                'scenarios' => ['update', 'create'],
                'path' => '@imgPath/product',
                'url' => '@imgUrl/product',
                'thumbs' => Yii::$app->params['thumbs'],
            ],
            'galleryBehavior' => [
                'class' => \zxbodya\yii2\galleryManager\GalleryBehavior::className(),
                'type' => 'product',
                'extension' => 'jpg',
                'directory' => Yii::getAlias('@imgPath') . '/product/gallery',
                'url' => Yii::getAlias('@imgUrl') . '/product/gallery',
                'versions' => Yii::$app->params['gallery'],
                'hasName' => true,
                'hasDescription' => false,
            ],
            [
                'class' => \voskobovich\behaviors\ManyToManyBehavior::className(),
                'relations' => [
                    'feature_ids' => 'features'
                ],
            ],
            [
                'class' => \voskobovich\behaviors\ManyToManyBehavior::className(),
                'relations' => [
                    'tag_ids' => 'tags'
                ],
            ],
            [
                'class' => \voskobovich\behaviors\ManyToManyBehavior::className(),
                'relations' => [
                    'site_ids' => 'sites'
                ],
            ],
        ];
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['entityId', 'name'], 'required', 'on'=>array('create', 'update')],
            [['entityId', 'transferType', 'countDive', 'minCertificate', 'minDive', 'divebookerId', 'main', 'showTours'], 'integer'],
            [['descr', 'include', 'notInclude', 'additionalCost', 'itinerary', 'slug', 'notice'], 'string'],
            [['name', 'departurePort', 'arrivalPort', 'transferFrom', 'transferTo', 'checkInOut', 'seoUrl', 'seoTitle', 'seoDescription', 'benefits'], 'string', 'max' => 255],
            [
                'seoUrl',
                'match', 'not' => true, 'pattern' => '/[^a-zA-Z0-9_-]/',
                'message' => Yii::t('app', 'Not valid url'),
            ],
            [['seoUrl'], 'unique'],
            [['entityId'], 'exist', 'skipOnError' => true, 'targetClass' => Entity::className(), 'targetAttribute' => ['entityId' => 'id']],
            [['feature_ids','site_ids','tag_ids'], 'each', 'rule' => ['integer']],
            [['logo'], 'file', 'skipOnEmpty' => true, 'extensions' => 'png, jpg'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        $entity = $this->entity;
        return [
            'id' => Yii::t('model', 'ID'),
            'entityId' => Yii::t('model', 'Entity ID'),
            'name' => Yii::t('model', 'Name'),
            'slug' => Yii::t('model', 'Slug'),
            'descr' => Yii::t('model', 'Descr'),
            'include' => Yii::t('model', 'Include'),
            'notInclude' => Yii::t('model', 'Not Include'),
            'additionalCost' => Yii::t('model', 'Additional Cost'),
            'feature_ids' => Yii::t('app', 'Features'),
            'tag_ids' => Yii::t('model', 'Tags'),
            'days' => Yii::t('model', 'Days'),
            'itinerary' => Yii::t('model', 'Itinerary'),
            'departurePort' => Yii::t('model', $entity && $entity->type == 2 ? 'Departure Airport' : 'Departure Port'),
            'arrivalPort' => Yii::t('model', $entity && $entity->type == 2 ? 'Arrival Airport' : 'Arrival Port'),
            'transferType' => Yii::t('model', 'Transfer Type'),
            'transferFrom' => Yii::t('model', 'Transfer From'),
            'transferTo' => Yii::t('model', 'Transfer To'),
            'checkInOut' => Yii::t('model', 'Check In Out'),
            'site_ids' => Yii::t('model', 'Site'),
            'countDive' => Yii::t('model', 'Count Dive'),
            'minCertificate' => Yii::t('model', 'Min Certificate'),
            'benefits' => Yii::t('model', 'Benefits'),
            'minDive' => Yii::t('model', 'Min Dive'),
            'sites' => Yii::t('model', 'Sites'),
            'logo' => Yii::t('model', 'Logo'),
            'notice' => Yii::t('model', 'Notice'),
            'divebookerId' => Yii::t('model', 'DivebookerId'),
            'seoUrl' => Yii::t('model', 'Seo Url'),
            'seoTitle' => Yii::t('model', 'Seo Title'),
            'seoDescription' => Yii::t('model', 'Seo Description'),
            'main' => Yii::t('model', 'Display on the main page'),
            'showTours' => Yii::t('model', 'Display tours'),
        ];
    }

    public function init()
    {
        parent::init();
        if (Yii::$app instanceof \yii\console\Application) {
            $this->ym = date('Ym');
        } else {
            $this->ym = Yii::$app->request->get('ym') ? Yii::$app->request->get('ym') : (isset($_COOKIE['ym']) ? $_COOKIE['ym'] : date('Ym'));
            if ($this->ym < date('Ym')) {
                $this->ym = date('Ym');
            }
        }

    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getEntity()
    {
        return $this->hasOne(Entity::className(), ['id' => 'entityId']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getProductSites()
    {
        return $this->hasMany(ProductSite::className(), ['productId' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getSites()
    {
        return $this->hasMany(Site::className(), ['id' => 'siteId'])->viaTable('{{%product_site_link}}', ['productId' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getProductFeatures()
    {
        return $this->hasMany(ProductFeature::className(), ['productId' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getFeatures()
    {
        return $this->hasMany(Feature::className(), ['id' => 'tagId'])->viaTable('{{%product_feature_link}}', ['productId' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getProductTags()
    {
        return $this->hasMany(ProductTag::className(), ['productId' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getTags()
    {
        return $this->hasMany(Tag::className(), ['id' => 'tagId'])->viaTable('{{%product_tag_link}}', ['productId' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getTourOpens()
    {
        return $this->hasMany(TourOpen::className(), ['productId' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getDays()
    {
        return $this->hasMany(Days::className(), ['productId' => 'id']);
    }

    public function showSiteNames()
    {
        $list = [];
        foreach ($this->sites as $site) {
            array_push($list, $site->name);
        }
        return join(', ', $list);
    }

    public function showFeatureNames()
    {
        $list = [];
        foreach ($this->features as $tag) {
            array_push($list, $tag->name);
        }
        return join(', ', $list);
    }

    public function li($fld)
    {
        if ($this->$fld) {
            return explode("\n", trim(strip_tags($this->$fld)));
        }
        return [];
    }

    public function getUrl()
    {
        if ($this->_url === null)
            $this->_url = Url::to(['product/show', 'country' => $this->country->url, 'url' => $this->seoUrl], true);

        return $this->_url;
    }

    /**
     * @return array
     */
    public function getGroupedTours()
    {
        $data = [];

        $query = (new \yii\db\Query())
            ->select(['t.*'])
            ->from('{{tour}} t')
            ->leftJoin('{{%tour_open}} op', 'op.tourId=t.id')
            ->where('t.productId = :productId AND t.isDelete = 0 && price > 0', [':productId' => $this->id])
            ->orderBy('t.startDate');

        if ($this->ym) {
            $query->andWhere('(t.ym >= :ym AND startDate >= NOW() - INTERVAL 1 DAY) OR t.isOpenDate = 1', [':ym' => $this->ym]);
        }
        if (!Yii::$app->sys->isInstructor()) {
            $query->andWhere('t.isInstructor != 1');
        }
        //reset date if no result
        if (!$query->count()) {
            $query = (new \yii\db\Query())
                ->select(['t.*'])
                ->from('{{tour}} t')
                ->leftJoin('{{%tour_open}} op', 'op.tourId=t.id')
                ->andWhere('t.productId = :productId AND t.isDelete = 0', [':productId' => $this->id])
                ->orderBy('t.startDate');

            $query->andWhere('(t.ym >= :ym AND startDate > NOW() - INTERVAL 1 DAY) OR t.isOpenDate = 1', [':ym' => date('Ym')]);

            if (!Yii::$app->sys->isInstructor()) {
                $query->andWhere('t.isInstructor != 1');
            }
        }

        //group tours
        $duration = null;
        foreach ($query->all() as $item) {
            $start = strtotime($item['startDate']);
            $ym = $item['isOpenDate'] ? 'od' : $item['ym'];
            $data[$ym]['year'] = $item['isOpenDate'] ? ''
                : Yii::$app->formatter->asDate($item['startDate'], 'php:Y');
            $data[$ym]['dayStart'] = $item['isOpenDate'] ? Yii::t('app', 'Open dates')
                : (
                    date('d ', $start)
                );
            $data[$ym]['monthStart'] = $item['isOpenDate'] ? Yii::t('app', 'Open dates')
                : (
                    Yii::t('app', date('M', $start))
                );
            $data[$ym]['dayEnd'] = $item['isOpenDate'] ? Yii::t('app', 'Open dates')
                : (
                    date('d ', strtotime('+'.($item['duration']-1).' day',$start))
                );
            $data[$ym]['monthEnd'] = $item['isOpenDate'] ? Yii::t('app', 'Open dates')
                : (
                    Yii::t('app', date('M', strtotime('+'.($item['duration']-1).' day',$start)))
                );
            if(!$duration){
                $duration = $item['duration'];
            }
            $data[$ym]['items'][] = [
                'id' => $item['id'],
                'productId' => $this->id,
                'name' => $this->name?:$item['name'],
                'startDate' => ($item['isOpenDate']) ? '' : date('d', strtotime($item['startDate'])). ' '.Yii::t('app', date('M', strtotime($item['startDate']))),
                'isOpenDate' => $item['isOpenDate'],
                'duration' => $item['duration'],
                'price' => $item['price'],
                'logo' => "/images/product/h128-".$this->logo,
                'salePrice' => $item['salePrice'],
                'spaces' => $item['spaces'],
                'isSpecial' => $item['isSpecial'],
                'isCompatriot' => $item['isCompatriot'],
                'notice' => $item['notice'],
                'isSale' => $item['salePrice'] && $item['isSpecial']
            ];
        }

        return [
            'duration' => $duration,
            'main' => array_slice($data, 0, 2, true),
            'all' => array_slice($data, 2, null, true)
        ];
    }

    /**
     * @return ArrayDataProvider
     */
    public function getToursData()
    {
        $data = [];

        $query = (new \yii\db\Query())
            ->select(['t.*'])
            ->from('{{tour}} t')
            ->leftJoin('{{%tour_open}} op', 'op.tourId=t.id')
            ->where('t.productId = :productId AND t.isDelete = 0 && price > 0', [':productId' => $this->id])
            ->orderBy('t.startDate');

        $query->andWhere('(startDate >= NOW() - INTERVAL 1 DAY) OR t.isOpenDate = 1');

        if (!Yii::$app->sys->isInstructor()) {
            $query->andWhere('t.isInstructor != 1');
        }
        //reset date if no result
        if (!$query->count()) {
            $query = (new \yii\db\Query())
                ->select(['t.*'])
                ->from('{{tour}} t')
                ->leftJoin('{{%tour_open}} op', 'op.tourId=t.id')
                ->andWhere('t.productId = :productId AND t.isDelete = 0', [':productId' => $this->id])
                ->orderBy('t.startDate');

            $query->andWhere('(startDate > NOW() - INTERVAL 1 DAY) OR t.isOpenDate = 1');

            if (!Yii::$app->sys->isInstructor()) {
                $query->andWhere('t.isInstructor != 1');
            }
        }

        //group tours
        foreach ($query->all() as $item) {
            $start = strtotime($item['startDate']);
            $isOpenDate = $item['isOpenDate'];

            $data[] = [
                'id' => $item['id'],
                'year' => $isOpenDate ? '' : Yii::$app->formatter->asDate($item['startDate'], 'php:Y'),
                'dayStart' => $isOpenDate ? Yii::t('app', 'Open dates') : date('d ', $start),
                'monthStart' => $isOpenDate ? Yii::t('app', 'Open dates') : Yii::t('app', date('M', $start)),
                'dayEnd' => $isOpenDate ? Yii::t('app', 'Open dates') : date('d ', strtotime('+'.($item['duration']-1).' day',$start)),
                'monthEnd' => $isOpenDate ? Yii::t('app', 'Open dates')
                    : Yii::t('app', date('M', strtotime('+'.($item['duration']-1).' day',$start))),
                'productId' => $this->id,
                'name' => $this->name?:$item['name'],
                'startDate' => $isOpenDate ? '' : date('d', $start). ' '.Yii::t('app', date('M', $start)),
                'isOpenDate' => $isOpenDate,
                'duration' => $item['duration'],
                'price' => $item['price'],
                'logo' => "/images/product/h128-".$this->logo,
                'salePrice' => $item['salePrice'],
                'spaces' => $item['spaces'],
                'isSpecial' => $item['isSpecial'],
                'isCompatriot' => $item['isCompatriot'],
                'notice' => $item['notice'],
                'isSale' => $item['salePrice'] && $item['isSpecial']
            ];
        }

        return new ArrayDataProvider([
            'allModels' => $data,
            'pagination' => [
                'pageSize' => 4,
            ],
            'sort' => [
                'attributes' => ['startDate'],
            ],
        ]);
    }

    /**
     * @return array
     */
    public function getByTags()
    {
        if(!$this->tag_ids) return [];

        $query = (new \yii\db\Query())
            ->select(['p.id', 'productName' => 'p.name','e.name', 'p.seoUrl','c.url'])
            ->from('{{product}} p')
            ->leftJoin('{{%entity}} e', 'p.entityId=e.id')
            ->leftJoin('{{%country}} c', 'e.countryId=c.id')
            ->leftJoin('{{%product_tag_link}} ptl', 'ptl.productId=p.id')
            ->where('ptl.tagId IN ('.implode(',',$this->tag_ids).') AND ptl.productId != :id', [':id' => $this->id]);

        return $query->all();
    }

    public function getGroupedImages()
    {
        $data = $this->images;
        return [
            'main' => array_slice($data, 0, 6, true),
            'all' => array_slice($data, 6, null, true)
        ];
    }
    /**
     * Creates and populates a set of models.
     *
     * @param string $modelClass
     * @param array $multipleModels
     * @return array
     */
    public static function createMultiple($modelClass, $multipleModels = [])
    {
        $model    = new $modelClass;
        $formName = $model->formName();
        $post     = Yii::$app->request->post($formName);
        $models   = [];

        if (! empty($multipleModels)) {
            $keys = array_keys(ArrayHelper::map($multipleModels, 'id', 'id'));
            $multipleModels = array_combine($keys, $multipleModels);
        }

        if ($post && is_array($post)) {
            foreach ($post as $i => $item) {
                if (isset($item['id']) && !empty($item['id']) && isset($multipleModels[$item['id']])) {
                    $models[] = $multipleModels[$item['id']];
                } else {
                    $models[] = new $modelClass;
                }
            }
        }

        unset($model, $formName, $post);

        return $models;
    }
}