Live News for Yii Framework News, fresh extensions and wiki articles about Yii framework. Tue, 13 Nov 2018 22:09:40 +0000 Zend_Feed_Writer 2 (http://framework.zend.com) https://www.yiiframework.com/ [extension] matthew-p/yii2-models-select Tue, 13 Nov 2018 22:09:39 +0000 https://www.yiiframework.com/extension/matthew-p/yii2-models-select https://www.yiiframework.com/extension/matthew-p/yii2-models-select MatthewP MatthewP

Select models widget for Yii2

  1. Installation
  2. Usage

Find and select models in select2 input.

Installation

The preferred way to install this extension is through composer.

Either run

php composer.phar require --prefer-dist matthew-p/yii2-models-select "*"

or add

"matthew-p/yii2-models-select": "*"

to the require section of your composer.json file.

Usage

Once the extension is installed, simply use it in your code by:

$form->field($model, 'attribute')->widget(MPModelSelect::class, [
    'searchModel'     => YouActiveRecordModel::class,
    'valueField'      => 'id',
    'titleField'      => 'title',
    'searchFields'    => [
        // convert to orWhere 'id' => query-string and etc.
        'id', 'title', 
        // add related input (will be added to data request and conver to ->andWhere 'category_id' => request value)
        'category_id' => new JsExpression('$("#category-id").val()'),
        // more examples see MPModelSelect::searchFields
    ],
    'dropdownOptions' => [
        'options'       => [
            'placeholder' => Yii::t('app', 'Select models ...'),
            'multiple'    => true,
        ],
        'pluginOptions' => [
            'minimumInputLength' => 1,
        ],
    ],
])

Add action in controller: `php class SampleController extends Controller { ...

public function actions(): array
{
    return array_merge(parent::actions(), [
        'model-search' => [
            'class' => MPModelSelectAction::class,
        ],
    ]);
}

... } `

Define encryption key in params.php: ` 'MPModelSelect' => [

'encryptionKey' => 'RandomKey',

], `

That's all. Check it.

]]>
0
[extension] devzyj/yii2-rest Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/devzyj/yii2-rest https://www.yiiframework.com/extension/devzyj/yii2-rest devzyj devzyj

REST Extension for Yii2

  1. Installation
  2. Usage
  3. Controllers
  4. UrlRule
  5. Actions
  6. Events
  7. Behaviors

增强 yiisoft/yii2-rest 功能,在 Actions 中增加事件。

并且增加了批量操作的 Actions

Installation

The preferred way to install this extension is through composer.

Either run

composer require --prefer-dist "devzyj/yii2-rest" "~1.0.0"

or add

"devzyj/yii2-rest" : "~1.0.0"

to the require section of your application's composer.json file.

Usage

// UserController.php
class UserController extends \devzyj\rest\ActiveController
{
    public $modelClass = 'app\models\User';
    //public $searchModelClass` = 'app\models\UserSearch';
    //public $notFoundMessage = 'User not found: `{id}`';
    //public $allowedCount = 100;
    //public $manyResourcesMessage = 'The number of users requested cannot exceed `{allowedCount}`.';
}

// config.php
return [
    'components' => [
        'urlManager' => [
            ......
            'rules' => [
                [
                    'class' => 'devzyj\rest\UrlRule',
                    'controller' => 'user',
                    //'extraTokens' => ['{account}' => '<account:\\w[\\w]*>'],
                ]
            ]
        ],
    ],
];

调用方法,只列出部分新增的 API:

  • POST /users/validate: 验证创建一个新用户时的数据
  • PATCH /users/123/validate and PUT /users/123/validate: 验证更新用户 123 时的数据
  • POST /users/batch: 创建多个新用户,
  • PATCH /users/batch and PUT /users/batch: 更新多个用户
  • GET /users/10;11;12: 显示用户 10, 11 和 12 的信息
  • DELETE /users/10;11;12: 删除用户 10, 11 和 12

创建多个新用户时的数据格式:

POST /users/batch
    -d [
        {"username": "example1", "email": "user1@example.com"},
        {"username": "example2", "email": "user2@example.com"}
    ]

更新用户 123 和 456 时的数据格式:

PUT /users/batch
    -d {
        "123": {"username": "example1", "email": "user1@example.com"},
        "456": {"username": "example2", "email": "user2@example.com"}
    }

Controllers

  • ActiveController
    • 增加 $searchModelClass 查询数据的模型类名,如果不设置,则使用 $modelClass
    • 增加 $notFoundMessage 模型不存在时的错误信息
    • 增加 $allowedCount 允许批量执行的资源个数
    • 增加 $manyResourcesMessage 批量操作请求资源过多的错误信息
    • 增加 checkActionAccess($action, $params = []) 检查用户是否有执行当前动作的权限
    • 增加 checkModelAccess($model, $action, $params = []) 检查用户是否有执行数据模型的权限
    • 废弃 checkAccess()

UrlRule

  • 增加 $extraTokens 额外的令牌列表。

Actions

修改的 Actions:

  • IndexAction
    • 增加 afterPrepareDataProvider 事件。
  • ViewAction
    • 增加 afterPrepareModel 事件。
  • CreateAction
    • 增加 beforeLoadModel 事件。
    • 增加 afterLoadModel 事件。
    • 增加 beforeProcessModel 事件。
    • 增加 afterProcessModel 事件。
  • UpdateAction
    • 增加 afterPrepareModel 事件。
    • 增加 beforeLoadModel 事件。
    • 增加 afterLoadModel 事件。
    • 增加 beforeProcessModel 事件。
    • 增加 afterProcessModel 事件。
  • DeleteAction
    • 增加 afterPrepareModel 事件。
    • 增加 beforeProcessModel 事件。
    • 增加 afterProcessModel 事件。

增加的 Actions:

  • CreateValidateAction 创建新模型时,验证数据。
    • beforeLoadModel
    • afterLoadModel
    • beforeProcessModel
  • UpdateValidateAction 更新模型时,验证数据。
    • afterPrepareModel
    • beforeLoadModel
    • afterLoadModel
    • beforeProcessModel
  • BatchViewAction 显示多个模型。
    • afterPrepareModel
  • BatchCreateAction 创建多个新模型。
    • beforeLoadModel
    • afterLoadModel
    • beforeProcessModel
    • afterProcessModel
    • afterProcessModels
  • BatchUpdateAction 更新多个模型。
    • afterPrepareModel
    • beforeLoadModel
    • afterLoadModel
    • beforeProcessModel
    • afterProcessModel
    • afterProcessModels
  • BatchDeleteAction 删除多个模型。
    • afterPrepareModel
    • beforeProcessModel
    • afterProcessModel
    • afterProcessModels

Events

  • afterPrepareDataProvider 在准备完数据源后触发的事件。
  • afterPrepareModel 在准备完模型后触发的事件。
  • beforeLoadModel 在模型加载数据前触发的事件,如果返回 false,则阻止模型加载数据。
  • afterLoadModel 在模型成功加载完数据后触发的事件。
  • beforeProcessModel 在处理模型前触发的事件,如果返回 false,则阻止处理模型。
  • afterProcessModel 在成功处理完模型后触发的事件。
  • afterProcessModels 在处理完模型列表后触发的事件。

在批量动作中会多次调用的事件:

  • afterPrepareModel
  • beforeLoadModel
  • afterLoadModel
  • beforeProcessModel
  • afterProcessModel

事件参数说明:

  • 事件参数的类型为 ActionEvent
  • ActionEvent::$object 执行事件时的数据对像,以下列出的是对应事件中的对像类型。
    • afterPrepareDataProvider\yii\data\ActiveDataProvider
    • afterPrepareModel\yii\db\ActiveRecord
    • beforeLoadModelArray
    • afterLoadModel\yii\db\ActiveRecord
    • beforeProcessModel\yii\db\ActiveRecord
    • afterProcessModel\yii\db\ActiveRecord
    • afterProcessModels\devzyj\rest\BatchResult

Behaviors

  • EagerLoadingBehavior 需要手动附加到 IndexAction,实现了在执行 Action::EVENT_AFTER_PREPARE_DATA_PROVIDER 事件时,即时加载指定的额外资源。
  • SuppressResponseCodeBehavior 需要手动附加到 config 中的 components.response,实现了根据查询参数 $suppressResponseCodeParam,判断是否始终使用 200 作为 HTTP 状态,并将实际的 HTTP 状态码作为内容的一部分包含在响应中。
]]>
0
[extension] devzyj/yii2-attribute-cache-behavior Mon, 05 Nov 2018 05:52:30 +0000 https://www.yiiframework.com/extension/devzyj/yii2-attribute-cache-behavior https://www.yiiframework.com/extension/devzyj/yii2-attribute-cache-behavior devzyj devzyj

ActiveRecord attribute cache behavior

  1. Installation
  2. Usage

提供了一些缓存 ActiveRecord 属性的方法。并且当某些事件发生时,自动使缓存失效。

Installation

The preferred way to install this extension is through composer.

Either run

composer require --prefer-dist "devzyj/yii2-attribute-cache-behavior" "~1.0"

or add

"devzyj/yii2-attribute-cache-behavior" : "~1.0"

to the require section of your application's composer.json file.

Usage

// User.php
class User extends \yii\db\ActiveRecord
{
    use \devzyj\behaviors\ActiveCacheBehaviorTrait;
    
    public function behaviors()
    {
        return [
            [
                'class' => 'devzyj\behaviors\ActiveCacheBehavior',
                //'cache' => 'cache',
                //'defaultDuration' => 604800,
                //'baseModelCacheKey' => ['User', 'PrimaryKey'],
                //'keyAttributes' => static::primaryKey(),
                //'valueAttributes' => $this->attributes(),
            ],
        ];
    }
}


// Using trait methods
// Returns a single active record model instance.
// Sets cache value if there is no cache available for the `$primaryKey`.
$user = User::findOrSetOneByAttribute($primaryKey);

// No changed, cache value exists.
$user->save();

// Changed, cache value not exists.
$user->name = 1;
$user->save();

// Deleted, cache value not exists.
$user->delete();

// Gets cache value for model instance.
$user->getActiveCache();

// Checks cache value exists for model instance.
$user->existsActiveCache();

// Sets cache value for model instance.
$user->setActiveCache();

// Adds cache value for model instance.
$user->addActiveCache();

// Deletes cache value for model instance.
$user->deleteActiveCache();


// Using single key attribute
// ActiveCacheBehavior::$keyAttributes = ['id']
$id = 1;

// get cache
User::instance()->getModelCacheByAttribute($id);
// OR
User::instance()->getModelCache(['id' => $id]);

// exists cache
User::instance()->existsModelCacheByAttribute($id);
// OR
User::instance()->existsModelCache(['id' => $id]);

// set cache
User::instance()->setModelCacheByAttribute($id, $value, $duration, $dependency);
// OR
User::instance()->setModelCache(['id' => $id], $value, $duration, $dependency);

// add cache
User::instance()->addModelCacheByAttribute($id, $value, $duration, $dependency);
// OR
User::instance()->addModelCache(['id' => $id], $value, $duration, $dependency);

// delete cache
User::instance()->deleteModelCacheByAttribute($id);
// OR
User::instance()->deleteModelCache(['id' => $id]);

// get or set cache
User::instance()->getOrSetModelCacheByAttribute($id, function ($behavior) use ($id) {
    $condition = $behavior->ensureActiveKeyAttribute($id);
    $model = User::findOne($condition);
    return $model ? $model->getActiveCacheValue() : false;
}, $duration, $dependency);
// OR
$condition = ['id' => $id];
User::instance()->getOrSetModelCache($condition, function ($behavior) use ($condition) {
    $model = User::findOne($condition);
    return $model ? $model->getActiveCacheValue() : false;
}, $duration, $dependency);

// trait method: find and return ActiveRecord from cache or database
User::findOrSetOneByAttribute($id, $duration, $dependency);


// Using composite key attribute
// ActiveCacheBehavior::$keyAttributes = ['id1', 'id2']
$id1 = 1;
$id2 = 2;
$ids = [$id1, $id2];

// get cache
User::instance()->getModelCacheByAttribute($ids);
// OR
User::instance()->getModelCache(['id1' => $id1, 'id2' => $id2]);

// exists cache
User::instance()->existsModelCacheByAttribute($ids);
// OR
User::instance()->existsModelCache(['id1' => $id1, 'id2' => $id2]);

// set cache
User::instance()->setModelCacheByAttribute($ids, $value, $duration, $dependency);
// OR
User::instance()->setModelCache(['id1' => $id1, 'id2' => $id2], $value, $duration, $dependency);

// add cache
User::instance()->addModelCacheByAttribute($ids, $value, $duration, $dependency);
// OR
User::instance()->addModelCache(['id1' => $id1, 'id2' => $id2], $value, $duration, $dependency);

// delete cache
User::instance()->deleteModelCacheByAttribute($ids);
// OR
User::instance()->deleteModelCache(['id1' => $id1, 'id2' => $id2]);

// get or set cache
User::instance()->getOrSetModelCacheByAttribute($ids, function ($behavior) use ($ids) {
    $condition = $behavior->ensureActiveKeyAttribute($ids);
    $model = User::findOne($condition);
    return $model ? $model->getActiveCacheValue() : false;
}, $duration, $dependency);
// OR
$condition = ['id1' => $id1, 'id2' => $id2];
User::instance()->getOrSetModelCache($condition, function ($behavior) use ($condition) {
    $model = User::findOne($condition);
    return $model ? $model->getActiveCacheValue() : false;
}, $duration, $dependency);

// trait method: find and return ActiveRecord from cache or database
User::findOrSetOneByAttribute($ids, $duration, $dependency);


// Using database transactions, and the `commit()` time is too long
$transaction = $db->beginTransaction();
try {
    // old cache key.
    $oldKey = $model->getActiveCacheKey();
    
    // update
    $model->attributes = $attributes;
    $model->save();
    $transaction->commit();
    
    // delete old cache.
    $model->deleteModelCache($oldKey);
} catch (\Exception $e) {
    $transaction->rollBack();
    throw $e;
}
]]>
0
[extension] abushamleh/yii2-toast Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/abushamleh/yii2-toast https://www.yiiframework.com/extension/abushamleh/yii2-toast Abdelhadi92 Abdelhadi92
  1. Installation
  2. Usage

Installation

Run the Composer command to install the latest version: composer require abushamleh/yii2-toast "dev-master"

Usage

ToastAlert
use abushamleh\toast\ToastAlert;

echo ToastAlert::widget([
    'options'   => [],
    'heading'   => 'heading',
    'text'      => 'text',
    'type'      => 'type',
]);

ToastBlock

