How to pass parameters with testAction in CakePHP2.0 - cakephp

I want to test a function with this header:
public function includeNumComments($posts){
Where $post is an array of data.
I wonder how can i test the method passing it an array of posts.
I have tried things like this, but it doesn't work:
$result = $this->testAction("/comments/includeNumComments/", array('data' => $posts));
$result = $this->testAction("/comments/includeNumComments/", array($posts));
Thanks

Here's the correct case, it worked for me. Hope it helps:
public function testAddUser() {
$data = array(
'User' => array(
'id' => 12,
'username' => 'testname1',
'password' => 'Pass#123!',
'email' => 'test#example.com'
)
);
$result = $this->testAction(
'/users/add',
array('data' => $data, 'method' => 'post')
);
debug($result);
}

That's not really using testAction then, because you can't pass an array via HTTP. There'd be no way to do this via a form or link on a website.
You can just test it as a normal function:
$result = $this->CommentsController->includeNumComments($posts);

Related

How do I set up an adapter in zend framework 2?

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

redirection on custom submit handler

so basically this is my 2nd day in this problem.
i have my module send_xml.module
function send_xml_form_user_register_form_alter(&$form, &$form_state) {
$form['#submit'][] = 'send_xml_submit_function';
}
function send_xml_submit_function($form, &$form_state){
$email = $form_state['values']['mail'];
$password = $form_state['values']['pass'];
$form_state['redirect'] = array(
'mylink', array(
'query' => array(
'email' => $email,
'password' => $password,
),
),
);
but it does not redirect after the process in mylink, it just refreshes the page.
Use hook_form_alter like this:
function send_xml_form_alter(&$form, &$form_state, $form_id) {
switch ($form_id) {
case 'user_register_form':
$form['#submit'] = array('send_xml_submit_function');
break;
default:
# code...
break;
}
}
function send_xml_submit_function($form, &$form_state){
// call default submit -- this is default submit action for register form
user_register_submit($form, $form_state);
// if you use profile2 to create fields in register form then call this function too
profile2_form_submit_handler($form, $form_state);
$email = $form_state['values']['mail'];
$password = $form_state['values']['pass'];
$form_state['redirect'] = array(
'mylink', array(
'query' => array(
'email' => $email,
'password' => $password,
),
),
);
}
I had same problem weeks ago and this is way I solved it, actually I have no clear idea why this work and why appending #submit don't work.
I checked drupal user_register_submit code and seems like it clear $form_state['redirect'] to redirect user to <front>.
You can also use drupal_goto function:
function send_xml_submit_function($form, &$form_state){
$email = $form_state['values']['mail'];
$password = $form_state['values']['pass'];
drupal_goto('REDIRECT_pATH', array('query' => array('email' => $email, 'password' => $password)));
}

Download function not working CakePHP

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.

Cakephp paginator array error

I'm new to CakePHP and have a question about this controller:
function showmy($userid) {
return $this->Voucher->find('all', array('conditions' => array('Voucher.user_id' => $userid)));
}
public function index() {
$this->Voucher->recursive = 0;
$userid = $this->Session->read('Auth.User.id');
$this->set('vouchers', $this->showmy($userid ));
}
I want all the Voucher with user_id by the loged in user.
It works, but i get many errors like :
Warning (2): array_filter() expects parameter 1 to be array, null given [CORE\Cake\View\Helper\PaginatorHelper.php, line 419]
Maybe someone with more experienced could give me some advice!
Thanks,
Julius
I think you need to use PaginatorComponent::paginate() to be able to use the PaginatorHelper in your view. More info in the manual.
You must declare $paginate array in you controller for the pagination
public $paginate = array(
'limit' => 25,
'order' => array(
'Post.title' => 'asc'
)
);
paginate => array
public function index() {
$this->Voucher->recursive = 0;
$userid = $this->Session->read('Auth.User.id');
$this->Paginator->settings = array(
array('conditions' => array('Voucher.user_id' => $userid))
);
$this->set('vouchers', $this->Paginator->paginate('Voucher'));
}

CakePHP Pagination. Keeping Model Fat

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.

Resources