How do i save files in a dyanamic location in PHP Yii2? - yii2

I want to save files to directories based on company id like if company has id of 11 then it should create a folder of same name and save/upload the files there?
I have my controller logic here but i dont know how to pass my company id which is in Company Model to saveAs() function.
Scene: I have list of companies from different model and i want to create a directory according to company id/name where the respective layout gets saved.
public function actionCreate()
{
$company=Company::find()->all();
$model = new Layouts();
// if ($model->load(Yii::$app->request->post()) && $model->save()) {
// return $this->redirect(['view', 'id' => $model->layout_id]);
// }
$model->setScenario('create');
if ($model->load(Yii::$app->request->post())) {
$model->layouts=UploadedFile::getInstance($model,'layouts');
if(!empty($model->layouts)){
$filename=time()."_layouts".".". $model->layouts->extension;
$model->layouts->saveAs('#app/web/uploads/layouts/'.$filename); //here i want it to be #app/web/uploads/layouts/company-id/filename
$model->layouts=$filename;
$model->created_by=Yii::$app->user->id;
$model->updated_by=Yii::$app->user->id;
}else{
var_dump($model->errors);die;
}
if($model->save()){
Yii::$app->session->addFlash('success','Record Created Successfully');
return $this->redirect(['view','id'=>$model->id]);
}else{
Yii::$app->session->addFlash('error','Record Can not be Created ');
}
return $this->render('create', [
'model' => $model,
'company'=>$company
]);
}
}

You should create folder first,
\yii\helpers\FileHelper::createDirectory(\Yii::getAlias('#app/web/uploads/layouts/'.$model->id), 0777);

Related

Yii2, on login from frontend redirect to backend?

After login from frontend in yii2 I want, page should redirect to backend index page.
public function actionLogin()
{
if (!Yii::$app->user->isGuest) {
return $this-> render('commercial');
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
$this->layout = 'noBar';
return $this-> render('home'); //backend/index should be open
} else {
return $this->render('login', [
'model' => $model,
]);
}
}
I have tried in many ways (like Url manager n all) but did not get the required result?
Instead this line:
return $this-> render('home'); //backend/index should be open
Write:
return $this->redirect('https://yoursite.com/backend/site/index');
Or you can make backendUrlManager in config like :
Yii2 Links between Frontend and Backend (advanced template)

how to add data from Employee table to user table in YII2 advanced