ToastBlock widget renders a message from session flash. All flash messages are displayed in the sequence they were assigned using setFlash. `php use abushamleh\toast\ToastBlock;

//You can set message as following: Yii::$app->session->setFlash('error', 'This is the message'); Yii::$app->session->setFlash('success', 'This is the message'); Yii::$app->session->setFlash('info', 'This is the message'); Yii::$app->session->setFlash('info', ['heading' => 'Message title' 'text' => 'This is the message']);

//Multiple messages could be set as follows: Yii::$app->session->setFlash('error', ['Error 1', 'Error 2']); Yii::$app->session->setFlash('error', [['heading' => 'Message title' 'text' => 'This is the message'], 'Error 2']);

echo ToastBlock::widget([

'options' => []

]);


]]>
0
[extension] abushamleh/yii2-opentok Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/abushamleh/yii2-opentok https://www.yiiframework.com/extension/abushamleh/yii2-opentok Abdelhadi92 Abdelhadi92

yii2-opentok

  1. Installation
  2. Working with SIP Interconnect
  3. Force Disconnect
  4. Sending Signals
  5. Samples
  6. Documentation

Yii2 client for opentok (http://www.tokbox.com/opentok)

Installation

  1. Run the Composer command to install the latest version:

    `bash composer require abushamleh/yii2-opentok "dev-master" `

  2. Add the component to config/main.php

    `php 'components' => [

     // ...
     'opentok' => [
         'class'      => 'abushamleh\opentok\Client',
         'api_key'    => 'your api key',
         'api_secret' => 'your secret key',
     ],
     // ...
    

    ], `

    Creating Sessions

To create an OpenTok Session, use the createSession($options) method of the OpenTok\OpenTok class. The $options parameter is an optional array used to specify the following:

  • Setting whether the session will use the OpenTok Media Router or attempt to send streams directly between clients.

  • Setting whether the session will automatically create archives (implies use of routed session)

  • Specifying a location hint.

The getSessionId() method of the OpenTok\Session instance returns the session ID, which you use to identify the session in the OpenTok client libraries.

use OpenTok\MediaMode;
use OpenTok\ArchiveMode;

// Create a session that attempts to use peer-to-peer streaming:
$session = Yii::$app->opentok->createSession();

// A session that uses the OpenTok Media Router, which is required for archiving:
$session = Yii::$app->opentok->createSession(array( 'mediaMode' => MediaMode::ROUTED ));

// A session with a location hint:
$session = Yii::$app->opentok->createSession(array( 'location' => '12.34.56.78' ));

// An automatically archived session:
$sessionOptions = array(
    'archiveMode' => ArchiveMode::ALWAYS,
    'mediaMode' => MediaMode::ROUTED
);
$session = Yii::$app->opentok->createSession($sessionOptions);


// Store this sessionId in the database for later use
$sessionId = $session->getSessionId();
Generating Tokens

Once a Session is created, you can start generating Tokens for clients to use when connecting to it. You can generate a token either by calling the generateToken($sessionId, $options) method of the OpenTok\OpenTok class, or by calling the generateToken($options) method on the OpenTok\Session instance after creating it. The $options parameter is an optional array used to set the role, expire time, and connection data of the Token. For layout control in archives and broadcasts, the initial layout class list of streams published from connections using this token can be set as well.

use OpenTok\Session;
use OpenTok\Role;

// Generate a Token from just a sessionId (fetched from a database)
$token = Yii::$app->opentok->generateToken($sessionId);
// Generate a Token by calling the method on the Session (returned from createSession)
$token = $session->generateToken();

// Set some options in a token
$token = $session->generateToken(array(
    'role'       => Role::MODERATOR,
    'expireTime' => time()+(7 * 24 * 60 * 60), // in one week
    'data'       => 'name=Johnny',
    'initialLayoutClassList' => array('focus')
));
Working with Streams

You can get information about a stream by calling the getStream($sessionId, $streamId) method of the OpenTok\OpenTok class.

use OpenTok\Session;

// Get stream info from just a sessionId (fetched from a database)
$stream = Yii::$app->opentok->getStream($sessionId, $streamId);

// Stream properties
$stream->id; // string with the stream ID
$stream->videoType; // string with the video type
$stream->name; // string with the name
$stream->layoutClassList; // array with the layout class list

You can get information about all the streams in a session by calling the listStreams($sessionId) method of the OpenTok\OpenTok class.

use OpenTok\Session;

// Get list of streams from just a sessionId (fetched from a database)
$streamList = Yii::$app->opentok->listStreams($sessionId);

$streamList->totalCount(); // total count
Working with Archives

You can only archive sessions that use the OpenTok Media Router (sessions with the media mode set to routed).

You can start the recording of an OpenTok Session using the startArchive($sessionId, $name) method of the OpenTok\OpenTok class. This will return an OpenTok\Archive instance. The parameter $archiveOptions is an optional array and is used to assign a name, whether to record audio and/or video, the desired output mode for the Archive, and the desired resolution if applicable. Note that you can only start an Archive on a Session that has clients connected.

// Create a simple archive of a session
$archive = Yii::$app->opentok->startArchive($sessionId);


// Create an archive using custom options
$archiveOptions = array(
    'name' => 'Important Presentation',     // default: null
    'hasAudio' => true,                     // default: true
    'hasVideo' => true,                     // default: true
    'outputMode' => OutputMode::COMPOSED,   // default: OutputMode::COMPOSED
    'resolution' => '1280x720'              // default: '640x480'
);
$archive = Yii::$app->opentok->startArchive($sessionId, $archiveOptions);

// Store this archiveId in the database for later use
$archiveId = $archive->id;

If you set the outputMode option to OutputMode::INDIVIDUAL, it causes each stream in the archive to be recorded to its own individual file. Please note that you cannot specify the resolution when you set the outputMode option to OutputMode::INDIVIDUAL. The OutputMode::COMPOSED setting (the default) causes all streams in the archive to be recorded to a single (composed) file.

Note that you can also create an automatically archived session, by passing in ArchiveMode::ALWAYS as the archiveMode key of the options parameter passed into the OpenTok->createSession() method (see "Creating Sessions," above).

You can stop the recording of a started archive using the stopArchive($archiveId) method of the OpenTok\OpenTok object. You can also do this using the stop() method of the OpenTok\Archive instance.

// Stop an Archive from an archiveId (fetched from database)
Yii::$app->opentok->stopArchive($archiveId);
// Stop an Archive from an Archive instance (returned from startArchive)
$archive->stop();

To get an OpenTok\Archive instance (and all the information about it) from an archive ID, use the getArchive($archiveId) method of the OpenTok\OpenTok class.

$archive = Yii::$app->opentok->getArchive($archiveId);

To delete an Archive, you can call the deleteArchive($archiveId) method of the OpenTok\OpenTok class or the delete() method of an OpenTok\Archive instance.

// Delete an Archive from an archiveId (fetched from database)
Yii::$app->opentok->deleteArchive($archiveId);
// Delete an Archive from an Archive instance (returned from startArchive, getArchive)
$archive->delete();

You can also get a list of all the Archives you've created (up to 1000) with your API Key. This is done using the listArchives($offset, $count) method of the OpenTok/OpenTok class. The parameters $offset and $count are optional and can help you paginate through the results. This will return an instance of the OpenTok\ArchiveList class.

$archiveList = Yii::$app->opentok->listArchives();

// Get an array of OpenTok\Archive instances
$archives = $archiveList->getItems();
// Get the total number of Archives for this API Key
$totalCount = $archiveList->totalCount();

For composed archives, you can change the layout dynamically, using the updateArchiveLayout($archiveId, $layoutType) method:

use OpenTok\OpenTok;

$layout Layout::getPIP(); // Or use another get method of the Layout class.
Yii::$app->opentok->updateArchiveLayout($archiveId, $layout);

You can set the initial layout class for a client's streams by setting the layout option when you create the token for the client, using the OpenTok->generateToken() method or the Session->generateToken() method. And you can change the layout classes for a stream by calling the OpenTok->updateStream() method.

Setting the layout of composed archives is optional. By default, composed archives use the "best fit" layout (see Customizing the video layout for composed archives).

For more information on archiving, see the OpenTok archiving developer guide.

Working with Broadcasts

You can only start live streaming broadcasts for sessions that use the OpenTok Media Router (sessions with the media mode set to routed).

Start the live streaming broadcast of an OpenTok Session using the startBroadcast($sessionId, $options) method of the OpenTok\OpenTok class. This will return an OpenTok\Broadcast instance. The $options parameter is an optional array used to assign a layout type for the broadcast.

// Start a live streaming broadcast of a session
$broadcast = Yii::$app->opentok->startBroadcast($sessionId);


// Start a live streaming broadcast of a session, setting a layout type
$options = array(
    'layout' => Layout::getBestFit()
);
$broadcast = Yii::$app->opentok->startBroadcast($sessionId, $options);

// Store the broadcast ID in the database for later use
$broadcastId = $broadcast->id;

You can stop the live streaming broadcast using the stopBroadcast($broadcastId) method of the OpenTok\OpenTok object. You can also do this using the stop() method of the OpenTok\Broadcast instance.

// Stop a broadcast from an broadcast ID (fetched from database)
Yii::$app->opentok->stopBroadcast($broadcastId);

// Stop a broadcast from an Broadcast instance (returned from startBroadcast)
$broadcast->stop();

To get an OpenTok\Broadcast instance (and all the information about it) from a broadcast ID, use the getBroadcast($broadcastId) method of the OpenTok\OpenTok class.

$broadcast = Yii::$app->opentok->getBroadcast($broadcastId);

You can set change the layout dynamically, using the OpenTok->updateBroadcastLayout($broadcastId, $layout) method:

use OpenTok\OpenTok;

$layout Layout::getPIP(); // Or use another get method of the Layout class.
Yii::$app->opentok->updateBroadcastLayout($broadcastId, $layout);

You can use the Layout class to set the layout types: Layout::getHorizontalPresentation(), Layout::getVerticalPresentation(), Layout::getPIP(), Layout::getBestFit(), Layout::createCustom().

$layoutType = Layout::getHorizontalPresentation();
Yii::$app->opentok->setArchiveLayout($archiveId, $layoutType);

// For custom Layouts, you can do the following
$options = array(
    'stylesheet' => 'stream.instructor {position: absolute; width: 100%;  height:50%;}'
);

$layoutType = Layout::createCustom($options);
Yii::$app->opentok->setArchiveLayout($archiveId, $layoutType);

You can set the initial layout class for a client's streams by setting the layout option when you create the token for the client, using the OpenTok->generateToken() method or the Session->generateToken() method. And you can change the layout classes for a stream by calling the Yii::$app->opentok->updateStream() method.

Setting the layout of live streaming broadcasts is optional. By default, broadcasts use the "best fit" layout (see Configuring video layout for OpenTok live streaming broadcasts).

For more information on live streaming broadcasts, see the OpenTok live streaming broadcasts developer guide.

Force a Client to Disconnect

Your application server can disconnect a client from an OpenTok session by calling the forceDisconnect($sessionId, $connectionId) method of the OpenTok\OpenTok class.

use OpenTok\OpenTok;

// Force disconnect a client connection
Yii::$app->opentok->forceDisconnect($sessionId, $connectionId);
Sending Signals

Once a Session is created, you can send signals to everyone in the session or to a specific connection. You can send a signal by calling the signal($sessionId, $payload, $connectionId) method of the OpenTok\OpenTok class.

The $sessionId parameter is the session ID of the session.

The $payload parameter is an associative array used to set the following:

  • data (string) -- The data string for the signal. You can send a maximum of 8kB.

  • type (string) -- — (Optional) The type string for the signal. You can send a maximum of 128 characters, and only the following characters are allowed: A-Z, a-z, numbers (0-9), '-', '_', and '~'.

The $connectionId parameter is an optional string used to specify the connection ID of a client connected to the session. If you specify this value, the signal is sent to the specified client. Otherwise, the signal is sent to all clients connected to the session.

use OpenTok\OpenTok;

// Send a signal to a specific client
$signalPayload = array(
    'data' => 'some signal message',
    'type' => 'signal type'
);
$connectionId = 'da9cb410-e29b-4c2d-ab9e-fe65bf83fcaf';
Yii::$app->opentok->signal($sessionId, $signalPayload, $connectionId);

// Send a signal to everyone in the session
$signalPayload = array(
    'data' => 'some signal message',
    'type' => 'signal type'
);
Yii::$app->opentok->signal($sessionId, $signalPayload);

For more information, see the OpenTok signaling developer guide.

Working with SIP Interconnect

You can add an audio-only stream from an external third-party SIP gateway using the SIP Interconnect feature. This requires a SIP URI, the session ID you wish to add the audio-only stream to, and a token to connect to that session ID.

To initiate a SIP call, call the dial($sessionId, $token, $sipUri, $options) method of the OpenTok\OpenTok class:

$sipUri = 'sip:user@sip.partner.com;transport=tls';

$options = array(
  'headers' =>  array(
    'X-CUSTOM-HEADER' => 'headerValue'
  ),
  'auth' => array(
    'username' => 'username',
    'password' => 'password'
  ),
  'secure' => true,
  'from' => 'from@example.com'
);

Yii::$app->opentok->dial($sessionId, $token, $sipUri, $options);

For more information, see the OpenTok SIP Interconnect developer guide.

Force Disconnect

Your application server can disconnect a client from an OpenTok session by calling the forceDisconnect($sessionId, $connectionId) method of the OpenTok\OpenTok class.

use OpenTok\OpenTok;

// Force disconnect a client connection
Yii::$app->opentok->forceDisconnect($sessionId, $connectionId);

Sending Signals

Once a Session is created, you can send signals to everyone in the session or to a specific connection. You can send a signal by calling the signal($sessionId, $payload, $connectionId) method of the OpenTok\OpenTok class.

The $sessionId parameter is the session ID of the session.

The $payload parameter is an associative array used to set the following:

  • data (string) -- The data string for the signal. You can send a maximum of 8kB.

  • type (string) -- — (Optional) The type string for the signal. You can send a maximum of 128 characters, and only the following characters are allowed: A-Z, a-z, numbers (0-9), '-', '_', and '~'.

The $connectionId parameter is an optional string used to specify the connection ID of a client connected to the session. If you specify this value, the signal is sent to the specified client. Otherwise, the signal is sent to all clients connected to the session.

use OpenTok\OpenTok;

// Send a signal to a specific client
$signalPayload = array(
    'data' => 'some signal message',
    'type' => 'signal type'
);
$connectionId = 'da9cb410-e29b-4c2d-ab9e-fe65bf83fcaf';
Yii::$app->opentok->signal($sessionId, $signalPayload, $connectionId);

// Send a signal to everyone in the session
$signalPayload = array(
    'data' => 'some signal message',
    'type' => 'signal type'
);
Yii::$app->opentok->signal($sessionId, $signalPayload);

For more information, see the OpenTok signaling developer guide.

Samples

There are three sample applications included in this repository. To get going as fast as possible, clone the whole repository and follow the Walkthroughs:

Documentation

Reference documentation is available at https://tokbox.com/developer/sdks/php/reference/index.html.

]]>
0
[extension] bizley/jwt Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/bizley/jwt https://www.yiiframework.com/extension/bizley/jwt Bizley Bizley

Latest Stable VersionTotal Downloads LicenseBuild Status

JWT Integration For Yii 2

  1. Installation
  2. Basic usage
  3. JSON Web Tokens

This extension provides the JWT integration for Yii 2 framework.

This is fork of sizeg/yii2-jwt package

Installation

Add the package to your composer.json:

{
    "require": {
        "bizley/jwt": "^2.0"
    }
}

and run composer update or alternatively run composer require bizley/jwt:^2.0

Basic usage

Add jwt component to your configuration file:

[
    'components' => [
        'jwt' => [
            'class' => \bizley\jwt\Jwt::class,
            'key' => ... // Secret key string or path to the public key file
        ],
    ],
],

Now you have got access to JWT library through Yii::$app->jwt and some helper methods like getBuilder(), getParser(), and getValidationData(). You can validate your JSON Web Token by using validateToken() method and check its signature with verifyToken().

REST authentication

Configure the authenticator behavior in controller.

class ExampleController extends Controller
{
    public function behaviors()
    {
        $behaviors = parent::behaviors();
        
        $behaviors['authenticator'] = [
            'class' => \bizley\jwt\JwtHttpBearerAuth::class,
        ];

        return $behaviors;
    }
}

For other configuration options refer to the Yii 2 Guide.

JWT Basic Usage

Please refer to the lcobucci/jwt Documentation.

JSON Web Tokens

]]>
0
[extension] donsimon/yii2-log-target-file Mon, 12 Nov 2018 04:27:50 +0000 https://www.yiiframework.com/extension/donsimon/yii2-log-target-file https://www.yiiframework.com/extension/donsimon/yii2-log-target-file chathurasudarsha chathurasudarsha

Yii2 LogTargetFile

  1. Installation
  2. Usage

Customize the log messages

Sort and change the log message's units

Installation

Just run in your console:

composer require donsimon/yii2-log-target-file "*"

or add

"donsimon/yii2-log-target-file": "*"

to the require section of your composer.json file.

Usage

Add following line to your main configuration file (e.g. config/main.php),

    'bootstrap' => ['log'],

Then,

Add following lines to the components section in configuration file, `php

    'log' => [
    //          'traceLevel' => YII_DEBUG ? 3 : 0,
                'targets' => [
                      [  
                            'class' => 'donsimon\log\logTargetFile',  
                            'levels' => ['info','warning','error'],
                            'categories' => ['user','application'],
                            'logVars' => ['_GET', '_POST', '_FILES', '_COOKIE', '_SESSION', '_SERVER'],
                            'logFile' => '@backend/runtime/logs/appAndUser.log',
                            'logMessageContainer' =>['timestamp','prefix','level','category','message'],
                            'prefixContainer'=>['ip','userId','sessionId']
                        ]
                ],
    ],
To write on log file client should call something like this,

 `Yii::info($message, $category);` 

Here $message and $category are variables.

your log will update.

What you can do here,
--

You can change log file name using `logFile`.

    eg: @backend/runtime/logs/user-activities.log

You can add many `categories`.

    eg: ['yii\web\HttpException:*','yii\base\ErrorException:*','user','application']

You can add many `levels` 

    eg: ['info','warning','error']

You can print vars using `logVars`.

[Refer more](https://www.yiiframework.com/doc/guide/2.0/en/runtime-logging)



New
--

`logMessageContainer` is a array of log messages units `['timestamp','prefix','level','category','message']`. 

You can sort and change log messages units using `logMessageContainer` 

`prefixContainer` is a array of prefix units `['ip','userId','sessionId']`.

You can sort and change log messages prefix using `prefixContainer`
 


]]>
0
[extension] alcad/yii2-cas Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/alcad/yii2-cas https://www.yiiframework.com/extension/alcad/yii2-cas alcad alcad

Yii2-CAS

Simple wrapper for phpCAS in Yii2

NOTE: Module is in initial development. jasig/phpCAS is required

Configuration

config/param.php `php return [

...
'cas' => [
	'host' => 'https://app.example.com/',
	'port' => 443,
	'uri' => '/cas',
            'log_file' => '/tmp/phpCAS.log',
],
...

]; `

config/web.php `php $config = [

...
'bootstrap' => [... , 'cas'],
'components' => [
	'casUser' => [
		'class' => 'alcad\cas\CasUser',
	]
],
'modules' => [
	'cas' => [
		'class' => 'alcad\cas\Cas',
	],
]
...

] `

]]>
0
[extension] lisi4ok/yii2-auditlog Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/lisi4ok/yii2-auditlog https://www.yiiframework.com/extension/lisi4ok/yii2-auditlog lisi4ok lisi4ok

Yii2 Audit Log

  1. Installation
  2. Usage

Yii2 Audit Log. This extension log all models actions -> find/insert/update/delete.

Installation

The preferred way to install this extension is through composer.

Either run

php composer.phar require --prefer-dist lisi4ok/yii2-auditlog "*"

or add

"lisi4ok/yii2-auditlog": "*"

to the require section of your composer.json file.

Go to yii app folder. and type: ./yii migrate --migrationPath=@vendor/lisi4ok/yii2-auditlog/migrations

Usage

<?php
namespace app\models;
use Yii;
use lisi4ok\auditlog\behaviors\LoggableBehavior;

class MyModel extends \yii\db\ActiveRecord
{
	public function behaviors() {
		return [
			[
				'class' => LoggableBehavior::className(),
				'ignoredAttributes' => ['created_at', 'updated_at', 'created_by', 'updated_by'], // default []
				'ignorePrimaryKey' => true, // default false
				'ignorePrimaryKeyForActions' => ['insert', 'update'], //default [] Note: (if ignorePrimaryKey set to true, ignorePrimaryKeyForActions is empty will apply for all)
				'dateTimeFormat' => 'Y-m-d H:i:s', // default 'Y-m-d H:i:s'
			],
		];
	}
}
]]>
0
[extension] mirocow/yii2-elasticsearch-debug Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/mirocow/yii2-elasticsearch-debug https://www.yiiframework.com/extension/mirocow/yii2-elasticsearch-debug Mirocow Mirocow

