2

I'm building a traderbot for drupal and I have problems with the namespacing. Something is not working or I do not understand it correctly. I looked on several pages and questions but could not understand it.

The start

I runned all code without namespaces. Then it is working well !!!

I included a project called ccxt. In this project there are classes with the same name. They have a class called kraken and I have as well. There classes are in namespace ccxt.

So mine class should be namespaced. Which is very obvious.

As I do call from drush I need to have a own autoloader.

function autoloader_traderbot( $class_name ){

  // Because of namespaces $class_name could be string/string therefore only the last string should be taken
  if (($pos = strpos($class_name, '\\')) !== FALSE) { 
    $class_name = substr($class_name, $pos+1); 
    (new log)->add(4,'Class name adjusted. Namespace removed from class path.');

  }

  (new log)->add(4,'Searching for loading class  name  : ' . $class_name );

  $dir_iterator = new RecursiveDirectoryIterator(CLASS_DIR);
  $iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST);

  foreach ($iterator as $file) {
    if($file->getFilename() == $class_name . ".class.php"){
      (new log)->add(4,'Loading class file name (.class.php) : ' . $class_name . ' in filename ' . $file );
      require_once tb_adjustfilename($file);
    }

    if($file->getFilename() == $class_name . ".php"){
      (new log)->add(4,'Loading class file name (.php): ' . $class_name . ' in filename ' . $file);
      require_once tb_adjustfilename($file);      
    };
  }

} 

So I add in kraken.class.php

namespace traderbot;

Then calling this object is working fine.

But then the problems are there

I also get

Error: Class 'traderbot\log' not found in traderbot\kraken->update_ohlc() (line 48 of C:\www\tb\modules\custom\tb\src\exchanges\kraken.class.php) #0 [31;40m[1m[error][0m

I checked log.class.php.

This is not namespaced so I add

namespace traderbot;

But then I get from php

Error: Class 'traderbot\SplFileInfo' not found in traderbot\log->add() (line 66 of C:\www\tb\modules\custom\tb\src\library\log.class.php).
Drush command terminated abnormally due to an unrecoverable error.    

But now I'm lost. Because this is just a normal php object so why is it going wrong?

Addition

Thxs, with the help of the answers it is working now. I saw the excellent video, change the statements, disable my own autoloading procedure.

As a result of this I should add in my classes the use statement for every object I use. The only thing I find a little bit strange is the following.

In every php file with a class I should add the use statement for every object.

Example 1.

// Define namespaces and objects
namespace Drupal\tb\library;
use SplFileInfo;
class log{
}

Example 2

namespace Drupal\tb;

use Drupal\tb\library\log;
use Drupal\tb\datacollector\datacollector;
use Drupal\tb\datacalculator\datacalculator;
use Drupal\tb\scenario\scenario;

class traderbot{


    public function start(){

        (new log)->add(0,"Start data collector");
        $collector = new datacollector;
        ...

        (new log)->add(0,"Start data calculator");
        $indicators = new datacalculator;
        ...

        (new log)->add(0,"Start scenario handler");
        $sc_handler = new scenario;
        ...

    }

}

I red some other documentation and QA and understand dat wild card loading of namespacing is not possible. https://stackoverflow.com/questions/29851099/how-to-load-all-classes-of-a-namespace but I also red somewhere that as long as the class is in the same namespace it is not needed to put the use statement for this object. So then I come to the following questions for verification:

Q1) Adding a standard use statement for SPL looks very strange for me. Is this correct?

Q2) Adding a long list of several use statements from unique objects in the same namespace is very strange for me as well. Is this correct?

3
  • Please show us the following to be able to debug your issue: the error, the namespace declaration and class declaration, the code that is calling that class, and any use statements implemented in the file for the code calling that class.
    – Jaypan
    Commented Jun 19, 2018 at 23:42
  • The namespacing is wrong. Read about PSR-4 autoloading and the doc pages on the same topic in Drupal.
    – Kevin
    Commented Jun 20, 2018 at 3:37
  • I still don’t understand why you need to do all of that code like that. Once you properly define your class, you should be able to add a use ... statement in the drush command to pull in the class and use it. Read the documentation on drupal.org about creating modules and classes, like a simple FormBase form or Controller. It’s all on display there.
    – Kevin
    Commented Jun 20, 2018 at 3:43

1 Answer 1

3

This is not namespaced so I add

namespace traderbot;

Clearly you don't understand the concept of namespaces, so I suggest you watch this short video.

After watching the video, you should come to the realization that you're telling PHP to open the "traderbot" folder which does not exist.

According the official Drupal docs on Namespaces, you need to structure it like this for Drupal:

namespace Drupal\<module name>\SubFolder1\SubFolder2;

Note: Since Drupal uses autodiscovery the \modules\custom nor \src paths are not need to be declared here, since Drupal will automatically look inside of these.

Note2: the file name matters, needs to be YourClassName.php (case sensitive).

Class Drupal\example_module\Foo\Bar in namespace Drupal\example_module\Foo should be in a file named example_module/src/Foo/Bar.php

so you should remove the .class part from your file names. In Drupal the convention is to create a file for each class.

In /modules/custom/tb/src/library/log.php you need to put:

namespace Drupal\tb\library;

Then on /modules/custom/tb/src/exchanges/kraken.php to load a class that is in a different name space, you need to put at the top

use <name_space>\<class_name>;

so it would be:

use Drupal\tb\library\log;
2
  • 1
    Namespaces are effectively class/path mappings for the autoloader and also assist in preventing naming collisions of classes.
    – Kevin
    Commented Jun 20, 2018 at 3:40
  • 1
    I think the file name also has to be updated to reflect the actual class name as well.
    – Kevin
    Commented Jun 20, 2018 at 3:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.