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
Related
I read the documentation regarding file downloads, however I can't seem to get this to work.
I have read through questions here as well, and have had no luck.
My function looks as follows:
public function generate($id) {
$this->layout = 'ajax';
$this->Magazine->recursive = 2;
$DistributionLists = $this->Magazine->DistributionList->find('all',
array(
'conditions' => array(
'Magazine.id' => $id
),
'order' => array(
'DistributionList.priority ASC'
)
)
);
$this->set('magazine',$DistributionLists[0]['Magazine']['magazine_name']);
$this->set(compact('DistributionLists'));
}
public function download() {
$this->viewClass = 'Media';
$params = array(
'id' => "Magazine Distribution List.doc",
'name' => "Magazine Distribution List",
'download' => true,
'extension' => 'doc',
'path' => APP . "tmp" . DS
);
$this->set($params);
unlink(APP."tmp".DS);
$this->redirect(array('action'=>'index'));
}
public function afterFilter() {
parent::afterFilter();
if($this->action == 'generate') {
$this->redirect(array('action'=>'download'));
}
}
The reason I have an afterFilter function is because the word document that needs to be downloaded is created in the view file.
Does anyone know why this doesn't work?
You have to remove the call to the redirect method in your download method because it prevents your view from getting "rendered" due to the redirect.
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.
Consider this code:
Controller Code
<?php
App::uses('AppController', 'Controller');
class UsersController extends AppController {
public $components = array(
'Security',
'Session'
);
public function example() {
if ($this->request->is('post')) {
$this->set('some_var', true);
}
}
}
View Code
<?php
echo $this->Form->create();
echo $this->Form->input('name');
echo $this->Form->end('Submit');
Since I have the Security component in place, tampering with the form in any way (such as adding a field to it) will cause the request to be black-holed. I'd like to test this:
Test Code
<?php
class UsersControllerTest extends ControllerTestCase {
public function testExamplePostValidData() {
$this->Controller = $this->generate('Users', array(
'components' => array(
'Security'
)
));
$data = array(
'User' => array(
'name' => 'John Doe'
)
);
$this->testAction('/users/example', array('data' => $data, 'method' => 'post'));
$this->assertTrue($this->vars['some_var']);
}
public function testExamplePostInvalidData() {
$this->Controller = $this->generate('Users', array(
'components' => array(
'Security'
)
));
$data = array(
'User' => array(
'name' => 'John Doe',
'some_field' => 'The existence of this should cause the request to be black-holed.'
)
);
$this->testAction('/users/example', array('data' => $data, 'method' => 'post'));
$this->assertTrue($this->vars['some_var']);
}
}
The second test testExamplePostInvalidData should fail because of some_field being in the $data array, but it passes! What am I doing wrong?
By adding the 'some_field' in the data of ->testAction, the security component will assume that field is part of your app (since it's coming from your code, not a POST array) so it won't be seen as a "hack attempt".
Checking for blackholes is a little more convoluted. But Cake core tests already test the blackhole functionality, so if those tests pass, you don't need to check it in your app.
If you insist though, check out the core Cake tests for guidance:
Specifically:
/**
* test that validatePost fails if any of its required fields are missing.
*
* #return void
*/
public function testValidatePostFormHacking() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->params['_Token']['key'];
$unlocked = '';
$this->Controller->request->data = array(
'Model' => array('username' => 'nate', 'password' => 'foo', 'valid' => '0'),
'_Token' => compact('key', 'unlocked')
);
$result = $this->Controller->Security->validatePost($this->Controller);
$this->assertFalse($result, 'validatePost passed when fields were missing. %s');
}
Lots more examples in the file:
https://github.com/cakephp/cakephp/blob/master/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php
I currently have this in my Model (Referer Model):
public function getReferers($type = 'today') {
if ($type == 'this_month') {
return $this->_getThisMonthsReferers();
} elseif ($type == 'today') {
return $this->_getTodaysPageReferers();
}
}
private function _getThisMonthsReferers() {
$today = new DateTime();
return $this->Visitor->find('all', array(
'fields' => array(
'Referer.url',
'COUNT(UserRequest.visitor_id) as request_count',
'COUNT(DISTINCT(Visitor.id)) as visitor_count',
'COUNT(UserRequest.visitor_id) / COUNT(DISTINCT(Visitor.id)) as pages_per_visit',
'COUNT(DISTINCT(Visitor.id)) / COUNT(UserRequest.visitor_id) * 100 as percent_new_visit'
),
'joins' => array(
array(
'table' => 'user_requests',
'alias' => 'UserRequest',
'type' => 'RIGHT',
'conditions' => array(
'UserRequest.visitor_id = Visitor.id'
)
)
),
'conditions' => array(
'Visitor.site_id' => $this->Site->id,
'MONTH(UserRequest.created)' => $today->format('m'),
'YEAR(UserRequest.created)' => $today->format('Y')
),
'group' => array(
'url'
)
));
}
The thing is that I how I would paginate this. It will be so easy if just copy my code out of the model and to the controller. The thing is I want the keep the query in my Model.
How is this supposed to be done in CakePHP?
A custom find type is one method. You can find more information here: http://book.cakephp.org/2.0/en/core-libraries/components/pagination.html#custom-query-pagination
To turn your _getThisMonthsReferers into a custom find, follow this http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#creating-custom-find-types
For example:
// model
protected function _findThisMonthsReferers($state, $query, $results = array()) {
if ($state === 'before') {
$query['fields'] = ....
$query['joins'] = ....
return $query;
}
return $results;
}
// controller
public $paginate = array('findType' => 'thisMonthsReferers')
EDIT:
I think it should be :
public $paginate = array('thisMonthsReferers');
However the Solution I used derived from this answer is adding this to the method I am using
$this->paginate = array('thisMonthsReferers');
Since I don't want i used in all my actions. Then paginating the Model like this.
$this->paginate('Visitor);
Instead of returning the results of the find, just return it's array of options:
return array(
'fields' => array(
//...etc
Then use those options to paginate in the controller. More details on this answer of this similar question: Paginate from within a model in CakePHP
It still keeps the model fat (with any logic that might alter the conditions, joins, fields...etc), and the controller skinny, which just uses the returned array as paginate options.
I have the following model
class Comment extends AppModel {
var $useTable = "comments";
var $recursive = 1;
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'userID'
)
);
function bindCommentsToUser() {
$this->bindModel(
array('belongsTo' => array(
'User' => array(
'className' => 'User',
'foreignKey' => 'userID'
)
)
)
);
}
The belongsTo variable at the top does absolutely nothing, I just cannot get it to work.
To confirm that the binding exists, I created the lower function to do dynamic binding which works perfectly. There appears to be no difference between the two. Is there some mistake that I am making or is there some setting somewhere else that has to be set?
There should be the same in both cases. You may want to create a ticket at http://cakephp.lighthouseapp.com. If possible change 'userID' to 'user_id' as recommended Travis Lleu. That will work for sure.