yii2-elasticsearch-debug

Install

if (YII_DEBUG) {
    // configuration adjustments for 'dev' environment
    $config['bootstrap'][] = 'debug';
    $config['modules']['debug'] = [
        'class' => 'yii\debug\Module',
        'allowedIPs' => ['127.0.0.1', '::1'],
        'panels' => [
            'elasticsearch' => [
                'class' => 'mirocow\\elasticsearch\\debug\\DebugPanel',
            ],
        ],
    ];
}
];

]]>
0
[extension] himiklab/yii2-gridview-ajaxed-widget Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/himiklab/yii2-gridview-ajaxed-widget https://www.yiiframework.com/extension/himiklab/yii2-gridview-ajaxed-widget himiklab himiklab

Ajaxed GridView Widget for Yii2

  1. Installation
  2. Usage

Improved Yii2 GridView widget with support ajax, pjax and modal (Bootstrap).

Packagist Packagist license

Installation

The preferred way to install this extension is through composer.

  • Either run
php composer.phar require --prefer-dist "himiklab/yii2-gridview-ajaxed-widget" "*"

or add

"himiklab/yii2-gridview-ajaxed-widget" : "*"

to the require section of your application's composer.json file.

Usage

// index.php
use himiklab\yii2\ajaxedgrid\GridView;

GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        'title',
        'author',
        'language',
        'visible:boolean',
    ],
    'jsErrorCallback' => 'function(jqXHR, textStatus) {console.log(jqXHR, textStatus, errorThrown)}',
]);
// _form.php
    <?php $form = ActiveForm::begin(['id' => 'test-form']); ?>

    <?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>

    <?= $form->field($model, 'author')->textInput(['maxlength' => true]) ?>

    <?= $form->field($model, 'language')->dropDownList($model::getAllLanguages()) ?>

    <?= $form->field($model, 'visible')->checkbox() ?>

    <div class="form-group">
        <?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
    </div>

    <?php ActiveForm::end(); ?>
// controller
    public function actionIndex()
    {
        $dataProvider = new ActiveDataProvider([
            'query' => Page::find(),
        ]);

        return $this->render('index', [
            'dataProvider' => $dataProvider,
        ]);
    }

    public function actionCreate()
    {
        $model = new Page();
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return null;
        }

        return $this->renderAjax('_form', [
            'model' => $model,
        ]);
    }

    public function actionUpdate($id)
    {
        $model = $this->findModel($id);
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return null;
            //return '#reload';
            //return '#alert OK!';
            //return '#redirect /';
            //return '#file document.txt ' . \base64_encode('document content');
        }

        return $this->renderAjax('_form', [
            'model' => $model,
        ]);
    }

    public function actionDelete($id)
    {
        $this->findModel($id)->delete();
    }

    protected function findModel($id)
    {
        if (($model = Page::findOne($id)) === null) {
            throw new NotFoundHttpException('Page not found.');
        }

        return $model;
    }

It's all!

]]>
0
[extension] codespede/yii2-template-renderer Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/codespede/yii2-template-renderer https://www.yiiframework.com/extension/codespede/yii2-template-renderer mhs135 mhs135

Template Renderer for Yii 2

  1. Installation
  2. Use Cases
  3. How to use
  4. Advantages

Facilitates rendering data in any custom format/structure with just a parent-view, child-view and DataProvider(Supports pagination, sorting, filtering and all other operations supported by DataProvider).

Though this extension is mainly intended for RESTful APIs built in Yii 2, it can be used anywhere in the application as explained below.

Installation

The preferred way to install this extension is through composer.

Either run

php composer.phar require codespede/yii2-template-renderer "*"

or add

"codespede/yii2-template-renderer": "*"

to the require section of your composer.json.

Use Cases

  • Suppose you want to deliver the data in CSV format like below:
    title,image,content
    ABC,abc.jpg,Content of ABC
    MNO,mno.jpg,Content of MNO
    XYZ,xyz.jpg,Content of XYZ
    
  • Suppose you have to render the API response in a specific format like below:
    -begin-
    --title=ABC
    --image=abc.jpg
    --content=Content of ABC
    ---
    --title=MNO
    --image=mno.jpg
    --content=Content of MNO
    ---
    --title=XYZ
    --image=xyz.jpg
    --content=Content of XYZ
    -end-
    
  • Or in any situation where the you have to deliver custom formatted data through the API.

How to use

One can use this by simply returning the TemplateRenderer object in any action as shown in the below code:

public function actionRender(){
    $dataProvider = new ActiveDataProvider(['query' => Model::find()->where($condition)])
    return new \cs\templaterenderer\TemplateRenderer([
        'dataProvider' => $dataProvider,
        'parentView' => '/path/to/parent-view', //path to the parent or wrapper view file
        'itemView' => '/path/to/item-view', //path to the item view file
    ]);
}

In the $parentView file, a placeholder {{items}} in the code will be replaced automatically with the collectively rendered result of $itemView for the models in the current page. For example, if the content has to be rendered as shown in the second use case above, the $parentView file should be like:

-begin-
{{items}}
-end-

and the $itemView should be like:

--title=<?=$model->title?>
--image=<?=$model->image?>
--content=<?=$model->content?>

Advantages

  • The data can be paginated, sorted and filtered just as how it can be done with a GridView or ListView. You can pass the pagination, sort and filter parameters in the URL and the content rendered will be according to the provided parameters.
  • Easy to navigate through paginated content by utilizing Pagination Headers in the response.
]]>
0
[extension] onmotion/yii2-survey Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/onmotion/yii2-survey https://www.yiiframework.com/extension/onmotion/yii2-survey onmotion onmotion
  1. Survey module for Yii2 application
  2. Installation
  3. Usage

Survey module for Yii2 application

Latest Stable Version Total Downloads Monthly Downloads License

>! Note: the module under active developing, so it may have vary errors and unstable work. > Highly appreciate your PR.

fluent

Installation

  • Just run:

    composer require onmotion/yii2-survey

or add

"onmotion/yii2-survey": "*"

to the require section of your composer.json file.

  • apply migration:
php yii migrate --migrationPath=@vendor/onmotion/yii2-survey/migrations
  • Define module to your config:
'modules' => [
//...
    'survey' => [
        'class' => '\onmotion\survey\Module',
        'params' => [
            'uploadsUrl' => 'http://advanced-frontend.lh/uploads/survey/', // full URL of the folder where the images will be uploaded.
           // 'uploadsUrl' => '/uploads/survey/', // or for basic
            'uploadsPath' => '@frontend/web/uploads/survey/', // absolute path to the folder where images will be saved.
        ],
//            'as access' => [
//                'class' => AccessControl::class,
//                'except' => ['default/done'],
//                'only' => ['default*'],
//                'rules' => [
//                    [
//                        'allow' => true,
//                        'roles' => ['survey'],
//                    ],
//                ],
//            ],
    ],
//...
]

don't forget change your own params.

Usage

If you are using the Yii basic template, you must manually define $controllerNamespace for module.

onmotion\survey\controllers - backend (admin/create/edit surveys)

onmotion\survey\widgetControllers - default (for widget)

Now go to /survey in your backend and create a survey.

fluent

After that you can select Survey entities and show it for user, for example:

echo \onmotion\survey\Survey::widget([
   'surveyId' => 1
]);

fluent

Admin:

fluent

fluent

]]>
0
[extension] mirocow/yii2-elasticsearch-log Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/mirocow/yii2-elasticsearch-log https://www.yiiframework.com/extension/mirocow/yii2-elasticsearch-log Mirocow Mirocow

Elasticsearch log storage module based on mirocow/yii2-elasticsearch

Latest Stable Version FOSSA Status Latest Unstable Version Total Downloads License Maintainability

Docs are available in english and russian.

  • Conclusion is easy to review and administer using Kibana
  • The date format is provided in the form YYYY-MM-DD HH:mm:ss and must be UTC

Install

$ composer require --prefer-dist mirocow/yii2-elasticsearch-log

Setup


return [
    'components' => [
        'log' => [
            'targets' => [
                [
                    'class' => 'mirocow\elasticsearch\log\ElasticsearchTarget',
                    'levels' => ['error', 'warning'],
                    'index' => 'yii-log',
                    'type' => 'console',
                ],
            ],
        ],
    ],
];

Tutorial

How we can use Discover, Visualization and Dashboard with cusom data

Depends

License

FOSSA Status

]]>
0
[extension] borysenko/yii2-liqpay Wed, 17 Oct 2018 14:43:26 +0000 https://www.yiiframework.com/extension/borysenko/yii2-liqpay https://www.yiiframework.com/extension/borysenko/yii2-liqpay borysenko borysenko

Yii2-liqpay

  1. Установка
  2. Подключение и настройка
  3. Модель Order
  4. Виджеты

В составе модуля содержится виджет оплаты заказа через liqpay.com.

В виджет передается модель заказа, которая должна имплементировать интерфейс interfaces/Order.

При успешной оплате liqpay вызывает callback, в котором сохраняется статус payment c значением yes в текущем заказе.

Установка

В сборке Yii2 в файле composer.json нужно заменить в свойстве "minimum-stability" значение "stable" на "dev". Т.е. у вас должно быть так: "minimum-stability": "dev"

  • Это связано с тем, что это расширение подтягивает другие расширения, в которых "minimum-stability": "dev"

Выполнить команду

composer require borysenko/yii2-liqpay "*"

Или добавить в composer.json

"borysenko/yii2-liqpay": "*",

И выполнить

php composer update

Подключение и настройка

В конфигурационный файл приложения добавить модуль liqpay

    'modules' => [
        'liqpay' => [
            'class' => 'borysenko\liqpay\Module',
            'public_key' => 'iNNNNNNNNNNN',
            'private_key' => 'NzpRclCywaSOrm0LTpqDpPPlRDhoOQyIX1ISHjk',
            'currency' => 'UAH',
            'pay_way' => null,
            'version' => 3,
            'sandbox' => false,
            'language' => 'ru',
            'result_url' => '/page/thanks',
            'paymentName' => 'Оплата заказа',
            'orderModel' => 'frontend\models\Order', //Модель заказа. Эта модель должна имплементировать интерфейс borysenko\liqpay\interfaces\Order. В момент списания денег будет вызываться $model->setPaymentStatus('yes').
        ],
        //...
    ],

Модель Order

<?php
namespace frontend\models;

use Yii;
use yii\db\ActiveRecord;

Class Order extends ActiveRecord implements \borysenko\liqpay\interfaces\Order
{
    public static function tableName()
    {
        return 'orders';
    }

    public function getId()
    {
        return $this->id;
    }

    public function getCost()
    {
        return $this->cost;
    }

    function setPaymentStatus($status)
    {
        $this->payment = $status;

        return $this;
    }
}

Виджеты

За вывод формы оплаты отвечает виджет borysenko\liqpay\widgets\PaymentForm.

<?=\borysenko\liqpay\widgets\PaymentForm::widget([
    'autoSend' => true,
    'orderModel' => $model, //Order::findOne($id);
    'description' => 'Оплата заказа'
]);?>
  • autoSend - нужно ли автоматически отправлять форму заказа
  • orderModel - экземпляр модели заказа, имплементирующий interfaces/Order
  • description - описание платежа
]]>
0
[extension] buttflattery/yii2-formwizard Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/buttflattery/yii2-formwizard https://www.yiiframework.com/extension/buttflattery/yii2-formwizard omeraslam omeraslam

Yii2-FormWizard (v1.0)

What is this repository for?

A Yii2 plugin used for creating stepped form or form wizard using yii\widgets\ActiveForm and \yii\db\ActiveRecord, it uses smart wizard library for creating the form interface that uses 3 builtin and 2 extra themes, moreover you can also create your own customized theme too.

Note : It uses limited features of the jquery plugin SmartWizard that suite the needs of the ActiveForm validation so not all options in the javascript plugin library are allowed to be changed or customized from within this plugin.

preview

External Libraries Used
How do I get set up?

use composer to install the extension

php composer.phar require  buttflattery/yii2-formwizard "@dev" 

or add into the composer.json file under require section

"buttflattery/yii2-formwizard":"@dev"
Demos

See all demos with all options.

