Search code examples
phpcakephpmodelcontrollercakephp-2.x

CakePHP Call to a member function disable() on a non-object


never use cakephp before and we have a project to edit for our client made in cakephp 2.5.

We tried to create a new functionality "Emplois" to add jobs inside the website. We mainly recreate what existed from an other models / controller already working inside the website but currently we get this error and we can't figure the problem.

Error: Call to a member function disable() on a non-object
File: /home/voyou/subdomains/labsurface/app/Controller/EmploisController.php
Line: 95

Here's the model : /app/Model/Emploi.php

<?php
App::uses('AppModel', 'Model');
/**
 * Emploi Model
 *
 */
class Emploi extends AppModel {

public $faIcone = "thumb-tack";
public $order = 'Emploi.ordre';


public $actsAs = array(
        'I18n' => array(
            'fields' => array('nom')
        ),
    );
/**
 * Display field
 *
 * @var string
 */
    public $displayField = 'nom_fre';
/**
 * Search field
 *
 * @var string
 */
    public $searchField = 'nom_fre';
}

And here's the controller : /app/Controller/EmploisController.php

<?php
App::uses('AppController', 'Controller');
/**
 * Emplois Controller
 *
 * @property Emploi $Emploi
 */
class EmploisController extends AppController {

    function beforeFilter() {
        parent::beforeFilter();
        $this->Auth->allow('get');
        
    }

/**
 * get method
 *
 * @return void
 */
    public function get($id = null) {
        if($id) {
            return $this->Emploi->findById($id);
        }
        else {
            return $this->Emploi->find('all');
        }
    }
    
    /**
 * get beforeRender method
 *
 * @return void
 */
    public function beforeRender()  {
        $this->set('faIcone', $this->Emploi->faIcone);
    }

/**
 * index method
 *
 * @return void
 */
    public function index() {
        $this->Emploi->recursive = 0;
        $this->set('Emplois', $this->paginate());
        parent::beforeRender();
    }

/**
 * voir method
 *
 * @param string $id
 * @return void
 */
    public function voir($id = null) {
        $this->Emploi->id = $id;
        if (!$this->Emploi->exists()) {
            throw new NotFoundException(__('Emploi invalide'));
        }
        $emploi = $this->Emploi->read(null, $id);
        $this->set('Emploi', $emploi);
        $this->set("title_for_layout", $emploi['Emploi']['seo_title']); 
        $this->set("description_for_layout", $emploi['Emploi']['seo_description']);
    }
    
    
/**
 * page_plugin method
 *
 * @return void
 */
    public function page_plugin($page_id = null) {
        $this->Emploi->recursive = 0;
        $this->set('Emplois', $this->Emploi->find('all', array('conditions'=> array('Emploi.page_id' => $page_id))));
    }
    
    
    
/**********************************
 * 
 *    Actions administratives
 * 
 **********************************/
    
/**
 * admin method
 *
 * @return void
 */
     public function admin($search = null) {
         
        //(debug($this));
        $this->layout = 'admin';
        $this->Emploi->Behaviors->disable('I18n');
        $this->Emploi->recursive = 0;
        
        $options['limit'] = 10000;
        if ($search) {
        $options['conditions'] = array('Emploi.'.$this->Emploi->searchField.' LIKE' => '%'.$search.'%');
        }
        $this->paginate = $options;

        $this->set('Emplois', $this->paginate());
        $this->set('searchField', $this->Emploi->searchField);
        
        if($this->RequestHandler->isAjax()) {
            $this->layout = 'ajax';
            $this->render('/Elements/tables/Emplois');
        }       
     }
/**
 * irre method
 *
 * @return void
 */ 
    public function irre($page_id = null){
        $this->set('page_id', $page_id);
        $this->set('Emplois', $this->Emploi->findAllByPageId($page_id));
            }

/**
 * ajouter method
 *
 * @return void
 */
    public function ajouter() {
        $this->layout = 'admin';
        $this->Emploi->Behaviors->disable('I18n');
        if ($this->request->is('post')) {
            $this->Emploi->create();
            if ($this->Emploi->save($this->request->data)) {
                $this->Session->setFlash(__('Le/la emploi a bien été ajouté'));
                $this->redirect(array('action' => 'admin'));
            } else {
                $this->Session->setFlash(__('Le/la emploi n\'a pas pu être ajouté. S\'il vous plaît, essayer de nouveau.'));
            }
        }
    $this->render('modifier');
    }

/**
 * modifier method
 *
 * @param string $id
 * @return void
 */
    public function modifier($id = null) {
        $this->layout = 'admin';
        $this->Emploi->Behaviors->disable('I18n');
        
        $this->Emploi->id = $id;
        if (!$this->Emploi->exists()) {
            throw new NotFoundException(__('emploi invalide'));
        }
        if ($this->request->is('post') || $this->request->is('put')) {
            if ($this->Emploi->save($this->request->data)) {
                $this->Session->setFlash(__('Le/la emploi a bien été sauvegardé'));
                $this->redirect(array('action' => 'admin'));
            } else {
                $this->Session->setFlash(__('Le/la emploi n\'a pas pu être sauvegardé. S\'il vous plaît, essayer de nouveau.'));
            }
        } else {
            $this->request->data = $this->Emploi->read(null, $id);
        }
    }

/**
 * supprimer method
 *
 * @param string $id
 * @return void
 */
    public function supprimer($id = null) {
        if (!$id) {
            throw new MethodNotAllowedException();
        }
        $this->Emploi->id = $id;
        if (!$this->Emploi->exists()) {
            throw new NotFoundException(__('Emploi invalide'));
        }
        if ($this->Emploi->delete()) {
            $this->Session->setFlash(__('Emploi supprimé'));
            $this->redirect(array('action' => 'admin'));
        }
        $this->Session->setFlash(__('Emploi n\'a pu être supprimé'));
        $this->redirect(array('action' => 'admin'));
    }
    
/**
 * ordre method
 */ 
    