I am working on my collage project i.e. Employee Management. I have Employee table in sql(crud is also generated from gii). only Admin is having rights to create Employee (there is no Signup).
My Problem: when I am creating employee then I am not able to save data in user table also, please help me to save data in both Employee and user table.
Thanks in advance
Update:
Below is the code:
public function actionCreate() {
$model1=new Employee;
$model2=new User;
if(isset($_POST['Employee']) && isset($_POST['User']))
{
$model1->attributes=$_POST['Emoloyee'];
$model2->attributes=$_POST['User'];
$model1->save();
$model2->save();
echo 'data is saved in both tables';
}
$this->render('create',array('model1'=>$model1,model2'=>$mod‌​‌​el2));
}
could be you have some validation problem
try check this way
......
$model1->attributes=$_POST['Emoloyee'];
$model2->attributes=$_POST['User'];
if ($model1->validate() && $model2->validate() ) {
$model1->save();
$model2->save();
} else {
$errors1 = $model1->errors;
$errors2 = $model2->errors;
var_dump($errors1);
var_dump($errors2);
exit();
}
then just for debug try using
$model1->attributes=$_POST['Emoloyee'];
$model2->attributes=$_POST['User'];
$model1->save(false);
$model2->save(false);
and check in db if the value are saved ..
You can try this example,
public function actionCreate()
{
$model = new Employee();
$user = new User();
if ($model->load(Yii::$app->request->post()) && $user->load(Yii::$app->request->post())) {
if($model->save() && $user->save()) {
Yii::$app->session->setFlash('success', 'Record saved successfully.');
} else {
//var_dump($model->getErrors());
//var_dump($user->getErrors());
Yii::$app->session->setFlash('error', 'Record not saved.');
}
return $this->redirect(['index']);
} else {
var_dump($model->getErrors());
var_dump($user->getErrors());
die();
}
return $this->render('create', [
'model' => $model,
'user' => $user,
]);
}
Follow the instruction given in below link . This should work
how to insert data to 2 tables i.e Employee and User(migrated) from single form(Employee Create) and controller in yii2

Yii2 kartik file FileInput Multiple

So I am working with Yii2 and am fairly new to it. I am using Kartik File upload and have attempted to convert the code for multiple files. but it only saves the first file.
I have removed the validation as this was also failing but will add back in once I know all else is working.
Model:
/**
* Process upload of image
*
* #return mixed the uploaded image instance
*/
public function uploadImage() {
// get the uploaded file instance. for multiple file uploads
// the following data will return an array (you may need to use
// getInstances method)
$image = UploadedFile::getInstances($this, 'image');
foreach ($image as $images) {
// if no image was uploaded abort the upload
if (empty($images)) {
return false;
}
// store the source file name
$this->image_src_filename = $images->name;
$extvar = (explode(".", $images->name));
$ext = end($extvar);
// generate a unique file name
$this->image_web_filename = Yii::$app->security->generateRandomString().".{$ext}";
// the uploaded image instance
return $images;
} }
Controller:
/**
* Creates a new PhotoPhotos model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new PhotoPhotos();
if ($model->load(Yii::$app->request->post())) {
// process uploaded image file instance
$images = $model->uploadImage();
if ($model->save(false)) {
// upload only if valid uploaded file instance found
if ($images !== false) {
$path = $model->getImageFile();
$images->saveAs($path);
}
return $this->redirect(['view', 'id' => $model->ID]);
} else {
//error in saving
}
}
return $this->render('create', [
'model' => $model,
]);
}
View:
//uncomment for multiple file upload
echo $form->field($model, 'image[]')->widget(FileInput::classname(), [
'options'=>['accept'=>'image/*', 'multiple'=>true],
]);
I see one problem which is that you reversed $images and $image in
foreach ($image as $images)
which should be
foreach ($images as $image)
Cheers

Yii2 Dynamic Form update Action is not working

I like to explain my problem clearly,
Am using wbraganca/yii2-dynamicform
Here create action is working perfectly, but in update action
In the code which i marked, i don't know what i need to do, i dont have such field (addresses) in customer table. am stuck on that.
suppose if i create a variable in model like public $addressess, it makes me the reload the table again, and that cause while update the same form, data's getting reload and form viewing as empty without empty,
if create a function on that name, i don't know what to write on that..
Am simply using code like this
public function getaddressess()
{
}
Create Action Code
public function actionCreate()
{
$modelCustomer = new Customer;
$modelsAddress = [new Address];
if ($modelCustomer->load(Yii::$app->request->post())) {
$modelsAddress = Model::createMultiple(Address::classname());
Model::loadMultiple($modelsAddress, Yii::$app->request->post());
// ajax validation
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ArrayHelper::merge(
ActiveForm::validateMultiple($modelsAddress),
ActiveForm::validate($modelCustomer)
);
}
// validate all models
$valid = $modelCustomer->validate();
$valid = Model::validateMultiple($modelsAddress) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $modelCustomer->save(false)) {
foreach ($modelsAddress as $modelAddress) {
$modelAddress->customer_id = $modelCustomer->id;
if (! ($flag = $modelAddress->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $modelCustomer->id]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
}
return $this->render('create', [
'modelCustomer' => $modelCustomer,
'modelsAddress' => (empty($modelsAddress)) ? [new Address] : $modelsAddress
]);
}
Help me to sort out this problem
$modelsAddress=$modelCustomer->addresses in that example mean array of related Address() instances
public function actionCreate()
{
$modelCustomer = new Customer;
$modelsAddress = $this->getaddressess($modelCustomer->id);
//...................
}
public function getaddressess($id)
{
$model = Address::find()->where(['id' => $id])->all();
return $model;
}
from
public function getaddressess($id)
{
$model = Address::find()->where(['id' => $id])->all();
return $model;
}
Shared above you will also need to add
on your Update view file :
'model' => $model,
'modelsAddress'=>$modelsAddress,
Hope this helps. It worked for me
It should be getAddresses() instead of getaddresses() (although both could work, I'd go with the first one to meet conventions). Or you could set a public $addresses if you don't need extra encapsulation.
suppose if i create a variable in model like public $addressess, it makes me the reload the table again, and that cause while update the same form, data's getting reload and form viewing as empty without empty,
I think you have a validation issue - no validator to mark the field as safe and you see it as empty after posting.
Add public $addresses to your Customer model.
Add "addresses" to your validation rules as safe (or more appropriate validator). This way after posting the form, it probably won't render empty.
This line code ---> $modelsAddress = $modelCustomer->addresses;
is get from model for customer at line ---> public function getAddresses()
this public function line code is code for get array related table from active record method on yii2.
$modelCustomer->addresses the word addresses should come from the $modelCustomer model you must have a relationship to the other table where you add the multiple values. In my example described in the video I have two tables po table and po_items table po_items table has foreign key of po_id. So when you make the Models using gii you will get a relationship in the model that is what you have to use instead of the addresses.
the relationship according my database should be - poItems you will see this at line 14
Add this to Customer Model
public function getAddresses(){
return $this->hasMany(Address::className(), ['id' => 'id']);
}
enter image description hereIn Po.php models:
public function getPoItems()
{
return $this->hasMany(PoItem::className(), ['po_id' => 'id']);
}
In PoController.php
public function actionUpdate($id)
{
$model = $this->findModel($id);
//$modelsPoItem = [new PoItem];
$modelsPoItem = $model->poItems;
if ($model->load(Yii::$app->request->post()) && $model->save())
{
$oldIDs = ArrayHelper::map($modelsPoItem, 'id', 'id');
$modelsPoItem = Model::createMultiple(PoItem::classname(), $modelsPoItem);
Model::loadMultiple($modelsPoItem, Yii::$app->request->post());
$deletedIDs = array_diff($oldIDs, array_filter(ArrayHelper::map($modelsPoItem, 'id', 'id')));
// validate all models
$valid = $model->validate();
$valid = Model::validateMultiple($modelsPoItem) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
if (! empty($deletedIDs))
{
PoItem::deleteAll(['id' => $deletedIDs]);
}
foreach ($modelsPoItem as $modelPoItem)
{
$modelPoItem->po_id = $model->id;
if (! ($flag = $modelPoItem->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $model->id]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
}
return $this->render('update', [
'model' => $model,
'modelsPoItem' => (empty($modelsPoItem)) ? [new PoItem] : $modelsPoItem
]);
}

Yii2 - insert relational data with junction table, many-many connection

I have a problem with Yii2 (Stable).
I have a Content(PK:id) table, I have a Tag(PK:id) table, and I have a junction table called Content_Tag (PK:content_id, tag_id). I'd like to use it for tagging, like WP tags.
All controllers and models are created with gii.
I have two problems:
If I create a new content, I'd like to save some new tags to the Tag table via the Content_Tag table. How can I do that? With link()?
What if there are tags (I know the ids) in the tag table, I'd like to connect only with the Content table via the junction table, without inserting into the Tag table. How can I do this?
I don't want to write native SQL command, I'd like to use the Yii2 built in functions like link() or via() or viaTable().
Thanks for your help!
I created a behavior to help handle do this, basically you do:
$content = Content::findOne(1);
$tags = [Tag::findOne(2), Tag::findOne(3)];
$content->linkAll('tags', $tags, [], true, true);
You can get the behavior here:
https://github.com/cornernote/yii2-linkall
If you'd prefer to do it without the behavior, something like this:
// get the content model
$content = Content::findOne(1);
// get the new tags
$newTags = [Tag::findOne(2), Tag::findOne(3)];
// get the IDs of the new tags
$newTagIds = ArrayHelper::map($newTags, 'id', 'id');
// get the old tags
$oldTags = $post->tags;
// get the IDs of the old tags
$oldTagIds = ArrayHelper::map($oldTags, 'id', 'id');
// remove old tags
foreach ($oldTags as $oldTag) {
if (!in_array($oldTag->id, $newTagIds)) {
$content->unlink('tags', $oldTag, true);
}
}
// add new tags
foreach ($newTags as $newTag) {
if (!in_array($newTag->id, $oldTagIds)) {
$content->link('tags', $newTag);
}
}
If you created models using gii then you might seen in the model the relationship is done like:
/**
* #return \yii\db\ActiveQuery
*/
public function getContent()
{
return $this->hasMany(Content_Tag::className(), ['content_id' => 'id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getContent()
{
return $this->hasMany(Tag::className(), ['tag_id' => 'tag_id'])->viaTable('content_tag', ['content_id' => 'id']);
}
If you want to save in Content_Tag table based on Content and Tag table then in controller you can use:
public function actionCreate()
{
$model = new Tag();
$content = new Content();
$content_tag = new Content_tag();
if($model->load(Yii::$app->request->post()) && $model->save()){
$model->save(false);
$content_tag->tag_id = $model->id;
$content_tag->content_id = $model->content_id;
$content_tag->save(false);
if($model->save(false))
{
Yii::$app->getSession()->setFlash('success', 'Created successfully');
return $this->render('create',[
'model' => $model,
'content' => $content,
'content_tag' => $content_tag
]);
}
}
else
{
return $this->render('create', [
'model' => $model,
]);
}
}
You can use link() to save. I am also searching for that as I didn't use that.