ATK4 model not found when moving to online

2020-02-15 10:06发布

问题:

I am developing a website using ATK4, a php framework with jquery.

I have developed this on my laptop using localhost/test1 as the directory and with a local php database.

If i move all the directories online and import the php database to my web host, most of the pages work but on one, i get an error on one of the pages indicating

Fatal error: Class 'model_TaskType' not found in /homepages/4/d184034614/htdocs/paperless/atk4/lib/AbstractObject.php on line 131

The line referred to in AbstractObject.php is part of the add function.

The model is present and exactly the same code is working on localhost. Other pages also have models and appear to be working fine. The table has exactly the same structure on both databases.

The model is not directly referenced in the page that has a problem, it is a refModel to a Model which is referenced. Is there some path issue here that doesnt present itself on localhost ?

The TaskType model looks like this class Model_TaskType extends Model_Table { public $entity_code='vscrum_tasktype'; public $table_alias='ty';

function init(){
    parent::init();

    $this->addField('id')->mandatory(true);
    $this->addField('name')->mandatory(true);
    $this->addField('budget_code')->mandatory(true);
    $this->addField('colour_desc')->refModel('model_Colour');
    $this->addField('project_id');
    $this->addField('team_id');
    $this->addField('company_id');

    $this->addCondition('team_id',$this->api->getTeamID());
  }

}

and the Task Model which is added to the page with the problem looks like this

  class Model_Task extends Model_Table {
  public $entity_code='vscrum_task';
  public $table_alias='tk'; 

function init(){
    parent::init();

//  debug causes error in Ajax in ATK v4.1.1
//  $this->debug(true);
$this->addField('id')->system(true)->visible(false);
$this->addField('story_id')->system(true)->visible(false);
$this->addField('backlog_ref')->system(true)->visible(false);
$this->addField('sprint_id')->system(true)->visible(false);
$this->addField('team_id')->system(true)->visible(false);
$this->addField('status')->defaultValue('I')->visible(false);
$this->addField('task_desc')->mandatory(true)->visible(true);
$this->addField('points')->mandatory(true)->defaultValue(1)->datatype('numeric');
    $this->addField('member_id')->mandatory(true)->refModel('model_Member');

    // join colour
    $this->addRelatedEntity('ty','vscrum_tasktype','tasktype_id','left');

    //tasktype
    $this->addField('tasktype_id')->refModel('model_TaskType')->mandatory(true);

}
}

Maybe i've missed something obvious, any ideas why this would work fine on localhost but break on my webhost ?

回答1:

 Class 'model_TaskType' not found in 

you should always use exact capitalization.

if you have Model_TaskType, it should be Model_TaskType when added to CRUD.

also this place:

$this->addField('tasktype_id')->refModel('model_TaskType')->mandatory(true);

should be:

$this->addField('tasktype_id')->refModel('Model_TaskType')->mandatory(true);

On widows, file name capitalization does not make a difference, where as in linux it does.



回答2:

in my experience with ATK4 (v4.1.3) this error is more likely a case-sensitivity and folder search declaration problem.

as the ATK4 PathFinder is the one responsible for loading all the classes, when you add() an object, like, Model_UserAccess it looks for different locations particularly: Model/UserAccess.php it then include() the file and then instantiates the class Model_UserAccess inside it, something like return new Model_UserAccess().

PathFinder changes all instances of underscores _ to / and traverse the locations accordingly.

therefore, a declaration something like this:

class Model_UserAccess extends Model_Table

and adding it:

$m = $this->add('Model_UserAccess');

searches and loads two files (not in particular order), 1st from: /Model/Table.php and 2nd from: /Model/UserAccess.php

once you are comfortable with this folder separation concept, developing in ATK4 will be much much easier.

i myself have a /lib/Model/ and /lib/Form/ and even a /lib/Form/Field/ since i am also redefining up to the field level. The latter would look something like:

class Form_Field_GraduatedSlider extends Form_Field



回答3:

OK, seems a bit strange but this is what i found.

I have a model called Task which extends Table.

class Model_Task extends Model_Table {
public $entity_code='vscrum_task';
    public $table_alias='tk';

function init(){
  parent::init();
  $this->addField('id')->system(true)->visible(false);
  $this->addField('story_id')->system(true)->visible(false);
  $this->addField('backlog_ref')->system(true)->visible(false);

  $this->addField('status')->defaultValue('I')->visible(false);
  $this->addField('task_desc')->mandatory(true)->visible(true);

      $this->addField('member_id')->mandatory(true)->refModel('model_Member');

      // join colour
      $this->addRelatedEntity('ty','vscrum_tasktype','tasktype_id','left');

      //tasktype
      $this->addField('tasktype_id')->refModel('model_TaskType')->mandatory(true);
 }

I have a model called ScrumwallTask which extends Task

class Model_ScrumwallTask extends Model_Task {

function init(){
  parent::init();

  $this->addField('status')->defaultValue('I')->system(true);
      $this->addField('colour_desc')->datatype('text')->calculated(true);
      $this->addField('status')->visible(true);

    }

function calculate_colour_desc(){
        return $this->api->db->dsql()
            ->table('vscrum_colour')
            ->where('id=ty.colour_id')
            ->field('colour_desc')
            ->select();
    }
}

ScrumwallTask calls parent::init so i assumed it would get all the fields added to Task

I got rid of the error by duplicating the addField for tasktype_id into ScrumwallTask even though it is already defined in the parent Task.

$this->addField('tasktype_id')->refModel('Model_TaskType');

Is that expeced behaviour for inheritance of models ? What is really confusing is that it worked fine on localhost (Windows 7) !