Passing result array to controller in codeigniter - arrays

I am developing a simple profile page but I am having a little dificulty passing the result array to the controller..am not sure if this how to do it.
Model:
class Login_model extends CI_Model{
function get_profile()
{
$this->db->where('email', $this->input->post('email'));
$query = $this->db->get('user');
if($query->num_rows == 1)
{
return $query->result_array();
}
}
}
Controller:
class Login extends CI_Controller {
function show_profile{
$this->load->model('login_model');
$q['user'] = $this->login_model->get_profile();
echo $q['user'];
}
}
I tried to echo out $q['user'] as a tests to see if it will work, but it did not work.

in this context a result array would be if you were getting back more then one result. since you are only getting back one result you can do row_array() so like
if($query->num_rows == 1)
{
return $query->row_array();
}
else
{
return false;
}
NEVER do this
// example of what NOT to do
$this->db->where('email', $this->input->post('email'));// NO NO NO
validate the email first using codeigniter form validation and then send it like
// if no user comes back then deal with it right away
if( ! $user = $this->login_model->get_profile($email) )
{
$this->showNoUserFor($email) ;
}
else
{ // carry on....
otherwise - do the tutorial first in the codeigniter manual, it will save you a lot of time.

you cannot echo $q['user'] because it is an array. Use
`print_r($q['user']); exit;
and you can pass this to your view page by
`$this->load->view('yourViewPage',$q);

Related

cant add paramater when caling view with search function in cakephp

In cakephp I have a search function which uses parameters and call backs. My issue is that I want to call this function with a parameter but the function cant accept parameters when called.
//I cant call this function with a paramater
$this->redirect(array('action' => 'email_list',$id,));
....
public function email_list($search = 0) {
$this->set( 'search',$search);
;
if (($this->request->is('post') || $this->request->is('put'))) {
if (isset($this->request->data['searchFilter'])) {
$filter_url['controller'] = $this->request->params['controller'];
$filter_url['action'] = $this->request->params['action'];
$filter_url['page'] = 1;
// for each filter we will add a GET parameter for the generated url
foreach($this->data['User'] as $name => $value){
if($value){
$filter_url[$name] = urlencode($value);
}
}
//Post params are now GET paramaters
return $this->redirect($filter_url);
}//isset
worked out a solution using a session variable that gets destroyed on entry. It is quick and easy. Having to redo a search function in cakephp ver 2 is not something i want to do. I am updating to cakephp ver 3
public function email_list($search = 0) {
if ($this->Session->check('sessrowid'))
{
$searchRowId=$this->Session->read('sessrowid');
$this->Session->delete('sessrowid');
}

CakePHP unit test code coverage $this->request->data clause not executed

I am completely new to PHP unit testing (using PHPUnit) and CakePHP(2) as a framework, and I'm coming back to PHP after 5 years away.
I've got a website up and running and am writing unit tests as I go along as best practice. However, xdebug is showing that one of my clauses is not covered when I believe I am calling it and I just can't see why. I've googled the hell out of all search terms I can think of and re-read the relevant sections of the cookbook and (while I've learned a lot of other useful things) I didn't find an answer so am hoping that a simple answer is forthcoming from someone in the know :)
Here are the relevant sections of code:
Controller:
<?php
App::uses('AppController', 'Controller');
// app/Controller/ClientsController.php
class ClientsController extends AppController {
/* other functions */
public function edit($id = null) {
if (!$id) {
$this->Session->setFlash(__('Unable to find client to edit'));
return $this->redirect(array('action'=>'index'));
}
$client = $this->Client->findById($id);
if(!$client) {
$this->Session->setFlash(__('Unable to find client to edit'));
return $this->redirect(array('action'=>'index'));
}
if ($this->request->is('post')) {
$this->Client->id = $id;
if ($this->Client->saveAll($this->request->data)) {
$this->Session->setFlash(__('Client has been updated.'));
return $this->redirect(array('action'=>'index'));
} else {
$this->Session->setFlash(__('Unable to update client'));
}
}
if (!$this->request->data) {
$this->request->data = $client;
$this->Session->setFlash(__('Loading data'));
}
}
}
Test:
<?php
// Test cases for client controller module
class ClientsControllerTest extends ControllerTestCase {
public $fixtures = array('app.client');
/* other tests */
public function testEdit() {
// Expect success (render)
$result = $this->testAction('/Clients/edit/1');
debug($result);
}
}
?>
The code executes as expected. If I browse to "/Clients/edit/1", the flash message (Loading data) I expect is displayed indicating that there was no request data, so it's loaded from the $client. The correct data displays in the edit form.
When I call from within my test, I get a success message that the test has passed but xdebug code coverage is showing the if (!$this->request->data) { .. } clause is not covered, and no errors are apparent.
This seems counter-intuitive to me, so in a hope to avoid frustration with future (more complex) unit tests - can anyone explain why the test would pass but not execute this clause when it is called during normal access of the page?
(The fixture is correct both in terms of data structure and inserting the data before I'm attempting to edit it. Calling edit() from a test case with no id or an invalid id correctly executes the relevant clauses, as does passing data that does not pass validation.)
I've got a similar problem and I solved by adding the second parameter to testAction():
$this->testAction('/Clients/edit/1', array('method' => 'get'));
Also you may want to change your
if ($this->request->is('post') {
...
}
if (!$this->request->data) {
...
}
To:
if ($this->request->is('post') {
...
} else {
...
}
Hope it helps.

Accessing Arguments using $_GET

I am adding an email validation step to my user registration. I cannot seem to get access to the arguments that are being passed in the emailed link;
link: activation.php?email=someone#somewhere.com&key=5614c46be05a95f55f2231d8dea41418d17b197a
Here is the page code;
class page_activation extends Page {
function init(){
parent::init();
if($this->api->auth->isLoggedIn())$this->api->redirect('index');
$loginAccount = $_GET['email'];
$activationKey = $_GET['key'];
$this->add('H1')->set('Activated');
$this->add('H3')->set('Account: '.$loginAccount);
$this->add('H3')->set('Key: '.$_GET['key']);
}
var_dump($_GET);
check network tab in inspector to make sure get params are actually passed.
check mod rewrite rules
I have found a solution in case it might help someone. It seems you can access the $_SERVER vars but the $_GET vars are lost by the time you get to the page. Here is some code that I used to accesses the passed vars from the email link;
class page_activation extends Page {
function init(){
parent::init();
if($this->api->auth->isLoggedIn())$this->api->redirect('index');
$data = parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY);
$queryParts = split('[;&]', $data);
$params = array();
foreach ($queryParts as $param) {
$item = explode('=', $param);
$params[$item[0]] = $item[1];
}
$loginAccount = $params['email'];
$activationKey = $params['key'];
$this->add('H1')->set('Activated');
$this->add('H3')->set('Account: '.$loginAccount);
$this->add('H3')->set('Key: '.$activationKey);
}
}

Cakephp 2.0 change password

I am attempting to create a change password form in cakephp 2.0. I found a behavior that EuroMark created for 1.3 and now am having a tough time converting this code to work with 2.0. I know that it has something to do with the Auth Component as there were major changes to this component in 2.0.
public function validateCurrentPwd(Model $Model, $data) {
if (is_array($data)) {
$pwd = array_shift($data);
} else {
$pwd = $data;
}
$uid = null;
if ($Model->id) {
$uid = $Model->id;
} elseif (!empty($Model->data[$Model->alias]['id'])) {
$uid = $Model->data[$Model->alias]['id'];
} else {
return false;
}
if (class_exists('AuthExtComponent')) {
$this->Auth = new AuthExtComponent();
} elseif (class_exists($this->settings[$Model->alias]['auth'].'Component')) {
$auth = $this->settings[$Model->alias]['auth'].'Component';
$this->Auth = new $auth();
} else {
return true;
}
return $this->Auth->verifyUser($uid, $pwd);
}
I am getting an error on the line that reads $this->Auth = new $auth();
The error is as follows:
Argument 1 passed to Component::__construct() must be an instance of ComponentCollection, none given, called in C:\UniServer\www\new_company_test\app\Model\Behavior\change_password.php on line 117 and defined [CORE\Cake\Controller\Component.php, line 77]
and
Undefined variable: collection [CORE\Cake\Controller\Component.php, line 78]
it's also throwing this
Call to undefined method AuthComponent::verifyUser() in C:\UniServer\www\new_company_test\app\Model\Behavior\change_password.php on line 121
I am not sure if there is anything else that needs to be addressed in the script, I'm guessing not as there is no other place where Auth is used.
Any suggestions on what I need to do to get this to work? Any help is appreciated.
Thanks
you did discover that there is also a 2.0 branch, didnt you? :)
it should contain the same behavior:
https://github.com/dereuromark/tools/tree/2.0
either way, you need to pass a component collection into it:
$this->Auth = new AuthExtComponent(new ComponentCollection());
You should create a method verifyUser in your custom AuthExt Component which extends Auth Component for "current password" to work like so:
/**
* Quickfix
* TODO: improve - maybe use Authenticate
* #return bool $success
*/
public function verifyUser($id, $pwd) {
$options = array(
'conditions' => array('id'=>$id, 'password'=>$this->password($pwd)),
);
return $this->getModel()->find('first', $options);
$this->constructAuthenticate();
$this->request->data['User']['password'] = $pwd;
return $this->identify($this->request, $this->response);
}
/**
* returns the current User model
* #return object $User
*/
public function getModel() {
return ClassRegistry::init(CLASS_USER);
}
Maybe it is also possible to use the existing identify method in combination with a fake request object in the behavior directly?
I am thinking about using
$this->authenticate = array('Form'=>array('fields'=>array('username' => 'id')));
feel free to fork the behavior and submit a pull request.
"current password" is the only thing that is not yet cleanly solved right now.

Use of requestAction in the ctp file and it turned out a blank page instead

I am using cakePHP 1.26.
The web page turned out blank when I tried to use requestAction to access a function in a COntroller from a .ctp.
Here is the code:
<?php
class TestingController extends AppController {
function hello($id=null){
$IfLoggedIn=$this->Session->check('user');
if($IfLoggedIn){
//search the database
//$result=doing something from the search results
$this->set('userInfo',$result);
return "2";
}
else if(!$IfLoggedIn && $id!=null){
return "1";
}
else if($id==null){
return "0";
}
}
}
and then in default.ctp file, I made use of the function defined above:
<?php
$u = $this->requestAction('/hello');
if($u=="2"){
echo "welcome back, my friend";
}
else{
echo "Hello World";
}
?>
But when I load a web page, it was blank page.
I have no idea what's wrong in the code.
Try to add
$u = $this->requestAction('/hello', array('return'=>true));
Check this
You might try including the controller in the url param of requestAction.
If you spend more time debugging and reading the manual, you'll learn more, more quickly.
I'm new to Cakephp myself, I'm using 2.0 which may be different in your version of Cake.
I found that the following code from the manual was wrong for me:
<?php
class PostsController extends AppController {
// ...
function index() {
$posts = $this->paginate();
if ($this->request->is('requested')) {
return $posts;
} else {
$this->set('posts', $posts);
}
}
}
You need a slight modification (seems the manual was wrong in this case). The following code worked for me:
<?php
class PostsController extends AppController {
// ...
function index() {
$posts = $this->paginate();
if ( !empty($this->request->params['requested']) ) { // line here is different
return $posts;
} else {
$this->set('posts', $posts);
}
}
}
We shouldn't be checking for the request HTTP verb, we should be checking if the request parameter is true.
Here's another relevant link to the manual about request parameters: http://book.cakephp.org/2.0/en/controllers/request-response.html#accessing-request-parameters
Hope that helps.

Resources