    public function ordre() {
        $this->autoRender = false;
        $this->Emploi->Behaviors->disable('I18n');
        $this->Emploi->Behaviors->disable('Image');
        $error = 0;
        Configure::write('debug', 0);
        foreach($_POST['Emplois'] as $pos=>$id) {
            if($id) {
                $data['Emploi']['id'] = $id;
                $data['Emploi']['ordre'] = $pos;
                if (!$this->Emploi->save($data, array('fieldList'=>array('ordre')))) {
                    $error++;
                }
            }
        }
    }
}

The error point to the line $this->Emploi->Behaviors->disable('I18n'); inside the public function admin but from our understanding, $this->Emploi is null and we have no idea how to link the model to the controller.

Here the /app/Model/AppModel.php

<?php
/**
 * Application model for Cake.
 *
 * This file is application-wide model file. You can put all
 * application-wide model-related methods here.
 *
 * PHP 5
 *
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @package       app.Model
 * @since         CakePHP(tm) v 0.2.9
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */

App::uses('Model', 'Model');

/**
 * Application model for Cake.
 *
 * Add your application-wide methods in the class below, your models
 * will inherit them.
 *
 * @package       app.Model
 */
class AppModel extends Model {
    
    function getNextId(){

        $next_increment = 0;

        $table = Inflector::tableize($this->name);

        $query = "SHOW TABLE STATUS LIKE '$table'";

        $db =& ConnectionManager::getDataSource($this->useDbConfig);

        $result = $db->rawQuery($query);



       while ($row = $result->fetch(PDO::FETCH_ASSOC)) {

            $next_increment = $row['Auto_increment'];

        }

        return $next_increment;

    }  
    
}

Solution

  • As mentioned in the comments, the problem with your code is that it uses non US English names, which violates CakePHP's naming conventions, and breaks the magic around that which is using inflection for tasks like finding and loading the default model for a controller based on singularizing the controller name.

    Inflection mostly works on word endings as known from US English based words, it's not like the inflector knows about all possible words, it's just some basic grammar rules and a few exceptions, so things might work for words from other languages simply because their ending happens to match a rule. -ois as in your Emplois name matches the rule for uninflected words, it will catch words like bourgeois or Illinois. Regarding your example from the comments, Projets and Projects, there's no difference for the inflector, it will not match anything irregular, but just the the -s ending rule, and therefore being interpreted as plural, so it happens to just work by chance, so to speak.

    Ideally you use proper English names everywhere. If you cannot work that out right now, then the next best thing would be to either use custom inflections, or depending on the situation where inflection is failing, interfer manually, like using loadModel() manually. An example for custom inflection for Emploi/Emplois would be:

    // in `app/Config/bootstap.php`
    
    Inflector::rules('singular', array(
        'irregular' => array(
            'emplois' => 'emploi',
        ),
    ));
    

    See also