Available Options
Widget options
  • wizardContainerId (string): Id of the main container for the wizard.
  • labelNext : Next button label.
  • labelPrev : Previuos button label.
  • labelFinish : Finish button label.
  • classNext : css classes for the button Next.
  • classPrev : css classes for the button Prev.
  • classFinish : css classes for the button Finish.
  • steps (array) : An array of the steps(array), the steps can have models dedicated to each step, or a single model for all steps. Following options are recognized when specifying a step.

    • model (object | array of models) : The \yii\model\ActiveRecord model object or array of models to create step fields.
    • title (string) : The title of the step to be displayed inside the step Tab.
    • description (string) : The short description for the step.
    • formInfoText (text) : The text to be displayed on the top of the form fields inside the step.
    • fieldConfig (array) : This option is used mainly to customize the form fields for the step. 2 special options are recognized inside the fieldConfig, except and only. See below for the details

      • except (array) : List of fields that should not be populated in the step or should be ignored, for example

        `

        'fieldConfig'=>[

          'except'=>[
              'created_on','updated_on'
          ]
        

        ]

        `

        By default all the attributes that are safe to load value are populated, and the id or primary_key is ignored by default.

      • only (array) : list of the fields that should be populated for the step, only the fields specified in the list will be available and all other fields will be ignored.

        Apart from the above options the fieldConfig recognizes some special options specific to every field separately when customizing a field, for example

        `

        'fieldConfig'=>[

          'username'=>[
              'options'=>[
                  'class'=>'my-class'
              ]
          ]
        

        ]

        `

        you should specify the field name of the model and its customization settings in form of name=>value pairs. The following special options can be used when specifying the form/model field_name.

        • options
        • containerOptions
        • template
        • labelOptions
        • widget
        • multifield (boolean)

        Details

        • options (array) : You can specify the HTML attributes (name-value pairs) for the field ` 'field_name'=>['options'=>['class'=>'my-class']]`

          ` All those special options that are recognized by the

          • checkbox(), radio() : uncheck, label, labelOptions
          • checkboxList(), radioList() : tag, unselect, encode, separator, itemOptions, item.

          can be used with-in the options option. The following 2 options are specially recognized by this widget when used with-in the options.

          • type (string): The type of the form field to be created, this can be text, dropdown,checkbox, radio or textarea. Default value for this option is text.

          • itemsList (string/array) : This option can be used with a dropdown, checkboxList or radioList. It is used in combination of the the option type. If you provide the itemsList an array and use the 'type'=>'checkbox' , it will call checkboxList(), and a checkbox() if you provide string, same goes for the radioList and radio.

        • lableOptions (array): The HTML and special options for customizing the field label, you can use the following settings
          • label (string): The label text.
          • options (array) : The HTML attributes (name-value pairs) for the label.
        • template (string) : The template used for the field the default value used is {label}\n{input}\n{hint}\n{error}.
        • containerOptions (array) : HTML atrtibutes for the cotnainer tag used as name=>value pairs.
        • widget : This option can be used if you want to use a widget instead of the the default fields, you can specify the widget class name 'widget'=>widget::class, and the options for the widget will be provided in the options option.
        • multifield (boolean) : a boolean which decides if the field name should consist of an array or not, for example using multi file upload widgets require the name attribute for the field to be declared as an array like filed_name[] instead of field_name. you can pass this option as true by default it is false.
Widget Plugin (SmartWizard) Options

Only the following options of the plugin SmartWizard are allowed to be customized

  • theme : name of the theme to be used, there are mainly 6 themes supported by the plugin
    • default : const THEME_DEFAULT
    • dots : const THEME_DOTS
    • arrows : const THEME_ARROWS
    • circles : const THEME_CIRCLES
    • material : const THEME_MATERIAL
    • material-v : const THEME_MATERIAL_V
  • transitionEffect (string) : The effect used when sliding the step it can be one of the
    • none
    • slide
    • fade
  • showStepURLhash (boolean) : Show url hash based on step, default false.
  • useURLHash (boolean) : Enable selection of the step based on url hash, default value is false.
  • toolbarPosition : Position of the toolbar (none, top, bottom, both), default value top.
  • toolbarButtonPosition: Position of the toolbar buttons (left, right), default value is left.
  • toolbarExtraButtons : Specify the extra buttons and its events to show on toolbar.
  • markDoneSteps (boolean) : Make already visited steps as done, default value is true.
  • markAllPreviousStepsAsDone (boolean): When a step selected by url hash, all previous steps are marked done, default value is true.
  • removeDoneStepOnNavigateBack (boolean) : While navigate back done step after active step will be cleared, default value is false.
  • enableAnchorOnDoneStep (boolean) : Enable/Disable the done steps navigation, default value is true.
Who do I talk to?
  • buttflattery@hotmail.com
  • omeraslam@idowstech.com
]]>
0
[extension] buttflattery/yii2-videowall Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/buttflattery/yii2-videowall https://www.yiiframework.com/extension/buttflattery/yii2-videowall omeraslam omeraslam

Yii2-VideoWall(v1.0)

What is this repository for?

A Yii2 plugin based on idows-videojs-videowall that creates a Video Wall for VIDEOJS video player using three different modes.

  • Carousel (Default)
  • Thumbnail
  • Playlist

delete-single-files

For details on the javascript plugin you can visit the link https://github.com/buttflattery/idows-videojs-videowall

External Libraries Used
DEMOS
How do I get set up?

use composer to install the extension

php composer.phar require  buttflattery/yii2-videowall "@dev" 

or add into the composer.json file under require section

"buttflattery/yii2-videowall":"@dev"
Demos
Available Options
  • videoTagOptions (array): Attributes for the the default video tag used by videoJs to initialize the player. You can pass the following options for the video tag.

    • class : Html class for the the video tag.
    • width : Width for the video tag.
    • height : Height for the video tag.
    • setupOptions : The setup options for the video tag used inside the data-setup attribute, below are few of the options commonly used by the videoJS player.
      • controls : Default value true.
      • autoplay : Default value true.
      • preload : Default value auto.
    • poster (path) : Path for the default poster for the video tag, use path relative to the web directory.
  • wallType (string) :
    • Videowall::TYPE_CAROUSEL (carousel)
    • Videowall::TYPE_THUMBNAIL (thumbnail)
    • Videowall::TYPE_PLAYLIST (playlist)
  • slideShowDelay (milliseconds) : integer, default value 2000 ms.
  • videoWallContainer (string): container class name for the video wall, default class video-wall-container.
  • containerId (string) : container id for the video wall slides, default id prefix video-wall-slides.
  • containerClass (string) : container class name for the video wall slides, default class slides-container.
  • helpImproveVideoJs (boolean) : true or false used by the videoJS player.
  • thumbPageSize (int) : page size for the thumbnails mode, default value 15.
  • playlistPageSize (int) : page size for the playlist model, default value 8.
  • loadBootstrapAssets (boolean) : select if plugin should load the bootstrap assets or use the globally registered yii bootstrap assets, by default this option is false and Yii2 default assets bundle is used.
  • bootstrapCssSource (url) : url to the bootstrap css file for the plugin to load, this option is effective when you have "loadBootstrapAssets"=>true.
  • bootstrapJsSource (url) : url to the boootstrap js file for the plugin to load, this option is effective when you have "loadBootstrapAssets"=>true.
  • select2Defaults (array) : default options used for rendring the kartik-v\yii2-select2 plugin, you override them and add you own too look into documentation for the options
    • allowClear: default value true.
    • theme : default value default.
    • width : default value 100%.
    • placeholder : default value Search Videos.
    • minimumInputlength : default value 2.
    • dropdownCssClass : default value bigdrop.
  • openOnStart (boolean) : Select if the video wall is open when player is initialized, default value is true.
  • callback (function): a callback function called by the plugin after initialized.
  • clientEvents (array) : an array of client events supported by the plugin, you can see the plugin documentation for the supported events, you can use them like below
    "pluginEvents"=>[
      'onBeforeNext' => 'function(event,dataObj){console.log(event);}',
    ]
    
Usage 1 Carousel Mode
<?php
        use buttflattery\videowall\Videowall;
        echo Videowall::widget([
            'videoTagOptions' => [
                'height' => "500",
            ],
            'wallType' => Videowall::TYPE_CAROUSEL,
            'videos' => [
                [
                    "src" => "/PATH/TO/VIDEO.MP4",
                    "mime" => 'video/mime',
                    "poster" => "/PATH/TO/POSTER.JPG",
                    "title" => "Sweet Sexy Savage",
                ], [
                    "src" => '/PATH/TO/VIDEO.MP4',
                    'poster' => '/PATH/TO/POSTER.JPG',
                    'mime' => 'video/mime',
                    'title' => 'Video 2',
                ],
            ]
        ]);
Usage 2 Thumbnail Mode

Thumbnail mode for compact display of the video files along with filter option using the select2 dropdown.

<?php
        use buttflattery\videowall\Videowall;
        echo Videowall::widget([
            'videoTagOptions' => [
                'height' => "500",
            ],
            'wallType' => Videowall::TYPE_THUMB,
            'videos' => [
                [
                    "src" => "/PATH/TO/VIDEO.MP4",
                    "mime" => 'video/mime',
                    "poster" => "/PATH/TO/POSTER.JPG",
                    "title" => "Sweet Sexy Savage",
                ], [
                    "src" => '/PATH/TO/VIDEO.MP4',
                    'poster' => '/PATH/TO/POSTER.JPG',
                    'mime' => 'video/mime',
                    'title' => 'Video 2',
                ],
            ]
        ]);
Usage 3 Playlist Mode

Bonus Feature for disaplying th playlists inside the video wall.

<?php
        use buttflattery\videowall\Videowall;
        echo Videowall::widget([
            'wallType' => Videowall::TYPE_PLAYLIST,
            'videoTagOptions' => [
                'width' => "800",
                'height' => "600",
            ],
            'playlists' => [
                [
                    'name' => 'Sweet Sexy Savage',
                    'cover' => '/PATH/TO/POSTER.JPG',
                    'videos' => [
                        [
                            'src' => '/PATH/TO/VIDEO.MP4',
                            'poster' => '/PATH/TO/POSTER.JPG',
                            'mime' => 'video/mime',
                            'title' => 'Video title',
                        ],
                        [
                            'src' => '/PATH/TO/VIDEO.MP4',
                            'poster' => '/PATH/TO/POSTER.JPG',
                            'mime' => 'video/mime',
                            'title' => 'Video title',
                        ],
                        [
                            'src' => '/PATH/TO/VIDEO.MP4',
                            'poster' => '/PATH/TO/POSTER.JPG',
                            'mime' => 'video/mime',
                            'title' => 'Video title',
                        ],
                        [
                            'src' => '/PATH/TO/VIDEO.MP4',
                            'poster' => '/PATH/TO/POSTER.JPG',
                            'mime' => 'video/mime',
                            'title' => 'Video title',
                        ],
                        [
                            'src' => '/PATH/TO/VIDEO.MP4',
                            'poster' => '/PATH/TO/POSTER.JPG',
                            'mime' => 'video/mime',
                            'title' => 'Video title',
                        ],
                    ],
                ],
                [
                    'name' => 'Hope',
                    'cover' => '/PATH/TO/POSTER.JPG',
                    'videos' => [
                        [
                            'src' => '/PATH/TO/VIDEO.MP4',
                            'poster' => '/PATH/TO/POSTER.JPG',
                            'mime' => 'video/mime',
                            'title' => 'Video title',
                        ],
                        [
                            'src' => '/PATH/TO/VIDEO.MP4',
                            'poster' => '/PATH/TO/POSTER.JPG',
                            'mime' => 'video/mime',
                            'title' => 'Video title',
                        ],
                        [
                            'src' => '/PATH/TO/VIDEO.MP4',
                            'poster' => '/PATH/TO/POSTER.JPG',
                            'mime' => 'video/mime',
                            'title' => 'Video title',
                        ], [
                            'src' => '/PATH/TO/VIDEO.MP4',
                            'poster' => '/PATH/TO/POSTER.JPG',
                            'mime' => 'video/mime',
                            'title' => 'Video title',
                        ], [
                            'src' => '/PATH/TO/VIDEO.MP4',
                            'poster' => '/PATH/TO/POSTER.JPG',
                            'mime' => 'video/mime',
                            'title' => 'Video title',
                        ], [
                            'src' => '/PATH/TO/VIDEO.MP4',
                            'poster' => '/PATH/TO/POSTER.JPG',
                            'mime' => 'video/mime',
                            'title' => 'Video title',
                        ]],
                ],
            ]
        ]);
Who do I talk to?
  • buttflattery@hotmail.com
  • omeraslam@idowstech.com
]]>
0
[extension] slavkovrn/yii2-lightbox Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/slavkovrn/yii2-lightbox https://www.yiiframework.com/extension/slavkovrn/yii2-lightbox Viacheslav Kolesnikov Viacheslav Kolesnikov

LightBox image galary widget for Yii2 Framework uses jQuery Lightbox v2.10.0 by Lokesh Dhakar

  1. Installation
  2. Usage

The extension uses jQuery Lightbox v2.10.0 by Lokesh Dhakar and makes image galary from php array of structure defined.

LightBox image galary PHP Array generator.

LightBox image galary

Installation

The preferred way to install this extension is through composer.

Either run:

composer require slavkovrn/yii2-lightbox

or add

"slavkovrn/yii2-lightbox": "*"

to the require section of your composer.json file.

Usage

Set link to extension in your view:

use kartik\grid\GridView;
use slavkovrn\lightbox\LightBoxWidget;

echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        [
            'header' => 'Pictures',
            'content' => function ($data){
                $images = [               // images at popup window of prettyPhoto galary
                    1 => [
                            'src' => 'http://yii2.kadastrcard.ru/uploads/prettyphoto/image1.jpg',
                            'title' => 'Image visible in widget',
                        ],
                    2 => [
                            'src' => 'http://yii2.kadastrcard.ru/uploads/prettyphoto/image2.jpg',
                            'title' => 'image 1',
                        ],
                    3 => [
                            'src' => 'http://yii2.kadastrcard.ru/uploads/prettyphoto/image3.jpg',
                            'title' => 'image 2',
                        ],
                    4 => [
                            'src' => 'http://yii2.kadastrcard.ru/uploads/prettyphoto/image4.jpg',
                            'title' => 'image 3',
                        ],
                ];
                return LightBoxWidget::widget([
                    'id'     =>'lightbox',  // id of plugin should be unique at page
                    'class'  =>'galary',    // class of plugin to define style
                    'height' =>'100px',     // height of image visible in widget
                    'width' =>'100px',      // width of image visible in widget
                    'images' => $images,
                ]);
            }
        ],
    ],
]);

write comments to admin

]]>
0
[extension] onmotion/yii2-widget-apexcharts Thu, 11 Oct 2018 07:55:54 +0000 https://www.yiiframework.com/extension/onmotion/yii2-widget-apexcharts https://www.yiiframework.com/extension/onmotion/yii2-widget-apexcharts onmotion onmotion

Yii2 charts widget

  1. Installation
  2. Usage
  3. Options
  4. Examples

Yii2 charts widget - wrapper for the ApexCharts.js.

Latest Stable Version Total Downloads Monthly Downloads License

fluentfluent

For more examples see ApexCharts.js demos

Installation

Just run:

composer require onmotion/yii2-widget-apexcharts

or add

"onmotion/yii2-widget-apexcharts": "*"

to the require section of your composer.json file.

Usage

Add echo \onmotion\apexcharts\ApexchartsWidget::widget([]) with necessary options in the view file.

Options

Option type default description
timeout int 500 Timeout before widget appearance
type string area Chart type. More
width string 100% Chart width
height string 350 Chart height
chartOptions array detail
series array detail

Examples

$series = [
    [
        'name' => 'Entity 1',
        'data' => [
            ['2018-10-04', 4.66],
            ['2018-10-05', 5.0],
        ],
    ],
    [
        'name' => 'Entity 2',
        'data' => [
            ['2018-10-04', 3.88],
            ['2018-10-05', 3.77],
        ],
    ],
    [
        'name' => 'Entity 3',
        'data' => [
            ['2018-10-04', 4.40],
            ['2018-10-05', 5.0],
        ],
    ],
    [
        'name' => 'Entity 4',
        'data' => [
            ['2018-10-04', 4.5],
            ['2018-10-05', 4.18],
        ],
    ],
];

echo \onmotion\apexcharts\ApexchartsWidget::widget([
    'type' => 'bar', // default area
    'height' => '400', // default 350
    'width' => '500', // default 100%
    'chartOptions' => [
        'chart' => [
            'toolbar' => [
                'show' => true,
                'autoSelected' => 'zoom'
            ],
        ],
        'xaxis' => [
            'type' => 'datetime',
            // 'categories' => $categories,
        ],
        'plotOptions' => [
            'bar' => [
                'horizontal' => false,
                'endingShape' => 'rounded'
            ],
        ],
        'dataLabels' => [
            'enabled' => false
        ],
        'stroke' => [
            'show' => true,
            'colors' => ['transparent']
        ],
        'legend' => [
            'verticalAlign' => 'bottom',
            'horizontalAlign' => 'left',
        ],
    ],
    'series' => $series
]);

fluent

]]>
0
[extension] saviorlv/yii2-dysms Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/extension/saviorlv/yii2-dysms https://www.yiiframework.com/extension/saviorlv/yii2-dysms saviorlv saviorlv

aliyun-dysms

  1. 安装
  2. 设置方法

安装

composer require "saviorlv/yii2-dysms:dev-master"

or添加下列代码在composer.json文件中并执行composer update 操作

{
    "require": {
       "saviorlv/yii2-dysms":"dev-master"
    }
}

设置方法

全局使用

在config/main.php配置文件中定义component配置信息 `bash 'components' => [ ..... 'aliyun' => [

  'class' => 'saviorlv\aliyun\Sms',
  'accessKeyId' => '123455',
  'accessKeySecret' => '122345666'
],

.... ]

> 代码中调用(调用短信发送接口示例)

