I have a problem with fixtures in yii2 , I just created all required file according to this document but it's not working.
let me explain , I have a module called Authyii and inside this module I have a model named User .
this is my directory structure :
my fixture file is like this :
namespace app\modules\Authyii\tests\fixtures;
use app\modules\Authyii\models;
use yii\test\ActiveFixture;
use yii\test\Fixture;
class UserFixture extends ActiveFixture
{
public $modelClass = 'app\modules\Aythyii\models\User';
public $tableName = 'authyii_user';
}
this is my command line :
but after I type 'yes' and command line says :
but when I check my database there is not new record inside authyii_user tables .
what I missed ?
File User.php id data dir must have table name authyii_user.php. In framework source code in file ActiveFixture.php line with code:
$dataFile = dirname($class->getFileName()) . '/data/'
. $this->getTableSchema()->fullName . '.php';
Best regards.
There is method getFixturesConfig() in \vendor\yiisoft\yii2\console\controllers\FixtureController.php
private function getFixturesConfig($fixtures)
{
$config = [];
foreach ($fixtures as $fixture) {
$isNamespaced = (strpos($fixture, '\\') !== false);
$fullClassName = $isNamespaced ? $fixture . 'Fixture' : $this->namespace . '\\' . $fixture . 'Fixture';
if (class_exists($fullClassName)) { // <<< I think you lose your UserFixture here
$config[] = $fullClassName;
}
}
return $config;
}
You should check what $fullClassName Yii expects it to be (for example logging or echoing it) and tweak your UserFixture's namespace accordingly.
Related
I am having a node type with machine name to_do_item, and I want to create a module called managefinishdate to update the node: when a user edit the node's field (field_status) to "completed" and click "save", then the module will auto update the field_date_finished to current date.
I have tried to create the module and already success to install in "Extend":
function managefinishdate_todolist_update(\Drupal\Core\Entity\EntityInterface $entity) {
...
}
however, I am not sure is this module being called, because whatever I echo inside, seems nothing appeared.
<?php
use Drupal\Core\Entity\EntityInterface;
use Drupal\node\Entity\Node;
/** * Implements hook_ENTITY_TYPE_update().
* If a user update status to Completed,
* update the finished date as save date
*/
function managefinishdate_todolist_update(\Drupal\Core\Entity\EntityInterface $entity) {
$node = \Drupal::routeMatch()->getParameter('node');
print_r($node);
//$entity_type = 'node';
//$bundles = ['to_do_item'];
//$fld_finishdate = 'field_date_finished';
//if ($entity->getEntityTypeId() != $entity_type || !in_array($entity->bundle(), $bundles)) {
//return;
//}
//$current_date=date("Y-m-d");
//$entity->{$fld_finishdate}->setValue($current_date);
}
Following Drupal convention, your module named 'manage_finish_date' should contain a 'manage_finish_date.module file that sits in the root directory that should look like this:
<?php
use Drupal\node\Entity\Node;
/**
* Implements hook_ENTITY_TYPE_insert().
*/
function manage_finish_date_node_insert(Node $node) {
ManageFinishDate::update_time();
}
/**
* Implements hook_ENTITY_TYPE_update().
*/
function manage_finish_date_node_update(Node $node) {
ManageFinishDate::update_time();
}
You should also have another file called 'src/ManageFinishDate.php' that should look like this:
<?php
namespace Drupal\manage_finish_date;
use Drupal;
use Drupal\node\Entity\Node;
class ManageFinishDate {
public static function update_time($node, $action = 'create') {
// Entity bundles to act on
$bundles = array('to_do_item');
if (in_array($node->bundle(), $bundles)) {
// Load the node and update
$status = $node->field_status->value;
$node_to_update = Node::load($node);
if ($status == 'completed') {
$request_time = Drupal::time();
$node_to_update->set('field_date_finished', $request_time);
$node_to_update->save();
}
}
}
}
The code is untested, but should work. Make sure that the module name, and namespace match as well as the class filename and class name match for it to work. Also, clear you cache once uploaded.
This will handle newly created and updated nodes alike.
Please look after this sample code which may help you:
function YOUR_MODULE_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
switch ($entity->bundle()) {
//Replace CONTENT_TYPE with your actual content type
case 'CONTENT_TYPE':
$node = \Drupal::routeMatch()->getParameter('node');
if ($node instanceof \Drupal\node\NodeInterface) {
// Set the current date
}
break;
}
}
I have upload CSV file but problem is i don't know how to read data of uploaded csv file in Magento2.
Please help me anyone.
Thanks in advance.
You can do that like you could in Magento 1. In Magento 1 you would use
new Varien_File_Csvbut in Magento 2 you can do the same with \Magento\Framework\File\Csv. You can use the following code.
In your __construct() inject the following classes:
protected $_fileCsv;
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Magento\Framework\Module\Dir\Reader $moduleReader,
\Magento\Framework\File\Csv $fileCsv
) {
$this->_moduleReader = $moduleReader;
$this->_fileCsv = $fileCsv;
parent::__construct($context); // If your class doesn't have a parent, you don't need to do this, of course.
}
Then you can use it like this:
// This is the directory where you put your CSV file.
$directory = $this->_moduleReader->getModuleDir('etc', 'Vendor_Modulename');
// This is your CSV file.
$file = $directory . '/your_csv_file_name.csv';
if (file_exists($file)) {
$data = $this->_fileCsv->getData($file);
// This skips the first line of your csv file, since it will probably be a heading. Set $i = 0 to not skip the first line.
for($i=1; $i<count($data); $i++) {
var_dump($data[$i]); // $data[$i] is an array with your csv columns as values.
}
}
How can I rename file if the file with the same name exist (prevent overwrite)? This method is used for uploading file:
// Upload user avatar
public function upload()
{
if ($this->validate()):
$this->avatar->saveAs('../web/images/avatars/' . $this->avatar->baseName . '.' . $this->avatar->extension);
return true;
endif;
return false;
}
Test if file exists with php function and then assign a proper name to your file:
$cnt = 1;
while (file_exists(string $filename)) {
$filename = $this->avatar->basename . $cnt;
$cnt++;
}
Then save.
PHPUnit has an option to take a screenshot upon a Selenium test case failure. However, the screenshot filename generated is a hash of something - I don't know what exactly. While the test result report allows me to match a particular failed test case with a screenshot filename, this is troublesome to use.
If I could rename the screenshot to use the message from the failed assert as well as a timestamp for instance, it makes the screenshots much easier to cross-reference. Is there any way to rename the generated screenshot filename at all?
You could try something like this (it's works with selenium2):
protected function tearDown() {
$status = $this->getStatus();
if ($status == \PHPUnit_Runner_BaseTestRunner::STATUS_ERROR || $status == \PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) {
$file_name = sys_get_temp_dir() . '/' . get_class($this) . ':' . $this->getName() . '_' . date('Y-m-d_H:i:s') . '.png';
file_put_contents($file_name, $this->currentScreenshot());
}
}
Also uncheck
protected $captureScreenshotOnFailure = FALSE;
I ended up using a modified version of #sectus' answer:
public function onNotSuccessfulTest(Exception $e) {
$file_name = '/' . date('Y-m-d_H-i-s') . ' ' . $this->getName() . '.png';
file_put_contents($this->screenshotPath . $file_name, base64_decode($this->captureEntirePageScreenshotToString()));
parent::onNotSuccessfulTest($e);
}
Although the conditional check in tearDown() works fine, based on Extending phpunit error message, I decided to go with onNotSuccessfulTest() as it seemed cleaner.
The filename could not accept colons :, or I would get an error message from file_get_contents: failed to open stream: Protocol error
The function currentScreenshot also did not exist, so I ended up taking the screenshot in a different way according to http://www.devinzuczek.com/2011/08/taking-a-screenshot-with-phpunit-and-selenium-rc/.
Another method I played around with, as I still wanted to use $this->screenshotUrl and $this->screenshotPath for convenient configuration:
I overwrote takeScreenshot from https://github.com/sebastianbergmann/phpunit-selenium/blob/master/PHPUnit/Extensions/SeleniumTestCase.php
protected function takeScreenshot() {
if (!empty($this->screenshotPath) &&
!empty($this->screenshotUrl)) {
$file_name = '/' . date('Y-m-d_H-i-s') . ' ' . $this->getName() . '.png';
file_put_contents($this->screenshotPath . $file_name, base64_decode($this->captureEntirePageScreenshotToString()));
return 'Screenshot: ' . $this->screenshotUrl . '/' . $file_name . ".png\n";
} else {
return '';
}
}
if (isset($_POST['Software'])) {
$_POST['Software']['sw_icon'] = $model->sw_icon;
$model->attributes = $_POST['Software'];
$uploadedFile = CUploadedFile::getInstance($model, 'sw_icon');
$model->attributes = $_POST['Software'];
$model->updated_date = date("Y-m-d H:i");
if ($model->save()) {
if (!empty($uploadedFile)) { // check if uploaded file is set or not
$uploadedFile->saveAs(Yii::app()->basePath . '/../images/software_icons/' . $model->sw_icon);
}
Yii::app()->user->setFlash('success', 'Software updated successfully.');
$this->redirect(array('index'));
}
}
When I use the above code i get the following error
...move_uploaded_file(): The second argument to copy() function
cannot be a directory.
Can you show me the result of Yii::app()->basePath . '/../images/software_icons/' . $model->sw_icon,seems like it a directory
You can move a file to another file name. You can't move a file to a folder.
Try replace Yii::app()->basePath . '/../images/software_icons/' . $model->sw_icon on
this: Yii::app()->basePath . '/../images/software_icons/newfile'