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;
}
}