All I want to do is change a value ('path') in the $actsAs array of my Upload model from the controller prior to a save.
The only way I've come up with that works is to unload the behavior and then load it with all of it's settings.
This seems like overkill to just change the path. Is there an easier/better way?
$this->loadModel('Upload');
$this->Upload->Behaviors->unload('Upload.Upload');
$this->Upload->Behaviors->load('Upload.Upload', array(
'photo' => array(
'thumbnailSizes' => array(
'xvga' => '1024x768',
'vga' => '640x480',
'thumb' => '80x80',
),
'thumbnailMethod' => 'php',
'thumbnailQuality' => '80',
'pathMethod'=>'random',
'path' => '{ROOT}webroot{DS}uploads{DS}test{DS}{field}{DS}',
'maxSize' => '5242880', //5MB
'mimetypes' => array('image/jpeg', 'image/png', 'image/gif', 'image/bmp'),
'extensions' => array('jpg', 'gif', 'png', 'bmp'),
),
));
if($this->Upload->save($this->request->data)) {
//...
From looking at the source I think the uploadSettings() method is what you're looking for:
$this->Upload->uploadSettings('photo', 'path', 'YOUR_PATH');
The BehaviorCollection should merge the configuration when you load it over an existing behavior, so you shouldn't need to re-include all the other configuration. In fact, you shouldn't need to unload it either.
$this->Upload->Behaviors->load('Upload.Upload', array(
'photo' => array(
'path' => '{ROOT}webroot{DS}uploads{DS}test{DS}{field}{DS}'
)
));
Since the merging uses array_merge instead of array_merge_recursive this will not work for you. I included it here because it's probably the preferred method, though the behavior you're using uses a configuration array that Cake won't handle the way you want it to.
Alternatively, you can simply modify the $actsAs variable when the model is constructed, which will cause it to set up correctly.
public function __construct($id = false, $table = null, $ds = null) {
// 2 lines for readability
$this->actsAs['Upload.Upload']['photo']['path'] =
'{ROOT}webroot{DS}uploads{DS}test{DS}{field}{DS}';
return parent::__construct($id, $table, $ds);
}
Related
Actually in my scenario I am binding relations in model's constructor function. Actually I need to use a model attribute in my model relationship and Cakephp preventing using model attribute in default relationships. So I can't use
public $hasMany = array(
'ProductDetail' => array(
'className' => 'ProductDetail',
'conditions' => array(
'ProductDetail.language_id' => $this->languageId //Throws error
),
'dependent' => true
),
);
So I made a trick. I did bind model relations on model's __construct() function. Below is my code
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->bindModel(array(
"hasMany" => array(
'ProductDetail' => array(
'className' => 'ProductDetail',
'dependent' => true,
'conditions' => array(
'ProductDetail.language_id' => $this->languageId //Doesn't throw an error
)
)
)
)
);
}
This trick works for me in each scenario. But when I delete a product, dependent model can't be deleted when I am binding relations under __construct() function. Is there any way to make this trick works or I need to trigger dependent functionality manually ?
After doing research I found that pass second parameter to false on bindModel function. Because this will make your on-the-fly binding last the duration of the request. So in that case Model::bindModel function looks like
$this->bindModel(array(
"hasMany" => array(
'ProductDetail' => array(
'className' => 'ProductDetail',
'dependent' => true,
'conditions' => array(
'ProductDetail.language_id' => $this->languageId
)
)
)
), false
);
this is the content of the autoload/global.php file :
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=web_builder;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
this is the content of the autoload/local.php file:
return array(
'db' => array(
'username' => 'DB_User_Name',
'password' => 'DB_Password',
,
); )
this is part of the content of module/Module.php :
namespace Application;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\Db\Adapter\Adapter;
.........
public function getServiceConfig() {
return array(
'factories' => array(
'Application\Controller\UserController' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new Model\StickyNotesTable($dbAdapter);
return $table;
},
),
);
}
Here I really don't understand what this function do, I just copy pasted from an example. If you could explain me what does getServiceConfig function do, I will really appreaciate it.
Finally the controller content:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Db\Adapter\Adapter;
use Zend\Db\TableGateway\AbstractTableGateway;
use Zend\Db\Sql\Select;
class UserController extends AbstractActionController{
public function __construct(Adapter $adapter) {
$this->adapter = $adapter;
}
public function loginAction(){
// here i just want to a simple select and yes I know queries will be executed
//in Model, but I want to here a simple query.
//For example in Codeigniter I can't do in model, controller, or view as well.
return new ViewModel();
}
The result of all this code is obviously an error:
Catchable fatal error: Argument 1 passed to Application\Controller\UserController::__construct() must be an instance of Zend\Db\Adapter\Adapter, none given, called in C:\xampp\htdocs\zf2\vendor\zendframework\zendframework\library\Zend\ServiceManager\AbstractPluginManager.php on line 170 and defined in C:\xampp\htdocs\zf2\module\Application\src\Application\Controller\UserController.php on line 21
Can someone post an answer to make this database or query stuff work ? thx
i have a problem to do this :
public $hasOne = array(
'Friend' => array(
'className' => 'Friend',
'conditions' => array('Friend.friend_id' => $this->Auth->user('id))
)
);
and i have an error :
Fatal Error
Error: syntax error, unexpected T_VARIABLE
File: /Users/guillaumebaduel/Sites/app/Model/User.php
Line: 98
What is the problem?
How can i get ID in a model?
Thanks
in the constructor:
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->hasOne = array(
'Friend' => array(
'className' => 'Friend',
'conditions' => array('Friend.friend_id' => AuthComponent::user('id))
)
);
}
Note that you need to use the model constructor here (basic OOP) and that you cannot just use a non-declared object dynamically. Only statically, and only because the user method allows you to do so.
Even though it would be cleaner to attach such non-stateless bindings at runtime instead of doing it even for non-logged-in users and others who dont need that.
I have question in cakephp model,
I want to add dynamic condition in var $hasMany keyword
I want to add condition like current user_id, i got user Id after my login.
var $hasMany = array(
"AskComment"=>array('limit'=>3),
'AskStatistic',
'AskContactsLink',
'AskStatistic',
'AskObject',
'AskLikes'
);
If you want to add dynamic condition in your model, then you might have to bind the model association-ship dynamically into your controller's code. Write the following code into your controller's method for which you want to impose some new condition on the existing/new associated models.
$this->PrimaryModel->bindModel(array('hasMany' => array(
'AskComment' => array(
'className' => 'AskComment',
'foreignKey' => 'primary_id',
'conditions' => array('AskComment.user_id' => $user_id)
)
)
));
Take a look at this link: Creating and destroying associations on the fly. This will surely help you to achieve the same.
I think its better to put your association in the construct function of your Model.
like this:
/**
* #see Model::__construct
*/
public function __construct($id = false, $table = null, $ds = null) {
public $hasMany = array(
'AskComment' => array(
'className' => 'AskComment',
'foreignKey' => 'primary_id',
'conditions' => array(
'AskComment.user_id' => $user_id,
),
),
);
}
I am currently trying to use Miles J plugin located here http://milesj.me/code/cakephp/uploader Although I have made great progress learning CakePhp, I am currently having a problem using the plugin and I would appreciate any help provided.
I have followed all the necessary steps to use the plugin. It has been downloaded put on Plugin folder, I bootstrapped with CakePlugin::loadAll().
So far so good.
Next I have proceed to set up the table as indicated by the plugin developer.
Ok, now back to my own code. I have the following set up:
images_controller.php , image.php and their views.
My goal now is to use the plugin inside those files as such:
App::import('Vendor', 'Uploader.Uploader');
Class ImagesController extends AppController {
var $components = array('Auth');
var $helpers = array('Design');
var $uses = array('Image', 'Uploader.Upload');
function manage(){
//here I show a simple upload form that uses the action saveimage
}
function saveimage(){
$this->Uploader = new Uploader();
if(!empty($this->data)){
$this->Upload->save($this->data);
}
}
}
Now, my model is set as follows
Class Image extends AppModel {
public $useTable = 'uploads';
public $actsAs = array(
'Uploader.FileValidation' => array(
'file' => array(
'extension' => array(
'value' => array('gif', 'jpg', 'jpeg'),
'error' => 'Only gif, jpg and jpeg images are allowed!'
),
'minWidth' => 500,
'minHeight' => 500,
'required' => true
),
'import' => array(
'required' => false
)
),
'Uploader.Attachment' => array(
'file' => array(
'name' => 'uploaderFilename',
'uploadDir' => '/files/uploads/',
'dbColumn' => 'path',
'maxNameLength' => 30,
'overwrite' => true,
'stopSave' => false,
'transforms' => array(
// Save additional images in the databases after transforming
array(
'method' => 'resize',
'width' => 100,
'height' => 100,
'dbColumn' => 'path_alt'
)
),
'metaColumns' => array(
'size' => 'filesize', // The size value will be saved to the filesize column
'type' => 'type' // And the same for the mimetype
)
),
'import' => array(
'uploadDir' => '/files/uploads/',
'name' => 'uploaderFilename',
'dbColumn' => 'path',
'overwrite' => true,
'stopSave' => false,
'transforms' => array(
array(
'method' => 'scale',
'percent' => .5,
'dbColumn' => 'path' // Overwrite the original image
)
)
)
)
);
}
}
On my model for testing purposes I have not changed anything but just copied and pasted the very same array as shown in the the Test/Model folder inside the plugin, which is meant to show the functionality of the plugin.
The following confusion, errors or lack of understanding is taking place:
My file is not being uploaded to the webroot/files/uploads folder
My data is being inserted in the database, but not in a complete manner by leaving empty as shown:
id | caption | path | path_alt | created |
4 | | | |2012:02:..|
Above, I expect the path to be saved, but it doesn't.
I have to admit my confusion comes mainly from my inexperience using plugins, so I am aware I might be doing something wrong regarding my models or my configuration.
Any prompt help would be appreciated greatly as I have tried to work this out on my own without any success.
A few things:
1 - In your controller you do not need to import the Uploader class. You also don't need to use the Uploader.Upload model (it's merely an example test case). All you need to do in the controller is call $this->Image->save() which will upload the file and save the path as a row into the database (if you defined the Attachment in Image).
2 - In your view, create the file input. Pay attention to the input name.
echo $this->Form->input('FILE_INPUT_NAME', array('type' => 'file'));
3 - In your Image model, setup the AttachmentBehavior and its options for that specific input field:
'Uploader.Attachment' => array(
'FILE_INPUT_NAME' => array(
'uploadDir' => '/files/uploads/',
'dbColumn' => 'path'
),
'ANOTHER_INPUT' => array()
);
Be sure that the column "path" exists in your images table. And thats it.
For more information on what each option does, check out the following: http://milesj.me/code/cakephp/uploader#uploading-files-through-the-model