```bash
// 单条发送
$response = Yii::$app->aliyun->sendSms(
            "孙坤峰", // 短信签名
            "SMS_76350132", // 短信模板编号
            "136*****134", // 短信接收者
            Array(  // 短信模板中字段的值
                "code"=>"12345",
                "product"=>"dsd"
            ),
            "123"
        );
        print_r($response);
        
//批量发送

$response = Yii::$app->aliyun->sendBatchSms(
            array("孙坤峰","孙坤峰"), // 短信签名
            "SMS_76350132", // 短信模板编号
            array("136*****134","180*****459"), // 短信接收者
            array(array(  // 短信模板中字段的值
                "code"=>"12345",
                "product"=>"dsd"
            ),array(  // 短信模板中字段的值
                "code"=>"123456",
                "product"=>"dsd"
            )),
            "123"
        );
//批量发送 签名、手机号、模板字段 数组长度必须相等

如上所示 180*******259收到的短信 签名是"孙坤峰" 内容为  123456
]]>
0
[wiki] Using multiple models in an identity Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/wiki/2545/using-multiple-models-in-an-identity https://www.yiiframework.com/wiki/2545/using-multiple-models-in-an-identity samdark samdark

Let's assume we have two models: Customer and Supplier and we want both to log in. Yii is quite flexible when it comes to authentication and authorization so it's possible.

First of all, Yii assumes that there's a single type of user component used at once. Still, we're able to create a universal Identity that works with both customers and suppliers.

So we create models/Identity.php:

final class Identity implements IdentityInterface
{
    const TYPE_CUSTOMER = 'customer';
    const TYPE_SUPPLIER = 'supplier';

    const ALLOWED_TYPES = [self::TYPE_CUSTOMER, self::TYPE_SUPPLIER];

    private $_id;
    private $_authkey;
    private $_passwordHash;

    public static function findIdentity($id)
    {
        $parts = explode('-', $id);
        if (\count($parts) !== 2) {
            throw new InvalidCallException('id should be in form of Type-number');
        }
        [$type, $number] = $parts;

        if (!\in_array($type, self::ALLOWED_TYPES, true)) {
            throw new InvalidCallException('Unsupported identity type');
        }

        $model = null;
        switch ($type) {
            case self::TYPE_CUSTOMER:
                $model = Customer::find()->where(['id' => $number])->one();
                break;
            case self::TYPE_SUPPLIER:
                $model = Supplier::find()->where(['id' => $number])->one();
                break;
        }

        if ($model === null) {
            return false;
        }


        $identity = new Identity();
        $identity->_id = $id;
        $identity->_authkey = $model->authkey;
        $identity->_passwordHash = $model->password_hash;
        return $identity;
    }

    public static function findIdentityByAccessToken($token, $type = null)
    {
        $model = Customer::find()->where(['token' => $token])->one();
        if (!$model) {
            $model = Supplier::find()->where(['token' => $token])->one();
        }

        if (!$model) {
            return false;
        }

        if ($model instanceof Customer) {
            $type = self::TYPE_CUSTOMER;
        } else {
            $type = self::TYPE_SUPPLIER;
        }

        $identity = new Identity();
        $identity->_id = $type . '-' . $model->id;
        $identity->_authkey = $model->authkey;
        $identity->_passwordHash = $model->password_hash;
        return $identity;
    }

    public function validatePassword($password)
    {
        return password_verify($password, $this->_passwordHash);
    }

    public static function findIdentityByEmail($email)
    {
        $model = Customer::find()->where(['email' => $email])->one();
        if (!$model) {
            $model = Supplier::find()->where(['email' => $email])->one();
        }

        if (!$model) {
            return false;
        }

        if ($model instanceof Customer) {
            $type = self::TYPE_CUSTOMER;
        } else {
            $type = self::TYPE_SUPPLIER;
        }

        $identity = new Identity();
        $identity->_id = $type . '-' . $model->id;
        $identity->_authkey = $model->authkey;
        $identity->_passwordHash = $model->password_hash;
        return $identity;
    }

    public function getId()
    {
        return $this->_id;
    }

    public function getAuthKey()
    {
        return $this->_authkey;
    }

    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }
}

In the above we assume that our ids are like customer-23 or supplier-34. When we need to get identity instance we split the id by - and getting both type and integer id for the model corresponding to that type.

Having identity we can tell Yii to use it via confing/main.php:

[
    // ...
    'components' => [
        // ...
        'user' => [
            'identityClass' => 'app\models\Identity',
            'enableAutoLogin' => true,
        ],
    ],
],

The only thing left is to adjust models\LoginForm.php:

class LoginForm extends Model
{
    // ...
    
    public function getUser()
    {
        if ($this->_user === false) {
            $this->_user = Identity::findIdentityByEmail($this->username);
        }

        return $this->_user;
    }
}

That's it. Now you can log in using both models.

]]>
0
[news] Redis extension 2.0.9 released Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/news/188/redis-extension-2-0-9-released https://www.yiiframework.com/news/188/redis-extension-2-0-9-released samdark samdark

We are very pleased to announce the release of Redis extension version 2.0.9 fixing zrangebyscore and adding >, <, >= and <= support to ActiveQuery.

See the CHANGELOG for details.

]]>
0
[news] Sphinx extension 2.0.11 released Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/news/187/sphinx-extension-2-0-11-released https://www.yiiframework.com/news/187/sphinx-extension-2-0-11-released samdark samdark

We are very pleased to announce the release of Sphinx extension version 2.0.11. In this release there is a bug fixed that yii\sphinx\ActiveQuery::all() was unable to follow instructions given by method indexBy().

See the CHANGELOG for details.

]]>
0
[news] Twig extension 2.2.1 released Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/news/186/twig-extension-2-2-1-released https://www.yiiframework.com/news/186/twig-extension-2-2-1-released samdark samdark

We are very pleased to announce the release of Twig extension version 2.2.1. This release fixes an error when outputting DateTime dates.

See the CHANGELOG for details.

]]>
0
[news] Swiftmailer extension 2.1.2 released Sun, 23 Sep 2018 22:04:27 +0000 https://www.yiiframework.com/news/185/swiftmailer-extension-2-1-2-released https://www.yiiframework.com/news/185/swiftmailer-extension-2-1-2-released samdark samdark

We are very pleased to announce the release of Swiftmailer extension version 2.1.2. This release brings automatic transport restart and adds an ability to specify the disposition of an attachment by supplying a setDisposition value when embedding content in a message.

See the CHANGELOG for details.

]]>
0
[news] HTTP client extension 2.0.7 released Sun, 23 Sep 2018 21:57:52 +0000 https://www.yiiframework.com/news/184/http-client-extension-2-0-7-released https://www.yiiframework.com/news/184/http-client-extension-2-0-7-released samdark samdark

We are very pleased to announce the release of HTTP client extension version 2.0.7. In this release, Response::detectFormatByContent was fixed to properly detect JSON Array. Additionally, Request::setFullUrl() method was added.

See the CHANGELOG for details.

]]>
0
[news] Debug extension 2.0.14 released Sun, 23 Sep 2018 22:38:01 +0000 https://www.yiiframework.com/news/183/debug-extension-2-0-14-released https://www.yiiframework.com/news/183/debug-extension-2-0-14-released samdark samdark

We are very pleased to announce the release of Debug extension version 2.0.14. In this release, additionally to bugfixes, there's new "Events" panel.

See the CHANGELOG for details.

]]>
0
[news] Auth Client extension 2.1.7 released Thu, 20 Sep 2018 07:26:26 +0000 https://www.yiiframework.com/news/182/auth-client-extension-2-1-7-released https://www.yiiframework.com/news/182/auth-client-extension-2-1-7-released samdark samdark

We are very pleased to announce the release of Auth Client extension version 2.1.7. It fixes OAuth2 client unsetting scope on defaultReturnUrl. Previously it was causing bad request from recent version of Google provider.

See the CHANGELOG for details.

]]>
0
[wiki] Update and Delete buttons on Breadcrumb Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/wiki/2544/update-and-delete-buttons-on-breadcrumb https://www.yiiframework.com/wiki/2544/update-and-delete-buttons-on-breadcrumb adinugro adinugro

The definition of breadcrumbs according to its documentation is as follow: Breadcrumbs displays a list of links indicating the position of the current page in the whole site hierarchy.

We can define the breadcrumbs easily by adding these lines.

$this->title = $model->formNo;
$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Supplier receiving'), 'url' => ['index', 'type' => $model->type]];
$this->params['breadcrumbs'][] = ['label' => $this->title, 'url' => ['view', 'id' => $model->id]];

Reading the documentation, I encountered the template keyword. I was excited about the possibility to add buttons into breadcrumbs. Add these lines and you would have buttons on the right side of the breadcrumb.

$this->title = $model->formNo;
$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Supplier receiving'), 'url' => ['index', 'type' => $model->type]];
$this->params['breadcrumbs'][] = ['label' => $this->title, 'url' => ['view', 'id' => $model->id]];
$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Delete'), 'template' =>
    Html::tag('span', Html::a(Html::icon('glyphicon glyphicon-trash white') . ' ' . Yii::t('app', 'Delete'), Url::to(['delete', 'id' => $model->id]), [
                'class' => 'btn btn-xs btn-danger',
                'title' => Yii::t('app', 'Delete'),
                'data-pjax' => '0',
                'data-method' => 'POST',
                'data-confirm' => Yii::t('app', 'Are you sure you want to delete this supplier receiving?'),
                    ]
            ), ['class' => 'pull-right'])];
$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Update'), 'template' => Html::tag('span', Html::a(
                    Html::icon('glyphicon glyphicon-pencil') . ' ' . Yii::t('app', 'Update'), Url::to(['update', 'id' => $model->id, 'inview' => 1]), [
                'class' => 'btn btn-xs btn-warning',
                'title' => Yii::t('app', 'Update'),
                'role' => 'modal-remote',
                'data-toggle' => 'tooltip',
                    ]
            ), ['class' => 'pull-right', 'style' => 'margin-right: 5px;'])];

Actually you can use this line to define the template, but $links means the full link. A suggestion to the developer is to make the $url and $label variables to be available like $links, so that we can make the template more flexible and meaningful than above codes.

FYI,

  1. I use ajaxcrud extension, so that the update link has 'role' => 'modal-remote' to allow the update process taken place on the modal window. I added a inview parameter to distinguish the update from index or view. Both actions will be called using ajax request and will show the form on the modal, but the index update will redirect to index and refresh gridview while in the view, it should redirect to the view.
  2. On the template, I used span over li to make ' / ' character not appear on the links buttons.

A simple tip to make the view layout efficient.

]]>
0
[news] Auth Client extension 2.1.6 released Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/news/181/auth-client-extension-2-1-6-released https://www.yiiframework.com/news/181/auth-client-extension-2-1-6-released samdark samdark

We are very pleased to announce the release of Auth Client extension version 2.1.6. It upgrades VKontakte API used to version 5.0 and fixes a couple of bugs related to OpenID and canceling login in auth form.

See the CHANGELOG for details.

]]>
0
[news] Replacing the forum software, moving to Discourse Mon, 03 Sep 2018 15:47:12 +0000 https://www.yiiframework.com/news/180/replacing-the-forum-software-moving-to-discourse https://www.yiiframework.com/news/180/replacing-the-forum-software-moving-to-discourse CeBe CeBe

A few month ago we have replaced the old Yii Framework website with a rewritten version in Yii 2. While developing the new site, we also discussed the replacement of the old IPB forum software with a more modern solution, but replacing the forum together with the site would have been too much work to do at once.

From a long discussion, which started already a few years ago, we have now evaluated different forum software and decided to go with Discourse, which is an open source forum software made by the people who created also StackOverflow. We are going to replace the old forum with a Discourse instance starting tomorrow (September 4, 2018).

Here is a list of things that are going to change:

  • User accounts will be managed by the website, there is no duplicate login as we have it now, and all users are signed in to the forum via SSO.
  • Forum categories, topics and posts are migrated from the old forum, so no content will be lost (we might re-arrange the categories though).
  • Links from the old forum should all be redirected to the new location. If you hit broken links, please report those to us!
  • Watched topics and watched forums are not going to be migrated, so if you want to get notified about new posts, make sure to visit the new forum and configure your notification settings as well as update watched topics.
  • User badges on the website do not include the forum posts anymore, instead we are using the Badge system by Discourse, which has a lot more badges than we had before.
  • Discourse allows you to configure it to behave like a mailing list, so if you prefer to take part in Yii discussions from your email client, you can do that now.

In case you have problems logging in to the new forum, please use the Contact form or Chat to get help.

There is a forum topic for discussion on this announcement.

]]>
0
[news] New member joining Yii team as primary Yii 3.0 developer Fri, 31 Aug 2018 22:23:17 +0000 https://www.yiiframework.com/news/179/new-member-joining-yii-team-as-primary-yii-3-0-developer https://www.yiiframework.com/news/179/new-member-joining-yii-team-as-primary-yii-3-0-developer samdark samdark

Andrii Vasyliev, @hiqsol joined Yii team. Andrii uses Yii daily for his team projects and is very interested in framework moving forward.

He's from Kiev, Ukraine and is part of HiQDev team same as another long term Yii team member, Dmytro Naumenko (@SilverFire).

His primary focus will be refreshing Yii architecture splitting it into more packages to achieve more frequent independent releases and making Yii core more robust.

]]>
0
[wiki] When to use Active Record Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/wiki/2541/when-to-use-active-record https://www.yiiframework.com/wiki/2541/when-to-use-active-record samdark samdark

When to use Active Record is a common question among developers, Yii and overall.

I have about 500K records in my DB tables and each query there are 2 or 3 joins. I was getting data via AR, about a hundred records a time and noticed that using createCommand consumes less memory and CPU. I think with DAO instead of AR it will be faster.

It is true that Active Record consumes memory for storing objects and CPU cycles for instantiate these objects.

Is AR bad? It it for small projects only? We have lots of inserts, about 5000 records an hour and we're using AR for that. Should we re-write?

AR is a pleasure to use when you're managing not that many records at the same time. CRUD is very easy with it. Yii 2 dirty attribute support (only what was modified is saved) off-loads database and mitigates many parallel editing conflicts. If you don't have complex logic in your app and you don't need entity abstractions, AR is an ideal choice.

AR is OK for queries not too complicated when they return no more than a hundred objects. Yes, it is faster and less memory consuming to use query builder or asArray() but working with arrays is significantly less convenient.

For complex queries, such as aggregates or reports, AR isn't recommended. These are easier to express with query builder or SQL. Same goes for import and export routines.

]]>
0
[wiki] Getting information from the current locale Thu, 09 Aug 2018 18:56:33 +0000 https://www.yiiframework.com/wiki/2540/getting-information-from-the-current-locale https://www.yiiframework.com/wiki/2540/getting-information-from-the-current-locale CeBe CeBe

Yii 2.0 comes with a formatter component to format dates, numbers, and other values for international users according to their locale. This is very useful for displaying data. When working with incoming data or when using enhanced input methods like the MaskedInput widget you sometimes need to access the symbols used by the formatter to generate a pattern or parse the input.

The Yii formatter does not have methods to access this data, it relies on the PHP intl extension for formatting. If you want to access the formatting symbols you need to work with intl directly.

Getting decimal and thousand separator

$locale = 'de_DE';

$formatter = new \NumberFormatter($locale,\NumberFormatter::DECIMAL);

$decimalSeparator = $formatter->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL);
$thousandSeparator = $formatter->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL);

There are more symbols than shown above, for the full list of symbols see the list of NumberFormatter constants in the php manual.

Getting a currency symbol

Getting the currency symbol is a bit more complicated if you do not want the symbol of the default currency of a locale, but another currency:

$locale = 'de_DE'; // get the currency symbol of Germanys default currency EUR = "€"
$locale = 'de_DE@currency=USD'; // get the currency symbol of USD in German locale = "$"

$formatter = new \NumberFormatter($locale, \NumberFormatter::CURRENCY);

$currencySymbol = $formatter->getSymbol(\NumberFormatter::CURRENCY_SYMBOL);

Note, that the NumberFormatter is instantiated with the CURRENCY constant instead of DECIMAL here.

Since Yii 2.0.14 Yii has this method built-in in the Locale class.

]]>
0
[wiki] What SQL-Statement creates yii? Fri, 27 Jul 2018 11:28:13 +0000 https://www.yiiframework.com/wiki/2539/what-sql-statement-creates-yii https://www.yiiframework.com/wiki/2539/what-sql-statement-creates-yii Necip Necip

The usual way to find out what Yii has created for an SQL query is to mutilate the SQL in the sourcecode and call the program again so that the SQL statement with errors is displayed. Or you can use the SQL logger, which must be switched on and off each time and logs all SQL statements, which leads to an enormous slowdown in program execution and decelerates your workflow.

These all is not necessary if you use XDebug and place a breakpoint after the function "getCommandBuilder" in the CActiveRecord.php and take a closer look at the return value in $command.

This database access is created in yii:

yii-sql11.png?w=474

This code is called by the yii framework

yii-sql21.png?w=474

getCommandBuilder returns this data structure with the generated SQL statement:

yii-sql32.png?w=474

Path to CActiveRecord.php

C:\xampp\htdocs\your_project\yii\framework\db\ar\CActiveRecord.php

]]>
0
[wiki] How to organize Design "things" in Yii 2 (themes and layout) Thu, 23 Aug 2018 17:32:30 +0000 https://www.yiiframework.com/wiki/2538/how-to-organize-design-things-in-yii-2-themes-and-layout https://www.yiiframework.com/wiki/2538/how-to-organize-design-things-in-yii-2-themes-and-layout olissongs olissongs
  1. Via "theming"
  2. Using layouts
  3. Both
  4. UseCase one
  5. UseCase two

Sometimes the App needs a nicer look & feel, so its necessary to organize the assets for this and Yii can help a lot to make it easy. In this article I provide tips for handling multiple "Designs". I use these three features:

  • AssetBundle
  • Layouts
  • Themes

What do you need for desingning your website:

  • CSS files
  • JS files
  • some Images or other media.

Lets call it "DesignAssets"

What Yii needs:

  • one or more Layout files
  • the view files
  • AssetBundle set in the layout-file

Lets call it "DesignTemplates".

So how to bundle these and where is the best place to put them in your application directory?

Via "theming"

  • myYiiApp
    • ...
    • designs
      • myDesign1
        • put here all your "DesignTemplates" (AssetBundle,layout, and view folder/files, when using themes)

Using layouts

  • myYiiApp
    • ...
    • views
      • layouts
        • myDesign1.php (layout file)
      • ...

Both

  • myYiiApp

    • ...
    • web

      • designs
        • myDesign1
          • put here all your "DesignAssets" (css, js, img, etc.)
    • ...

So you can work with the default security file-rights for the correct purpose.

UseCase one

Write an App and distribute it to some Customer. Here can it be necessary that every customer wants a personal design.

Solution: Using themes

you config in your web.php or main.php (advanced template) whats documented here

if you need special "DesignAssets"

put your "DesignAssets" und the web directory myYiiApp/web/designs/myDesign1/css and js and img folders

customize your myYiiApp/designs/myDesign1/assets/MyDesignAsset.php

and your layout file myYiiApp/designs/myDesign1/layout/main.php

thats it.

UseCase two

you need several designs for e.g. controllers. so my remmmendation is using layouts, because easy switching in controller action.

Solution with layouts

there is no need to configure anything in the config files

if you need special "DesignAssets"

put your "DesignAssets" und the web directory myYiiApp/web/designs/myDesign1/css and js and img folders

create and customize your myYiiApp/assets/MyDesignAsset.php

and your layout file myYiiApp/views/layout/mydesign1.php

in your controller action set your layout.

public function actionIndex() {
    $this->layout = 'mydesign1';
}

may it helps your start with designing Yii.

]]>
0
[news] Yii 1.1.20 is released Fri, 06 Jul 2018 18:12:52 +0000 https://www.yiiframework.com/news/178/yii-1-1-20-is-released https://www.yiiframework.com/news/178/yii-1-1-20-is-released CeBe CeBe

We are very pleased to announce that Yii Framework version 1.1.20 is released. You can download it at yiiframework.com/download/.

This release is a release of Yii 1.1 that has reached maintenance mode and will, only receive necessary security fixes and fixes to adjust the code for compatibility with PHP 7 if they do not cause breaking changes. This allows you to keep your servers PHP version up to date in the environments where old Yii 1.1 applications are hosted and stay within the version ranges supported by the PHP team. Yii 1.1.20 is compatible with PHP 7.2 that, at the time of this writing, has an announced security support until November 30, 2020.

We recommend to use Yii 2.0 for new projects as well as introducing Yii 2.0 for developing new features in existing Yii 1.1 apps, as described in the Yii 2 guide. Upgrading a whole app to Yii 2.0 will, in most cases, result in a total rewrite so this option provides a way for upgrading step by step and allows you to keep old applications up to date even with low budget.

This release includes a few PHP 7 compatibility fixes and security improvements.

For the complete list of changes in this release, please see the change log. For upgrading, always make sure to read the upgrade instructions, however in this release there are no changes that require changes.

We would like to express our gratitude to all contributors who have spent their precious time helping improve Yii and made this release possible.

To comment on this news, you can do so in the related forum post.

]]>
0
[wiki] An alternative way to ElasticSearch Sun, 12 Aug 2018 07:49:50 +0000 https://www.yiiframework.com/wiki/2255/an-alternative-way-to-elasticsearch https://www.yiiframework.com/wiki/2255/an-alternative-way-to-elasticsearch Necip Necip

This article is for those who have dealt with the complexity of Elasticsearch or any other indexing machines and are looking for an easier way to index the existing database without additional effort.

Why this post?

The amount of data increases every day. As a result, the search in the databases becomes longer and longer. Conventional data structures must be realigned in order to be able to access information more quickly. There are already database systems like Elasticsearch that can do this. However, such systems also have disadvantages.

The most noticeable major drawbacks are:

  • Learning a new query language. SQL-Plugin won’t get you far or is not flexible enough.
  • The existing programs must be rewritten in order to process the new result sets appropriately.
  • The safety regulations must be defined again.
  • A second database must be set up, which in principle contains the same data.

Who will benefit from this post?

This information is useful for any programmer who wants to integrate an index database into his existing system in a simple way without additional effort.

The basic idea behind Indexing-machines

We will use this simple Table to demonstrate what an Index-machine does

Tablename: object

UID	TITLE	DESCRIPTION
4711	Rudyard Kipling	If you can keep your head when all about you …
4712	John Magee	I have slipped the surly bonds of Earth and danced the skies on laugher-silvered wings …
4713	Wiliam Wordsworth	Ten thousand saw I at a glance, Tossing their heads in sprightly dance…

With this request we can find very specific texts in this single table:

SELECT ID, Title, Description
FROM object
WHERE Description like '%head%'

But what if we want to find ‚%head%‘ in all tables of our database? We have to write a code to do this job for us. This is inefficent and will work very slowy. The idea behind Elasticsearch and other indexing tables is – so far I understood – to break the strings in single tokens. That means in a very easy way that we have to transform the horicontal order of the table into a vertical order.

Tablename: ncp_index

UID	TABLENAME	FIELDNAME	ID	TOKEN
1001	object	Description	4711	if
1002	object	Description	4711	you
1003	object	Description	4711	can
…				
1010	object	Description	4712	I
1011	object	Description	4712	have
1012	object	Description	4712	slipped
…				

We can tokenize any field of any table of our database into the table ncp_index. Now we can find with a single query very fast any (tokenized) word in our hole database.

SELECT Tablenname, Fieldname, Token
FROM ncp_index
WHERE Token like '%head%'

That is the secret of any Index-Searchengine. Yes, the ncp_index table has a lot of redundant data that we can normalize as follows:

Every field is stored in a system table and has a unique id. let us call it field_id Every content of a field has a lot of same words. These words should be stored only once in a separat words-table.

Our ncp_index table looks now so:

UID	FIELD_ID	ID	TOKEN_ID
1001	123	4711	1
1002	123	4711	2
1003	123	4711	31010	123	4712	4
1011	123	4712	5
1012	123	4712	6
…	
		
Systemtable: fields

UID	TABLENAME	NAME
122	object	Name
123	object	Description
…		

Tablename: word

UID	TOKEN
1	if
2	you
3	can
…	

Some basic examples

/**
 * @author ncp <necips@live.de>
 */
class NCPSearch
{
    /**
     * @param $model
     * @param $tablename
     * @param $fieldnames
     */
    public static function delete_ncp_search_item($model, $tablename) {
        $criteria = new CDbCriteria;
        $criteria->condition = "tablename = :tablename " .
                    "AND id = :id ";
        $criteria->params[":tablename"] = $tablename;
        $criteria->params[":id"] = $model->uid;
        NCPIndexModel::model()->deleteAll($criteria);
    }
    /**
     * @param $model
     * @param $tablename
     * @param $fieldnames
     */
    public static function update_ncp_search_item($model, $tablename, $fieldnames) {
        NCPSearch::delete_ncp_search_item($model, $tablename);
        NCPSearch::insert_ncp_search_item($model, $tablename, $fieldnames);
    }
    /**
     * @param $model
     * @param $tablename
     * @param $fieldnames
     */
    public static function insert_ncp_search_item($model, $tablename, $fieldnames) {
        foreach ($fieldnames as $fieldname) {
            $NCP_index_model = new NCPIndexModel("create");
            $NCP_index_model->tablename = $tablename;
            $NCP_index_model->fieldname = $fieldname;
            $NCP_index_model->id = $model->uid;
            $NCP_index_model->save();
            // a very simple way to tokenize the strings!
            $raw = strip_tags($model->{$fieldname});
            $tokens = explode( ' ', $raw);
            foreach ($tokens as $token) {
                $NCP_token_model = new NCPTokenModel("create");
                $NCP_token_model->NCP_index_uid = $NCP_index_model->uid;
                $NCP_token_model->token = $token;
                $NCP_token_model->save();
            }
        }
    }
    /**
     * @param $models
     * @param $tablename
     * @param $fieldnames
     */
    public static function insert_ncp_search_items($models, $tablename, $fieldnames) {
        foreach ($models as $model) {
            NCPSearch::insert_ncp_search_item($model, $tablename, $fieldnames);
        }
    }
}


// main.php:

// initialize ncp_search table once with all tables which has to be indexed in the main function
NCPSearch::insert_ncp_search_items(UserModel::model()->findAll(), "user", ["login", "mail", "name_last", "name_first"]);
NCPSearch::insert_ncp_search_items(DepartmentModel::model()->findAll(), "department", ["title", "description"]);
NCPSearch::insert_ncp_search_items(ObjectModel::model()->findAll(), "object", ["title", "description"]);
  

// model.php:

class Object : Model
{
  function afterSave()  {
    
    
     // insert this code to synchronize the informations on ncp_index
     if ($this->status === ObjectStatus::DELETED)
            NCPSearch::delete_ncp_search_item($this, "object");
        else
            NCPSearch::update_ncp_search_item($this, "object", ["title", "description"]);       
            
    ...
  }
  
  ...
  
}

Conclusion

These are my basic observations on this subject. These are the first steps to a search-engine that can index existing tables so that informations can be found quickly.

Thanks to

Github

https://github.com/Necip8/ncp_search

Homepage https://ncpup.wordpress.com

I hope this information helps you to build your own super search engine!

]]>
0
[news] Yii adopts SemVer since version 3.0.0 Tue, 13 Nov 2018 22:09:40 +0000 https://www.yiiframework.com/news/177/yii-adopts-semver-since-version-3-0-0 https://www.yiiframework.com/news/177/yii-adopts-semver-since-version-3-0-0 samdark samdark

Since version 3.0.0 Yii adopts SemVer versioning to achieve better predictability and compatibility with Composer.

Same will happen with extensions. They will adopt SemVer starting from next major versions.

SemVer is simple. Given a version number MAJOR.MINOR.PATCH, increment the:

  • MAJOR version when you make incompatible API changes,
  • MINOR version when you add functionality in a backwards-compatible manner, and
  • PATCH version when you make backwards-compatible bug fixes.

Yii 2.0.x versioning stays as is.

]]>
0
[news] Queue extension 2.1.0 released Wed, 23 May 2018 21:35:19 +0000 https://www.yiiframework.com/news/176/queue-extension-2-1-0-released https://www.yiiframework.com/news/176/queue-extension-2-1-0-released samdark samdark

We are very pleased to announce the release of Queue extension version 2.1.0.

Additionally to fixing bugs, the version brings two major enhancements on board. First, there is now Amazon SQS queue support.

Second, cli\Queue:EVENT_WORKER_LOOP worker loop event was added. It is called on each iteration between requests to queue.

Other than that, there are slightly updated documentation and new Japanese translation.

Full changelog is available at GitHub.

]]>
0
[wiki] Pjax GridView: refresh page after delete Tue, 24 Jul 2018 14:11:51 +0000 https://www.yiiframework.com/wiki/867/pjax-gridview-refresh-page-after-delete https://www.yiiframework.com/wiki/867/pjax-gridview-refresh-page-after-delete hehbhehb hehbhehb

Normally, after clicking the delete button in gridview, the record will be deleted and the page will refresh, but the page number in query string is lost. This is not always the case we expect.

How to refresh current page with pjax after deleting the record? It seems there is no very simple solution.

  1. Controller file

     public function actionDelete($id)
     {
         $this->findModel($id)->delete();
         if (Yii::$app->request->isAjax) {
             Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
             return ['success' => true];
         }
         return $this->redirect(['index']);
     }
    
  2. index.php (view file)

    <?php
     $this->registerJs("
         $(document).on('ready pjax:success', function() {
             $('.pjax-delete-link').on('click', function(e) {
                 e.preventDefault();
                 var deleteUrl = $(this).attr('delete-url');
                 var pjaxContainer = $(this).attr('pjax-container');
                 var result = confirm('Delete this item, are you sure?');                                
                 if(result) {
                     $.ajax({
                         url: deleteUrl,
                         type: 'post',
                         error: function(xhr, status, error) {
                             alert('There was an error with your request.' + xhr.responseText);
                         }
                     }).done(function(data) {
                         $.pjax.reload('#' + $.trim(pjaxContainer), {timeout: 3000});
                     });
                 }
             });
    
         });
     ");
    ?>
    
    <?php Pjax::begin(['id' => 'my_pjax']); ?>
     <div class="shop-index">
         <?= GridView::widget([
             'dataProvider' => $dataProvider,
             'filterModel' => $searchModel,
             'columns' => [
                 'id',
                 [
                     'class' => 'yii\grid\ActionColumn',
                     'buttons' => [
                         'update' => function ($url, $model) {
                             return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [
                                 'class' => 'pjax-update-link',
                                 'title' => Yii::t('yii', 'Update'),
                             ]);
                         },
                         'delete' => function ($url, $model) {
                             return Html::a('<span class="glyphicon glyphicon-trash"></span>', false, [
                                 'class' => 'pjax-delete-link',
                                 'delete-url' => $url,
                                 'pjax-container' => 'my_pjax',
                                 'title' => Yii::t('yii', 'Delete')
                             ]);
                         }
                     ],
                 ],
             ],
         ]); ?>
     </div>
    <?php Pjax::end(); ?>
    
]]>
0
[news] Gii extension 2.0.7 released Wed, 02 May 2018 22:09:25 +0000 https://www.yiiframework.com/news/175/gii-extension-2-0-7-released https://www.yiiframework.com/news/175/gii-extension-2-0-7-released samdark samdark

We are very pleased to announce the release of Gii extension version 2.0.7. The release corrects Gii behavior adapting it to changes introduced in version 2.0.15 of the framework. Additionally there are fixes in model and CRUD generators.

]]>
0
[news] Swiftmailer extension 2.1.1 released Tue, 24 Apr 2018 23:26:51 +0000 https://www.yiiframework.com/news/174/swiftmailer-extension-2-1-1-released https://www.yiiframework.com/news/174/swiftmailer-extension-2-1-1-released samdark samdark

We are very pleased to announce the release of Swiftmailer extension version 2.1.1 that fixes yii\swiftmailer\Mailer::setTransport had no effect after sending of first message.

]]>
0
[news] Smarty extension 2.0.7 released Tue, 24 Apr 2018 23:11:22 +0000 https://www.yiiframework.com/news/173/smarty-extension-2-0-7-released https://www.yiiframework.com/news/173/smarty-extension-2-0-7-released samdark samdark

We are very pleased to announce the release of Smarty extension version 2.0.7 that fixes widget registration and rendering code generation inside subtemplates and adds an ability to use SmartyBC class.

]]>
0
[wiki] Configuring PhpStorm IDE for Yii 2 Fri, 27 Apr 2018 13:08:08 +0000 https://www.yiiframework.com/wiki/865/configuring-phpstorm-ide-for-yii-2 https://www.yiiframework.com/wiki/865/configuring-phpstorm-ide-for-yii-2 CeBe CeBe

There are a few settings and plugins that can enhance the development experience with Yii in PHPStorm or IntelliJ IDEA. This article explains how to get the most out of your IDE.

This arcticle is valid for Yii 2 and above, there is an older article for Yii 1.1.

Plugins

  • Yii2 Support adds many useful tools that improve working with Yii. It makes working with class configuration, DI and views easier.

  • Yii2 Inspections is a very useful plugin that adds Yii specific code inspections to PHPStorm. It helps for example to manage @property annotations for getters and setters as well as translation messages.

  • Php Inspections (EA Extended) is not directly Yii related but has a lot of additional code inspections that help you write better code. There is also a paid version that has even more features, especially security related inspections.

Project Setup

  • Exclude runtime directories from code search. Debug toolbar stores a lot of stuff that clutters search results.

    runtime - right click - Mark Directory As - Excluded

  • Enable composer integration to tell PHPStorm to separate vendor files from project files.

    composer.json - right click - Composer - Init Composer ...

PHPUnit and Codeception

PHPStorm has integrations for PHPUnit as well as Codeception, so you can run your tests directly from the IDE.

Settings for that can be found at Run - Edit Configurations....

To add your Codeception tests, click the + button, select Codeception. Then enter the following details:

  • Name: "Codeception tests" - or whatever you want to name it
  • Test Scope: Defined in the Configuration file
  • Use alternative configuration file: "codeception.yml"
  • In case PHPStorm asks you to do it, configure a PHP Interpreter in PHPStorm settings
  • Configure Codeception binary as vendor/bin/codecept

You can now run your tests directly from PHPStorm.

For PHPUnit the steps are similar but Yii application templates do not provide PHPUnit tests by default so the options depend on your setup.

]]>
0
[wiki] How to login from different tables in Yii2 Thu, 05 Apr 2018 13:57:25 +0000 https://www.yiiframework.com/wiki/864/how-to-login-from-different-tables-in-yii2 https://www.yiiframework.com/wiki/864/how-to-login-from-different-tables-in-yii2 androidelp androidelp

The Problem: Yii2 utilizes by default UserIdentity configured in config/web.php for connection, this object appy one table to authentication ('identityClass' => 'app\painel\models\User'). How to authentication from diferent tables? Solution: Create instances in web.php to uses UserIdentify. eg:

$user = \Yii::$app->user;  
$school = \Yii::$app->school; 
$teacher = \Yii::$app->teacher;

My config/web.php

'user' => [
	'class'=>'yii\web\User',
	'identityClass' => 'app\models\User',
	'enableAutoLogin' => false,
	'authTimeout' => 60*30,
	'loginUrl' => ['dashboard/login'],
	'identityCookie' => [
		'name' => '_panelUser',
	]
],
'school'=>[
	'class'=>'yii\web\User',
	'identityClass' => 'app\models\SchoolUser',
	'enableAutoLogin' => false,
	'authTimeout' => 60*30,
	'loginUrl' => ['dashboard-school/login'],
	'identityCookie' => [
		'name' => '_panelSchool',
	]	
],
'teacher'=> [
	'class'=>'yii\web\User',
	'identityClass' => 'app\models\TeacherUser',
	'enableAutoLogin' => false,
	'authTimeout' => 60*30,
	'loginUrl' => ['dashboard-teacher/login'],
    'identityCookie' => [
		'name' => '_painelTeacher',
	]
],

Note that for each there is a identifyClass and one view login. Now, we need to create the models:

namespace app\models;
use Yii;
// My user
class User extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface
{
    public static function tableName()
    {
        return '{{%user}}';
    }
    // to continues....

Model scholl:


namespace app\models;
use Yii;
// My School
class SchoolUser' extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface
{
    public static function tableName()
    {
        return '{{%schoolUser}}';
    }
    // to continues
    

Model Teacher:


namespace app\models;
use Yii;
// My School
class TeacherUser'' extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface
{
    public static function tableName()
    {
        return '{{%teacher}}';
    }
    // to continues....

Now In my example I want to have controllers for each type of access, without generating conflicts between them:

In Behavior of the controller i have defined for dashboard-school, teacher and user, the user object representing the authentication status or the ID of the user application component.


	//behaviors of the school
public function behaviors()
{
	return [
        'access' => [
            'class' => AccessControl::className(),
            'user'=>'school', // this user object defined in web.php
            'rules' => [
                [
                    'allow' => true,
                    'roles' => ['@'],
                ],
                [
                    'allow' => true,
                    'actions' => ['login'],                    
 'roles' => ['?'],

                ],
            ],
        ]
    ];
}

To use login:

//school
\Yii::$app->scholl->login($model, $this->rememberMe ? 3600*24*30 : 0);

//teacher
\Yii::$app->teacher->login($model, $this->rememberMe ? 3600*24*30 : 0);

For restrict access in views:

<?php if (!\Yii::$app->scholl->isGuest):?>
<h1>My scholl Name: <?=\Yii::$app->scholl->identity->name?>
<?php endif;?>

<?php if (!\Yii::$app->teacher->isGuest):?>
<h1>Teacher Name: <?=\Yii::$app->teacher->identity->name?>
<?php endif;?>

Always use the specific instance of the user you want to work with.

Criticism, suggestions and improvements, use the comments

]]>
0
[news] MongoDB extension 2.1.7 released Tue, 24 Apr 2018 23:09:22 +0000 https://www.yiiframework.com/news/172/mongodb-extension-2-1-7-released https://www.yiiframework.com/news/172/mongodb-extension-2-1-7-released samdark samdark

We are very pleased to announce the release of MongoDB extension version 2.1.7 that fixes Yii 2.0.14+ incompatibility and enhances Session component error reporting.

]]>
0
[news] Shell extension version 2.0.1 released Mon, 26 Mar 2018 14:53:24 +0000 https://www.yiiframework.com/news/171/shell-extension-version-2-0-1-released https://www.yiiframework.com/news/171/shell-extension-version-2-0-1-released samdark samdark

We are very pleased to announce the release of Shell extension version 2.0.1 which updates psy/psysh dependency to 0.8.x versions.

]]>
0
[wiki] Use non Gmail/Gsuite on Gcloud projects Sun, 15 Jul 2018 14:00:50 +0000 https://www.yiiframework.com/wiki/863/use-non-gmailgsuite-on-gcloud-projects https://www.yiiframework.com/wiki/863/use-non-gmailgsuite-on-gcloud-projects gogl92 gogl92

Small companies and startups use cheap email services or even Cpanel's mail services which are less secure and compete directly with bigger email providers like Microsoft with Outlook and Google with Gmail. This creates a problem when you try to use their services to send/receive emails from this cheap services. google-cloud-platform.png

Google says this: Google Compute Engine does not allow outbound connections on ports 25, 465, and 587. By default, these outbound SMTP ports are blocked because of the large amount of abuse these ports are susceptible to. In addition, having a trusted third-party provider such as SendGrid, Mailgun, or Mailjet relieves Compute Engine and you from maintaining IP reputation with your receivers.

Some time ago I had a project that requieres this, send emails using a cpanel mail services but we have Google Cloud services so when the client send me the credentials to put it in production the app crashes in a critical time, client will not pay to use Gsuite and I have all the stuff ready for production and configured in Google Cloud, so I found a solution.

  • Make sure you have swiftmail extension installed (it also comes with the basic and advance template)
  1. First get a Gmail or Gsuite account to use it as a bridge between emails. The name doesn't matter it will never be seen by final users. let's say mail_service54@gmail.com or use a Gsuite custom email. It is also important that you have full priviledges to this email as you will need it in the next step.
  2. Enable less secure apps to your email. [https://support.google.com/accounts/answer/6010255?hl=en](Official Docs here)
  3. Now configure the swiftmailer extension to send emails with your account. I use this config for gmail/gsuite accounts:
    'mailer' => [
             'class' => 'yii\swiftmailer\Mailer',
             'transport' => [
                 'class' => 'Swift_SmtpTransport',
                 'host' => 'smtp.gmail.com',
                 'username' => 'yourmail@gmail.com',
                 'password' => 'your password',
                 'port' => '587',
                 'encryption' => 'tls',
             ],
         ],
    
  4. Test that you can send an email so we can get sure the past configuration works well.
  5. After you can send an email, login into your account on the web and go to settings > Accounts and Import > Send mail as
  6. Do the import process of the other service/cpanel email, usually they will send you a link/code to the other email and you will have to confirm it.
  7. Now you can from your gmail account send mails as some other mail.
  8. Do this in your Yii code:
    Yii::$app->mailer->compose()
     ->setFrom('from@cpanel-mail.com')
     ->setTo('to@domain.com')
     ->setSubject('Message subject')
     ->setTextBody('Plain text content')
     ->setHtmlBody('<b>HTML content</b>')
     ->send();
    

    And that's it!

This is the first post of many about using Yii/Open Source in business and enterprise level becuase Open source != not cost.

]]>
0
[news] Finally releasing the new Yiiframework.com website Mon, 03 Sep 2018 15:54:45 +0000 https://www.yiiframework.com/news/169/finally-releasing-the-new-yiiframework-com-website https://www.yiiframework.com/news/169/finally-releasing-the-new-yiiframework-com-website CeBe CeBe

We are very happy to announce that the new yiiframework.com website is finally ready for deployment.

A huge thanks to Сергей Хильков (eshill) for his design work, to Jacob Moen and Nikola Trifunović for the countless hours spent on tweaking the frontend code and doing pages markup. Thanks to prodex, Robert Korulczyk and other contributors for fixes and additions.

There is a forum topic for discussion on this announcement.

Content

The new website will keep most of the content that is currently available online. We tried to keep existing content in the same places, so URLs should be the same as before. If you find that content is missing that was available before, please report to website project issues.

You can have a look at the new site on https://new.yiiframework.com/. Please note that this is just a preview. All content there will be re-imported destroying all the changes made when we'll deploy production version. Be careful with the forum however as it is real production one proxied to the new site :)

The new website puts more focus on the documentation, making Guide and API docs the first items in the navigation. You can now also directly search for API entries from the main navigation search field. You can search for class names and also method and property names, e.g. ActiveRecord.save() or just .save() or ::save().

Wiki and Extensions are available as before. Extensions now integrate with packagist, so if your extension is listed on packagist.org you no longer have to maintain two different places, the content is automatically synced with packagist if you enter the packagist URL in the extension properties.

The community section still has the old forum, which will continue to operate as before for now. We might replace the forum with a better solution in the future (Update Sep. 3, 2018: Moving the forum to Discourse). Also badges and ranking functionality has been ported from the old website.

Other information about Yii is now grouped under the "More" point in the navigation.

User accounts

We have imported all user accounts from the old website. You should be able to log in with your user name and password as before. If it does not work, there is a password reset option. In case you lost access to your account, we'll be there to help, please report to website project issues or write an email to admin@yiiframework.com.

You can now log in with github. To connect your existing login with your github account, log in regularly first, then go to your profile page (click on your user name on the top right) and authorize github. You won't need to type password again.

Feedback

If you have feedback about the new website, or you found a bug, please report in the Github issue tracker.

Roadmap

We are going to switch to the new website on March 23, 2018 in the time frame 8:00 to 12:00 UTC. During the switch, you will not be able to write comments, wikis, forum entries etc. Also the documentation may not be available. You can use http://stuff.cebe.cc/yii2docs/ to view the documentation.

We will be avilable in the Slack chat and on IRC #yii on freenode, so if you need help, get there.

]]>
0
[news] Releasing Yii 2.0.15 and database extensions with security fixes Mon, 09 Apr 2018 21:18:03 +0000 https://www.yiiframework.com/news/168/releasing-yii-2-0-15-and-database-extensions-with-security-fixes https://www.yiiframework.com/news/168/releasing-yii-2-0-15-and-database-extensions-with-security-fixes CeBe CeBe

Today we are releasing several versions for Yii 2.0.x and official extensions to fix a security issue.

The problem addressed in these patches exists in ActiveRecord shortcut methods findOne() and findAll(), which may allow SQL injection if input is not prepared properly. We consider this as a security issue in Yii because the documentation for these methods did not contain an explicit warning that there are cases when passing unfiltered user input might be dangerous. Thanks to analitic1983 for making us aware of the issue.

The nature of this issue does not solely exists in the Yii Framework but depends on how an application uses Yii. We have changed Yii to be more robust against the worst impact of the problem (SQL injection), but applications may still be vulnerable and changes to application code are necessary in some cases. As a safety measure, findOne() and findAll() are now limited to filter on columns that are AR properties only. In the following we will explain the problem in more detail and show which application code is affected and what needs to be adjusted on upgrade.

For discussion on this issue, there is a forum topic.

Summary of Affected Classes, Methods and Composer Packages

  1. Not Affected Code
  2. Affected Code
  • yii\db\ActiveRecord::findOne() and yii\db\ActiveRecord::findAll() in yiisoft/yii2 referenced as CVE-2018-7269. Methods allow SQL injection if input is not prepared properly. Attackers could probably execute arbitrary SQL queries or circumvent access checking methods applied on query level.
  • yii\redis\ActiveRecord::findOne() and yii\redis\ActiveRecord::findAll() in yiisoft/yii2-redis referenced as CVE-2018-8073. Methods allow remote code execution in redis servers lua script environment. Attackers could probably manipulate data on the redis server.
  • yii\elasticsearch\ActiveRecord::findOne() and yii\elasticsearch\ActiveRecord::findAll() in yiisoft/yii2-elasticsearch referenced as CVE-2018-8074. Methods may allow injecting different search condition than desired or cause an error response from the elasticsearch server.

Is my Application Affected?

  1. Not Affected Code
  2. Affected Code

This vulnerability affects all releases of the 2.0.x branch. It is fixed in Yii 2.0.15. For versions below 2.0.15, we have released two patch versions, 2.0.13.2 and 2.0.12.1, which apply the fix to 2.0.13.1 and 2.0.12 respectively. Users of 2.0.14, can upgrade to 2.0.15, there are no other changes made in this release.

Not Affected Code

The methods findOne() and findAll() accept a single argument, which can be scalar or array. If the calling code ensures that a scalar is passed or if client inputs cannot modify the array's structure, your application is not affected by this issue. The following code examples are not affected by this issue (examples shown for findOne() are valid also for findAll()):

// yii\web\Controller ensures that $id is scalar
public function actionView($id)
{
    $model = Post::findOne($id);
    // ...
}
// casting to (int) or (string) ensures no array can be injected (an exception will be thrown so this is not a good practise)
$model = Post::findOne((int) Yii::$app->request->get('id'));
// explicitly specifying the colum to search, passing a scalar or array here will always result in finding a single record
$model = Post::findOne(['id' => Yii::$app->request->get('id')]);

Affected Code

The following code however is vulnerable, an attacker could inject an array with an arbitrary condition and even exploit SQL injection:

$model = Post::findOne(Yii::$app->request->get('id'));

For the above example, the SQL injection part is fixed with the patches provided in this release, but an attacker may still be able to search records by different condition than a primary key search and violate your application business logic. So passing user input directly like this can cause problems and should be avoided.

How do I Upgrade?

  1. Not Affected Code
  2. Affected Code

If you are using Yii 2.0.14:

composer require "yiisoft/yii2":"~2.0.15.0"

If you are using Yii 2.0.13:

composer require "yiisoft/yii2":"~2.0.13.2"

If you are using Yii 2.0.12:

composer require "yiisoft/yii2":"~2.0.12.1"

If you are using yii2-redis extension:

composer require "yiisoft/yii2-redis":"~2.0.8"

If you are using yii2-elasticsearch extension:

composer require "yiisoft/yii2-elasticsearch":"~2.0.5"

Update: We have since released further patches to lower the impact of the BC break introduced by the security fix, so you get versions 2.0.15.1, 2.0.13.3 and 2.0.12.2 from the above.

Upgrading isn't Enough!

  1. Not Affected Code
  2. Affected Code

Upgrading Yii addresses the SQL injection but doesn't make findOne() and findAll() safe in general. Check all usages of findOne() and findAll() in your application. Also note, that where() and filterWhere() never escape column names, so if you need to pass a variable as a column name, make sure it is safe.

]]>
0
[wiki] Yii2 RESTful API with OAuth 2.0 Thu, 08 Nov 2018 00:08:15 +0000 https://www.yiiframework.com/wiki/862/yii2-restful-api-with-oauth-2-0 https://www.yiiframework.com/wiki/862/yii2-restful-api-with-oauth-2-0 sirin_ibin sirin_ibin

https://cdn.pbrd.co/images/GMN5ROs.jpg

Overview

This article is for the one’s who is already working with PHP/Yii2 or who wants to quick start developing a RESTful API using Yii2 framework with

  1. OAuth 2.0 authentication
  2. A developer dashboard
  3. API documentation template

Here I’m sharing the Live demo and Source code of a RESTful API with OAuth2 authentication/security developed using Yii2 framework You can use this if you want to quick start developing your own custom RESTful API by skipping 95% of your scratch works. Hopefully this will save lot of your time as this API includes all the basic stuffs you need to get started.

Developer Dashboard

This API also includes a developer dashboard with the API documentation which is developed in Yii2 framework. This will be useful to manage your developers access to the API documentation.

Why Yii2?

Yii2

It's Fast, It’s Secure and Professional!. Yii comes with rich features: MVC, DAO/ActiveRecord, I18N/L10N, caching, authentication and role-based access control, scaffolding, testing, etc. It can reduce your development time significantly.

What is a RESTful API?

REST is an architectural style for building APIs. It stands for “Representational State Transfer”. It means when we build an API, we build it in a way that HTTP methods and URIs mean something, and the API has to respond in a way that’s expected.

Something about OAuth 2.0

The OAuth 2.0 is an authorization framework which enables a third-party application to obtain limited access to an HTTP service.

DEMO

http://developers.yii2.nintriva.net/

Login: developer/developer

Source Code

https://github.com/sirinibin/Yii2-RESTful-API-with-OAuth2

Official Documentation

Documentation for this RESTful API can be found on the Yii 2.0 RESTful API with OAuth 2.0 Documentation. Security Vulnerabilities

If you discover a security vulnerability within this API, please send an e-mail to Sirin k at sirin@nintriva.com. All security vulnerabilities will be promptly addressed.

Installation instructions

https://github.com/sirinibin/Yii2-RESTful-API-with-OAuth2

Similar API Implementation in NodeJs,Laravel &GoLang

Expressjs 4.15/Mysql RESTful API with OAuth2

Expressjs 4.15/MongoDb RESTful API with OAuth2

Laravel 5.5 Lumen 5.5/Mysql RESTful API with OAuth2

GoLang/MongoDb Microservice with OAuth2

Linkedin Post1

Linkedin Post2

Sirin K

]]>
0
[wiki] How to get SEO friendly URL using Model and new getUrl() function Thu, 21 Sep 2017 04:25:33 +0000 https://www.yiiframework.com/wiki/861/how-to-get-seo-friendly-url-using-model-and-new-geturl-function https://www.yiiframework.com/wiki/861/how-to-get-seo-friendly-url-using-model-and-new-geturl-function shivam4u shivam4u

We all need SEO friendly URLs for our projects. its not always good to call route with params so we can generalise it for all models using a common function.

Following the general convention of model and control sharing common name, we can use this code to get seo friendly URL.

public function getControllerID() {
		$modelClass = get_class ( $this );
		$pos = strrpos ( $modelClass, '\\' );
		$class = substr ( $modelClass, $pos + 1 );
		return Inflector::camel2id ( $class );
	}
	public function getUrl($action = 'view', $id = null) {
		$params = [ 
				$this->getControllerID () . '/' . $action 
		];
		if ($id != null)
			$params ['id'] = $id;
		else
			$params ['id'] = $this->id;
		// add the title parameter to the URL
		$params ['title'] = ( string ) $this;
		// absolute url
		return Yii::$app->getUrlManager ()->createAbsoluteUrl ( $params, true );
	}

In code code where ever you need to url to a model , you just call $model->url or $model->getUrl('view').

You may have to additionally update urlManager in config with rules for pretty url.

'<controller:[A-Za-z-]+>/<id:\d+>/<title>' => '<controller>/view',
								'<controller:[A-Za-z-]+>/<id:\d+>' => '<controller>/view',
								'<controller:post>/<id:\d+>/<title>' => 'blog/view',
								'<controller:[A-Za-z-]+>/<action:[A-Za-z-]+>/<id:\d+>/<title>' => '<controller>/<action>',
								'<controller:[A-Za-z-]+>/<action:[A-Za-z-]+>/<id:\d+>' => '<controller>/<action>',
	

you will get url like this.

http://localhost/link/650/need-a-professional-developer

]]>
0
[wiki] Yii2 Report Grid Mon, 26 Mar 2018 10:10:29 +0000 https://www.yiiframework.com/wiki/860/yii2-report-grid https://www.yiiframework.com/wiki/860/yii2-report-grid chrisb34 chrisb34

A Yii2 Gridview designed specifically for reporting

  1. Why is this significant
  2. Widget Setup
  3. Column Configuration

There are some very advanced grids in the Yii2 community, specifically Kartik's amazing gridview extensions but they all designed for interactive screen use.

ReportGrid is designed to provide report results to users, without filtering or sorting.

But more importantantly it has sub-totalling and report totalling built into the gridview itself.

Why is this significant

Because it enables you to use closures (anonymous functions) within the sub-total fields. For example, say we want to build a report on order items, with a break at order level. At the order level, we want to report something off the order model but the dataProvider is on the order-item level.

With ReportGrid, we can do this by using a closure on the sub-total to return the $model->order->some_relationship->some_value

Installation The preferred way to install this extension is through composer. Either run:

$ php composer.phar require chrisb34/reportgrid "@dev"

or add:

"chrisb34/yii2-report-grid": "@dev"

to the require section of your composer.json file. Then run:

php composer.phar update

to get the updated package on your application install.

Widget Setup

As with most Yii2 widgets, you control the using options on widget creation. This widget is based on the Yii2 gridview widget, so anything mentioned here is over and above the base options on the gridview widget

Note: that this widget does not support pagination. It actively switches pagination off in the dataProvider

  • controlBreak : boolean, turn on all this functionality. defaults to true. If set to false will make this widget behave like a notmal gridView

  • totalRowOptions : array, array list of options eg: [ 'class'=>'total-row']

  • totalsHeader : boolean, whether to repeat the table header row just before the report totals.

  • exportCSV : boolean, whether to include the 'Export to CSV' button

  • afterRow : closure, provides the ability to output an extra row after every model row. Closure call in the format function( $model, $key, $index)

  • pageSummary : closure, provides the ability to output an extra row at the end of the report. Closure call in the format function( $model, $key, $index)

Usage

echo ReportGrid::widget([
    'dataProvider' => $dataProvider,
    'columns' => $gridColumns,
    'controlBreak' => true,
    'totalRowOptions' => ['class'=>'total-row'],
    'totalsHeader' => true,
    'exportCSV' => true,
    'afterRow' => function( $model, $key, $index)  {
    	return $someContent;
    },
    'pageSummary' => [
            Html::tag('tr','<td colspan=10><h1>Report Summary goes here</h1></td>'),
    ]
    
    ]);

Column Configuration

When you use sub-totalling in a report, your report layout must follow the same structure as your query. So the first thing is to define your query with the results in the correct order.

When defining columns, you first need to specify which columns will cause your report to break. Normally, these will also be in the same order as the columns themselves but this is not mandatory.

  • subTotalOn : integer, The break level runs from 1 upwards and the gridview then uses level zero as the report totals.

  • subTotal : array | boolean, with the following options;
    • if set to true, then reportGrid uses the attribute value, summing the model->attribute or model->value amounts.
    • value : string|attribute name|closure ~ function($model, $key, $index, $widget, $break) {}, the value used by the totalling function as opposed to the value displayed.
    • breakValue : string|attribute name|closure ~ function($model, $key, $index, $widget, $break) {}, what to display in the sub-total cell. note the addition of the $break variable which can be used to determine the current break level. For example: you may use if ($break!=1) return $model->some_amount; else return ' ';
    • showOnBreak | hideOnBreak : integer, show/hide the sub-total at the specified break level
    • format : boolean, uses the yii2 formatter to pre-format the cell contents eg: currency, html, text
    • totalMethod : the only available option at this stage is ReportColumn::TOTAL_BREAKDOWN, This will provide a summary table at the control break of this column values and summed values specified by totalOn.
    • totalOn : string|attribute name|closure ~ function($model, $key, $index, $widget, $break) { return $model->attribute; },, the value to be applied to the totalling.

Usage

'subTotal' => [
       'breakValue' => function($model, $key, $index, $widget, $break) {
           if ($break == 1)
               return   $model->category_name; 
           elseif ($break == 0)
               return 'REPORT TOTAL';
       },
       'hideOnBreak' => 2
       ]
	

for more info see: yii2.percipero.com

]]>
0
[wiki] How to make UrlManager createAbsoluteUrl work with sub-domains Sun, 25 Mar 2018 02:06:47 +0000 https://www.yiiframework.com/wiki/858/how-to-make-urlmanager-createabsoluteurl-work-with-sub-domains https://www.yiiframework.com/wiki/858/how-to-make-urlmanager-createabsoluteurl-work-with-sub-domains wadeshuler wadeshuler

Upon creating my Yii2 Members System, I have ran into a few snags along the way that forced me to extend and bend Yii2 to my will.

I will describe how my app is intended to work, so you know how this article fits into your project needs. My members system is designed to resemble the good ole' days, when we had site.com/members and site.com/admin. It is common to also have them on sub-domains as members.site.com and admin.site.com . The sub-domains add an extra layer of security, especially with the admin on it's own sub-domain separate from the users. Now, that alone wont save you from everything, but as I said, it's just an extra layer. Some of us need them separated like this, because the sub-domains are on different servers. For example, your API could be on an independent server. Or maybe your users and admin sections are on different servers or IPs. If you look at large systems like Microsoft or Adobe, they have many servers for many different uses. Users, API, time, activation, fonts, and many more... So it isn't crazy to want your apps on different sub-domains.

Unfortunately, Yii2 is flat out retarded when it comes to sub-domains. Hopefully they will implement what I am about to show you, or a better version of this. I am always open to a better way to do this.

When I Googled this issue, there wasn't much out there. I found info related to how to link to backend from frontend, and that is even in the official Yii2 docs. That DOES NOT work with sub-domains though! It only works for directories, ie: what comes after your domain, not the sub-domain. I did find one GitHub repo from Postor. Problem was, it wasn't very intuitive and looks like a broken unfinished repo. So I feel the one I made was better.

So in this guide, I am going to show you the best and only way I found to create links to another one of your Yii apps (ie: backend or frontend) that are on a sub-domain.

My method for handling sub-domains

Unfortunately, there isn't an accurate and reliable way to grab only the domain name. A bunch of regex or stripping, or pulling from a huge list of valid domain extensions, etc. Nothing you want running on a site with tons of users, it will create a bottle neck real quick. Yeah, you could implement caching and you should for large volume sites. However, I prefer to cache lean efficient code instead of using caching to save my rear on terrible logic.

So this REQUIRES us to define our domain and sub-domains in our common bootstrap file.

common/config/bootstrap.php

// URL Manager Aliases
Yii::setAlias('@domainName', (YII_ENV === 'dev') ? 'yii2-members-system.dev' : 'yourlivesite.com');
Yii::setAlias('@frontendSubdomain', 'users');
Yii::setAlias('@backendSubdomain', 'admin');

Create common/components/UrlManager.php

<?php
namespace common\components;

use Yii;
use yii\helpers\Url;
use yii\base\InvalidConfigException;

class UrlManager extends yii\web\UrlManager
{
    public $subDomain;
    public $domainName;

    protected $_hostInfo;

    public function getProperDomain()
    {
        if ( ! isset($this->domainName) || empty($this->domainName) ) {
            throw new InvalidConfigException('Request requires a domain name to be configured!');
        }

        $subDomain = (isset($this->subDomain) && !empty($this->subDomain)) ? $this->subDomain : '';
        $domain = empty($subDomain) ? '' : $subDomain . '.';
        $domain .= $this->domainName;

        return $domain;
    }

    public function getHostInfo()
    {
        if ($this->_hostInfo === null)
        {
            $secure = Yii::$app->getRequest()->getIsSecureConnection();
            $http = $secure ? 'https' : 'http';

            if (isset($_SERVER['HTTP_HOST'])) {
                $this->_hostInfo = $http . '://' . $this->getProperDomain();
            } elseif (isset($_SERVER['SERVER_NAME'])) {
                $this->_hostInfo = $http . '://' . $this->getProperDomain();
                $port = $secure ? $this->getSecurePort() : $this->getPort();

                if (($port !== 80 && !$secure) || ($port !== 443 && $secure)) {
                    $this->_hostInfo .= ':' . $port;
                }
            }
        }
        return $this->_hostInfo;
    }

}

Now in whichever app your needing to link to another subdomain, you need to edit it's main config. So if in backend you need to link to frontend (or mainsite needs to link to frontend as in my members system), then edit your backend config.

Add this to your config under the components array:

'urlManagerFrontend' => [
    'class' => 'common\components\UrlManager',
    'subDomain' => Yii::getAlias('@frontendSubdomain'),
    'domainName' => Yii::getAlias('@domainName'),
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'rules' => [
    ],
],

Now, wherever you need to create a link (or get the url for any reason) use CreateAbsoluteUrl inside the new UrlManager like so:

Yii::$app->urlManagerFrontend->createAbsoluteUrl(['site/login'])

In my app, it generates a link for my mainsite to the users app: http://users.yii2-members-system.dev/site/login. This was so on my mainsite I can link to the user's subdomain for them to login.

I hope this helps someone, and I hope Yii actually adopts a solution for this sort of linking and handling sub-domains.

]]>
0
[wiki] Show raw SQL query Sat, 14 Jan 2017 19:53:41 +0000 https://www.yiiframework.com/wiki/857/show-raw-sql-query https://www.yiiframework.com/wiki/857/show-raw-sql-query darioo darioo

Here's a quick tip to dump the SQL for query.

$query = new Books::find()->where('author=2');
echo $query->createCommand()->sql;

or to get the SQL with all parameters included try:

$query->createCommand()->getRawSql()

Thanks to http://chris-backhouse.com/Yii2-Output-the-SQL-from-a-query-builder/1027

]]>
0
[wiki] Working with relational removals by yii2 Mon, 05 Jun 2017 03:57:13 +0000 https://www.yiiframework.com/wiki/856/working-with-relational-removals-by-yii2 https://www.yiiframework.com/wiki/856/working-with-relational-removals-by-yii2 androidelp androidelp

This tutorial shows you how to safely remove records between relationships.

First we create three tables using a Many to Many relationship.

Imagem da relacao

Important: Apply cascade to foreign key constraints for update and delete.

The cascade feature will allow you to remove the foreign keys along with the line you want to delete and helps keep your code to a minimum.

Script SQL the ralation has.

CREATE TABLE `tests_has_games` (
   `tests_id` int(11) NOT NULL,
   `games_id` int(11) NOT NULL,
   PRIMARY KEY (`tests_id`,`games_id`),
   KEY `fk_tests_has_games_games1_idx` (`games_id`),
   KEY `fk_tests_has_games_tests_idx` (`tests_id`),
   CONSTRAINT `fk_tests_has_games_games1` FOREIGN KEY (`games_id`) REFERENCES `games` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
   CONSTRAINT `fk_tests_has_games_tests` FOREIGN KEY (`tests_id`) REFERENCES `tests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

