Search code examples
phpdrupaldrupal-7

Cannot load custom content type nodes with load_node_multiple or load_node


I have a custom content type called "program" that I am trying to load via a drupal module.

The .module file includes a class called Program that has a method called
getAllPrograms() using include_once(drupal_get_path('module', 'progs') . '/progs.php');

When i try and load nodes using either node_load() or node_load_multiple() i get one of two different errors randomly.

either:

Fatal error: Fatal error: Call to undefined function user_access() in /mypath/modules/filter/filter.module on line 1035

or

Error: Call to undefined function token_get_entity_mapping() in /mypath//sites/all/modules/contrib/token/token.tokens.inc, line 767

Note: 99% of times it is the first error, and occasionally i would recieve the token_get_entity error.

The strange thing is, while i have been trying different things to resolve the error I have been able to get both of these functions to work for a period but as soon as i clear the Drupal Cache i get the error again.

What I have tried

  • Disabling and enabling the user module via the database.
  • Checking the paths and status are correct for the main modules (system, user, block etc)
  • using db_select to get a list of node ids and then use node_load() (with a loop) and node_load_multiple() to load the nodes. This is one of the things that started working for a short time until i cleared the cache.
  • Tested to see if i can call user_access() from my .module file. This does not work and returns the same call to undefined function error.

Here is the code that I have (not progs an anonymized name)

progs.module

include_once(drupal_get_path('module', 'progs') . '/progs.php');

progs.php

if( !class_exists('progs') ):

    class progs 
    {
        //a bunch of properties

        function __construct()
        {
            // load partial includes and objects
            $this->load_partial_inclues();

            //retrieve all programs that are open
            $this->open_programs = Program::getAllOpenPrograms();
        }

        function load_partial_inclues()
        {
            //includes
            include_once(drupal_get_path('module', 'progs') . '/core/objects/program.php');
        }

    }

function progs()
{
    global $progs;

    if( !isset($progs) )
    {
        $progs = new progs();
    }

    return $progs;

}

// initialize
progs();

endif; 

Note: I load the $progs into the global space so i can call it elsewhere in my module.

program.php

if( !class_exists('Program') ):

    class Program 
    {
        //a bunch of properties

        public static function getAllOpenPrograms() 
        {
             // This is the line that causes all of the issues. 
             $result = node_load_multiple('',array('type' => 'program')); 
             dpm($result);

        }

Thanks in advance!


Solution

  • Like Mike Vranckx mentioned, if you call progs() directly when you include it in progs.module, Drupal basically hasn't bootstrapped, i.e. hasn't started running fully yet. Suggest you put your progs() in progs_init() or similar so that Drupal will invoke it at the right time.

    Here's a proposed way that follows your initial structure quite closely, and below you will see an alternative that better follows Drupal's conventions.

    New progs.module

      /**
       * Implements hook_init().
       */
      function progs_init(){
        progs();
      }
    

    And modify your progs.php

        // Why are you doing this check? Are you defining this class elsewhere in your project? If not you can safely ignore this
        //if( !class_exists('progs') ):
    
        // Convention is to name classes with Pascal case btw.
        class progs 
        {
            //a bunch of properties
    
            function __construct()
            {
                // load partial includes and objects
                $this->load_partial_inclues();
    
                //retrieve all programs that are open
                $this->open_programs = Program::getAllOpenPrograms();
            }
    
            function load_partial_inclues()
            {
                //includes
                include_once(drupal_get_path('module', 'progs') . '/core/objects/program.php');
            }
    
        }
    
        function progs()
        {
            global $progs;
    
            if( !isset($progs) )
            {
                $progs = new progs();
            }
    
            return $progs;
    
        }
    

    A more Drupal way:

    progs.module

        /**
        * Implements hook_init().
        */
        function progs_init(){
            global $progs;
    
            // Consider using drupal_static to cache this
            if( !isset($progs) )
            {
                module_load_include('inc', 'progs', 'progs');
                $progs = new Progs();
            }
        }
    

    progs.inc (convention is to use .inc)

        class Progs 
        {
            //a bunch of properties
    
            function __construct()
            {
                // load partial includes and objects
                $this->load_partial_inclues();
    
                //retrieve all programs that are open
                $this->open_programs = Program::getAllOpenPrograms();
            }
    
            function load_partial_inclues()
            {
                //includes
                module_load_include('php', 'progs', 'core/objects/program');
            }
    
        }