Step 2: Create models: (to use generator gii, this system create model with relations of the table). ModelGames:

public function getTestsHasGames()
    {
        return $this->hasMany(TestsHasGames::className(), ['games_id' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getTests()
    {
        return $this->hasMany(Tests::className(), ['id' => 'tests_id'])->viaTable('{{%tests_has_games}}', ['games_id' => 'id']);
    }

Model Tests:

public function getTestsHasGames()
    {
        return $this->hasMany(TestsHasGames::className(), ['tests_id' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getGames()
    {
        return $this->hasMany(Games::className(), ['id' => 'games_id'])->viaTable('{{%tests_has_games}}', ['tests_id' => 'id']);
    }

Step 3: Simple Removal Functions in controllers:

public function actionDeletarTest($id)
  {

    $session = \Yii::$app->session;

    $testes = Tests::findOne($id);

    if($testes->delete())
    {
      $session->addFlash('resposta', [
        'type'=>'success',
        'msg'=>'Teste deletado com sucesso.'
      ]);
    }else{
      $session->addFlash('resposta', [
        'type'=>'danger',
        'msg'=>'Erro encontrado favor resolver.'
      ]);
    }

    return $this->redirect(['site/delete-relations']);

  }

Other Methods

public function actionDeleteListGames()
  {
    $array_id = [1,2,3,4];

    $games = Games::find()->where(['in','id',$array_id])->all();

    foreach($games as $k => $game)
    {
      $game->delete();
    }

  }
     // deletando de vinculo
     public function actionDeleteTestAll()
     {
       $game = Games::findOne(1);
       foreach($game->tests as $test)
       {
          $test->delete();
       }
     }


public function actionDeleteTheRelation($id)
  {


    $game = Games::find()->joinWith(['tests'=>function($q){
      return $q->where(['like','nome','proccess'])
    }])->where(['id'=>$id])->one();

    foreach($games->tests as $k => $test)
    {
      $test->delete();
    }

  }

Get All code in Your text to link here...

]]>
0
[wiki] Interactive mode command-line command for Yii1 Mon, 21 Nov 2016 12:41:10 +0000 https://www.yiiframework.com/wiki/854/interactive-mode-command-line-command-for-yii1 https://www.yiiframework.com/wiki/854/interactive-mode-command-line-command-for-yii1 trejder trejder

For one of my projects I needed an interactive console command in Yii 1, i.e. the one that is gathering all information from user in an interactive mode (a serie of questions and answers displayed directly in the console), ignoring command-line arguments at all.

This is an example (or rather a bare foundation, as this actually is doing nothing) of such solution. It has some console text formatting methods (borders, text alignment) plus simple method for gathering user response.

The code

Here is an implementation for Yii 1 of mentioned solution.

class ImportCommand extends CConsoleCommand
{
    const BORDER_WIDTH = 80;

    public function actionIndex($args)
    {
        $message = $this->alignText('This text is aligned to the right border...', 'right')."\n";
        $message .= "\n";
        $message .= $this->alignText('...this one is centered...', 'center')."\n";
        $message .= "\n";
        $message .= $this->alignText('...and this is left as is, so aligned to the left border!', 'left')."\n";
        $message .= "\n\n";
        $message .= $this->alignText('Finally we have a really long text, no matter, how aligned, that is going to be cut right there, where it should');

        $this->drawBorder($message);

        $this->readStdin();

        echo 'You selected: '.$this->readStdin('Enter any alphabet letter, please...');
        
        $this->clearStdin();
    }

    /**
     * Aligns text to given margin.
     * 
     * @param  string $text       Text to be aligned.
     * @param  string $align      Align method: 'right', 'center' or 'left' (default == empty string).
     * @param  integer $lineWidth Maximim line width. If not specified, class' constant will be used instead.
     * 
     * @return string             Aligned text, pad with trailing and following spaces.
     */
    public function alignText($text, $align = 'left', $lineWidth = null)
    {
        $lineWidth = is_null($lineWidth) ? self::BORDER_WIDTH : $lineWidth;
        $lineWidth = $lineWidth - 4;

        $text = strlen($text) > $lineWidth ? substr($text, 0, $lineWidth) : $text;

        if($align === 'right')
        {
            return str_repeat(' ', $lineWidth - strlen($text)).$text;
        }

        if($align === 'center')
        {
            $margin = floor($lineWidth  / 2) - floor(strlen($text) / 2);

            return str_repeat(' ', $margin).str_pad($text, $margin , ' ');
        }
        else return $text;
    }

    /**
     * Draws console-like (DOS-like?) text border around passed text.
     * 
     * @param  string $text       Text to be outlined in a fancy-like text border.
     * @param  integer $lineWidth Maximim width of each border line. See above for details.
     */
    public function drawBorder($text, $lineWidth = null)
    {
        $lineWidth = is_null($lineWidth) ? self::BORDER_WIDTH : $lineWidth;
        $lineWidth = $lineWidth > 80 ? 80 : $lineWidth;

        $nl = $lineWidth === 80 ? '' : "\n";

        echo str_repeat('*', $lineWidth).$nl;

        echo '*'.str_repeat(' ', $lineWidth - 2).'*'.$nl;

        foreach(explode("\n", $text) as $line) echo '* '.str_pad($line, $lineWidth - 4, ' ').' *'.$nl;

        echo '*'.str_repeat(' ', $lineWidth - 2).'*'.$nl;

        echo str_repeat('*', $lineWidth).$nl;
    }

    /**
     * Get user entry / decision.
     * 
     * @param  string $message Information to be displayed, when requiring user to enter something.
     * 
     * @return string          User entry.
     */
    public function readStdin($message = 'Continue [Y/N]?')
    {
        echo $message;

        $handle = fopen("php://stdin","r");
        $line = fgets($handle);

        return trim($line);
    }
    
    /**
     * Clears console window.
     *
     * The implementation used here can't be anymore ugly, but it is the only one,
     * that is working, when using GitBash. All other methods fails:
     *
     * http://stackoverflow.com/a/24327758/1469208
     * http://stackoverflow.com/a/29193143/1469208
     */
    public function clearStdin()
    {
        for ($i = 0; $i < 50; $i++) echo "rn";
    }
}

Execution

To get this thing working, put all the above code in a separate .php file and save it to protected/commands path under ImportCommand.php name.

Then open console window, navigate to protected folder in your application and execute:

yiic import

Of course, rename both file and class name, if you want to use this command under different name.

Also make sure that you have set correctly everything around running console commands.

]]>
0
[wiki] REST API and null values in XML Fri, 11 Nov 2016 00:26:44 +0000 https://www.yiiframework.com/wiki/853/rest-api-and-null-values-in-xml https://www.yiiframework.com/wiki/853/rest-api-and-null-values-in-xml marko60 marko60

I have been working on a REST API using the excellent tools provided by Yii2. My problem was that I have to differentiate between empty values and null values. In other words, <elem></elem> is different from null as it represents an empty string. Also, although some use <elem/> to represent a null value it should still be interpreted as an empty string. In other cases, the absence of the element is taken to represent a null value, but this may create problem with some parsers.

After some research, it appears that the correct way of describing a null value is <elem xsi:nil="true"/>.

However this is not supported by the current implementation of XmlResponseFormatter because values are always appended as DOMText. This means that, even is I pass a PHP null value, I get <elem></elem>.

Therefore, I have extended XmlResponse Formatter as follows.

Firstly, the function format() must be modified because creating $root as DOMElement makes it immutable while I need to attach the xsi: namespace definition. Therefore I use:

...
$dom = new DOMDocument($this->version, $charset);
// A writeable element is created and the namespace added
$root = $dom->createElement($this->rootTag);
$root->setAttributeNS('http://www.w3.org/2000/xmlns/' ,'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$dom->appendChild($root);
...

Then I have modified the buildXml function as follows:

protected function buildXml($element, $data){
  if (is_array($data) ||
    ($data instanceof \Traversable && $this->useTraversableAsArray && !$data instanceof Arrayable)
  ) {
    foreach ($data as $name => $value) {
      if (is_int($name) && is_object($value)) {
        $this->buildXml($element, $value);
      } elseif (is_array($value) || is_object($value)) {
        $child = new DOMElement(is_int($name) ? $this->itemTag : $name);
        $element->appendChild($child);
        $this->buildXml($child, $value);
      } else {
        $child = new DOMElement(is_int($name) ? $this->itemTag : $name);
        $element->appendChild($child);
        // Checks if the value is null and creates a null MXL element
        if ($value === null) {
          $child->setAttributeNS('http://www.w3.org/2001/XMLSchema-instance','xsi:nil','true');
        } else {
          $child->appendChild(new DOMText((string) $value));
        }
      }
    }
  } elseif (is_object($data)) {
    $child = new DOMElement(StringHelper::basename(get_class($data)));
    $element->appendChild($child);
    if ($data instanceof Arrayable) {
      $this->buildXml($child, $data->toArray());
    } else {
      $array = [];
      foreach ($data as $name => $value) {
        $array[$name] = $value;
      }
      $this->buildXml($child, $array);
    }
  } else {
    // Checks if $data is null and adds xsi:nil to $element
    if ($data === null) {
      $element->setAttributeNS('http://www.w3.org/2001/XMLSchema-instance','xsi:nil','true');
    } else {
      $element->appendChild(new DOMText((string) $data));
    }
  }
}

This way, if the value of the XML element is null, I get <element xsi:nil="true"/> which is more correct while, if the value is an empty string, I get <element></element> as expected.

I hope this would be useful to somebody and maybe the Yii2 could consider this improvement in a future release.

]]>
0
[wiki] Optimize Scenarios for yii2 Thu, 12 Apr 2018 13:24:16 +0000 https://www.yiiframework.com/wiki/852/optimize-scenarios-for-yii2 https://www.yiiframework.com/wiki/852/optimize-scenarios-for-yii2 androidelp androidelp

Working with scenarios, with models that can receive many modifications in their rules or structures as development evolves, can create disruptions in the rescue process.

One way to avoid this disorder is to encapsulate the information defined for the scenarios and to have a single point of customization.

For this we need to create constants for each scenario, note: once you define a scenario, you will need to use scenarios for any database edition that uses this model.

In model

class MyModel extends \yii\db\ActiveRecord
{

  const SCENARIOCRIATE = 'scenariocriate';
  const SCENARIOUPDATE = 'scenarioupdate';

    // scenarios encapsulated
    public function getCustomScenarios()
    {
      
      return [
          self::SCENARIOCRIATE      =>  ['user_id', 'name', 'desc', 'published','date_create'],
          self::SCENARIOUPDATE      =>  ['user_id', 'name', 'desc', 'date_update'],
      ];
    }
    // get scenarios
    public function scenarios()
    {
        $scenarios = $this->getCustomScenarios();
        return $scenarios;
    }

    // modify itens required for rules
    public function ModifyRequired()
    {

      $allscenarios = $this->getCustomScenarios();
      // published not required
      $allscenarios[self::SCENARIOCRIATE] = array_diff($allscenarios[self::SCENARIOCRIATE], ['published']);
      return $allscenarios;

    }

    public function rules()
    {
      // get scenarios
      $allscenarios = $this->ModifyRequired();
        return [
            [$allscenarios[self::SCENARIOCRIATE], 'required', 'on' => self::SCENARIOCRIATE],
            [$allscenarios[self::SCENARIOUPDATE], 'required', 'on' => self::SCENARIOUPDATE],
            [['user_id'], 'integer'],
            [['name','desc'], 'string', 'max' => 70],
            [['date_create', 'date_update'], 'date', 'format' => 'php:Y-m-d H:i:s'],
        ];
    }

GetCustomScenarios will be used for when you need to make column modifications.

The ModifyRequired is used to remove from the required, because at this point will be used getCustomScenarios for the save.

In Controller

public function actionIndex()
{

    $model = new MyModel;
    $model->scenario = 'scenariocriate';

    if ($model->load(\Yii::$app->request->post())){

        // force my columns
        if($model->save()){
          //return true
        } 
    }
}

It may seem redundant, but constructing the controller in this way, avoids having problems with maintenance of database tables, the adjustments will be made only in the model, since there is no reference of communes in the controller.

]]>
0