Create a custom resource webservice PrestaShop - php

I create a module for PrestaShop 1.6 where I create a table as following in mymodule/mymodule.php:
class Mymodule extends Module {
// Some code
public function installDb() {
return Db::getInstance()->execute("
CREATE TABLE IF NOT EXISTS `" . _DB_PREFIX_ . "mytable`(
`id_mdm` INT NOT NULL AUTO_INCREMENT,
`id_category` INT NOT NULL,
`service` INT NOT NULL,
`title` VARCHAR(300) NOT NULL default '',
`title_font_size` VARCHAR(128) NOT NULL default '',
`title_color` VARCHAR(128) NOT NULL default '',
`background_color` VARCHAR(128) NOT NULL default '',
`border_style` VARCHAR(128) NOT NULL default '',
`position` INT NOT NULL,
`count` INT NOT NULL,
PRIMARY KEY (`id_mdm`), UNIQUE (`id_category`)) ENGINE = InnoDB;");
}
// Some code
}
It works fine, my table is created. Then I override webservice in mymodule/override/classes/webservice/WebserviceRequest.php:
class WebserviceRequest extends WebserviceRequestCore {
public static function getResources() {
$resources = parent::getResources();
$resources['myresource'] = array(
'description' => '',
'class' => 'myresource'
);
ksort($resources);
return $resources;
}
}
I create a new class called myresource in mymodule/override/classes/Myresource.php:
class MyresourceCore extends ObjectModel {
public $id;
public $id_mdm;
public $id_category;
public $service;
public $title;
public $title_font_size;
public $title_color;
public $background_color;
public $border_style;
public $position;
public $count;
public static $definition = array(
'table' => 'mytable',
'primary' => 'id_mdm',
'fields' => array(
'id_category' => array('type' => self::TYPE_INT),
'service' => array('type' => self::TYPE_INT),
'title' => array('type' => self::TYPE_STRING),
'title_font_size' => array('type' => self::TYPE_STRING),
'title_color' => array('type' => self::TYPE_STRING),
'background_color' => array('type' => self::TYPE_STRING),
'border_style' => array('type' => self::TYPE_STRING),
'position' => array('type' => self::TYPE_INT),
'count' => array('type' => self::TYPE_INT)
)
);
protected $webserviceParameters = array();
}
In the Back office I generate a key for myresource, but when I test in my browser http://mydomain/api/myresource?ws_key=mykey, there is the following error:
Fatal error: Class 'myresource' not found in /path/mydomain/classes/webservice/WebserviceRequest.php on line 502
I don't know why PrestaShop doesn't detect it. Thank you in advance for your assistance.

In Prestashop 1.7, you can use this hook: addWebserviceResources
Example:
include_once dirname(__FILE__) . '/classes/Sample.php';
class myAPISample extends Module {
// ...
public function install() {
return parent::install() && $this->registerHook('addWebserviceResources');
}
// ...
public function hookAddWebserviceResources($params) {
return [ 'samples' => ['description' => 'My sample', 'class' => 'Sample' ] ];
}
//...
}
See also (in french) : https://www.h-hennes.fr/blog/2018/06/25/prestashop-ajouter-un-objet-dans-lapi/

If you check the PHP error logs, you will notice an error of the type Class not found. In this case it's class "MyResource" not found.
In order to solve this, you need to include your Model class in the constructor of the override method like this
class WebserviceRequest extends WebserviceRequestCore {
public function __construct()
{
include_once(_PS_MODULE_DIR_ . 'myresource' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'MyResource.php');
}
public static function getResources()
{
$resources = parent::getResources();
$resources['myresource'] = array(
'description' => '',
'class' => 'myresource'
);
ksort($resources);
return $resources;
}
}
And you need to place the Model Class in /mymodule/classes/MyResource.php
Placing the Model Class in mymodule/override/classes/Myresource.php is not correct cause there is no Myresource class to override. This will give you an error when uninstalling the module - you will not be able to uninstall it

Finally I found an alternative solution without using the native PrestaShop webservice. I created a directory called webservice in mymodule/webservice/mymodule.php. This file will be used to post data to PrestaShop's website. Here is how I did it:
<?php
$currentDirectory = str_replace('modules/mymodule/webservice/', '',
dirname($_SERVER['SCRIPT_FILENAME']) . "/");
$sep = DIRECTORY_SEPARATOR;
require_once $currentDirectory . 'config' . $sep . 'config.inc.php';
require_once $currentDirectory . 'init.php';
$hostnameIp = $_SERVER['REMOTE_ADDR'];
if ($hostnameIp == 'AUTHORIZED_IP') {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Some code
http_response_code(200);
} else {
http_response_code(405);
}
} else {
http_response_code(403);
}
Then I just need to execute a POST request to myresource at the following url: http://mydomain/modules/mymodule/webservice/mymodule.php.
Be careful to do some validation for security, like IP address. If the validation is successful, then your do some treatment to insert or update data to mysql tables.

Related

SECURITY TOKEN in first Prestashop 1.7 module

I have tryed now for a few day´s to create a module.
Its going to be a easy one, that add some variable to different table, and show them in a list when you select from a dropdown.
Im only still in admin, the front do i create later,
I follow a tutorials that was easy to follow.
First copy the sql to the db.
CREATE TABLE pasta (
`id` INT NOT NULL AUTO_INCREMENT,
`sku` VARCHAR(255) NOT NULL,
`name` VARCHAR(255) NOT NULL,
`description` TEXT,
`id_pasta_category` INT NOT NULL,
`created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE = InnoDB;
Then i copy the ObjectModel class /override/classes/fc_pasta/Pasta.php
<?php
class Pasta extends ObjectModel {
public $id; // fields are mandatory for create/update
public $sku;
public $name;
public $created;
public $category;
public $id_pasta_category;
public static $definition = [
'table' => 'pasta',
'primary' => 'id',
'fields' => [
'sku' => ['type' => self::TYPE_STRING, 'validate' => 'isAnything', 'required'=>true],
'name' => ['type' => self::TYPE_STRING, 'validate' => 'isAnything', 'required'=>true],
'description' => ['type' => self::TYPE_HTML, 'validate' => 'isAnything',],
'created' => ['type' => self::TYPE_DATE, 'validate' => 'isDateFormat'],
'id_pasta_category' => ['type'=>self::TYPE_INT, 'validate'=>'isUnsignedInt','required'=>true,],
],
];
}
And after that i copy the module /modules/fc_pasta/fc_pasta.php
<?php
if (!defined('_PS_VERSION_')) {exit;}
class Fc_Pasta extends Module {
public function __construct() {
$this->name = 'fc_pasta'; // must match folder & file name
$this->tab = 'administration';
$this->version = '1.0.0';
$this->author = 'Florian Courgey';
$this->bootstrap = true; // use Bootstrap CSS
parent::__construct();
$this->displayName = $this->l('PrestaShop Module by FC');
$this->description = $this->l('Improve your store by [...]');
$this->ps_versions_compliancy = ['min' => '1.7', 'max' => _PS_VERSION_];
// install Tab to register AdminController in the database
$tab = new Tab();
$tab->class_name = 'AdminPasta';
$tab->module = $this->name;
$tab->id_parent = (int)Tab::getIdFromClassName('DEFAULT');
$tab->icon = 'settings_applications';
$languages = Language::getLanguages();
foreach ($languages as $lang) {
$tab->name[$lang['id_lang']] = $this->l('FC Pasta Admin controller');
}
$tab->save();
}
}
And after that i create the AdminPastaController
<?php
require_once _PS_ROOT_DIR_.'/override/classes/fc_pasta/Pasta.php';
class AdminPastaController extends ModuleAdminController {
public function __construct(){
parent::__construct();
// Base
$this->bootstrap = true; // use Bootstrap CSS
$this->table = 'pasta'; // SQL table name, will be prefixed with _DB_PREFIX_
$this->identifier = 'id'; // SQL column to be used as primary key
$this->className = 'Pasta'; // PHP class name
$this->allow_export = true; // allow export in CSV, XLS..
// List records
$this->_defaultOrderBy = 'a.sku'; // the table alias is always `a`
$this->_defaultOrderWay = 'ASC';
$this->_select = 'a.name as `pastaName`, cl.name as `categoryName`';
$this->_join = '
LEFT JOIN `'._DB_PREFIX_.'category` cat ON (cat.id_category=a.id_pasta_category)
LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (cat.id_category=cl.id_category and cat.id_shop_default=cl.id_shop)';
$this->fields_list = [
'id' => ['title' => 'ID','class' => 'fixed-width-xs'],
'sku' => ['title' => 'SKU'],
'pastaName' => ['title' => 'Name', 'filter_key'=>'a!name'], // filter_key mandatory because "name" is ambiguous for SQL
'categoryName' => ['title' => 'Category', 'filter_key'=>'cl!name'], // filter_key mandatory because JOIN
'created' => ['title' => 'Created','type'=>'datetime'],
];
// Read & update record
$this->addRowAction('details');
$this->addRowAction('edit');
$categories = Category::getCategories($this->context->language->id, $active=true, $order=false); // [0=>[id_category=>X,name=>Y]..]
$categories = [['id'=>1, 'display'=> 'abc'], ['id'=>2, 'display'=>'def']];
$this->fields_form = [
'legend' => [
'title' => 'Pasta',
'icon' => 'icon-list-ul'
],
'input' => [
['type'=>'html','html_content'=>'<div class="alert alert-info">Put here any info content</div>'],
['name'=>'id_xxx','label'=>'XXX','type'=>'select',
'options'=>[ 'query'=>$categories,
'id'=>'id', // use the key id as the <option> value
'name'=> 'display', // use the key display as the <option> title
]
],
['name'=>'name','type'=>'text','label'=>'Name','required'=>true],
['name'=>'description','type'=>'textarea','label'=>'Description',],
['name'=>'created','type'=>'datetime','label'=>'Created',],
['name'=>'id_pasta_category','label'=>'Category','type'=>'select','required'=>true,'class'=>'select2',
'options'=>[ 'query'=>$categories,
'id'=>'id_category', // use the key "id_category" as the <option> value
'name'=> 'name', // use the key "name" as the <option> title
]],
],
'submit' => [
'title' => $this->trans('Save', [], 'Admin.Actions'),
]
];
}
protected function getFromClause() {
return str_replace(_DB_PREFIX_, '', parent::getFromClause());
}
}
Everything almost ok, but everytime i update the page it create a new menu all the time:
FC Pasta Admin controller, instead of 1 i have 25 now.
That I can´t find why.
And one more thing, everything i do in the module i get INVALID SECURITY TOKEN
Im really new to create modules to PS 1.7, but i really whant to try.
You are creating and saving a new backoffice tab in the module constructor,
so a new tab will be created everytime the module object is instantiated.
You'll need to move the tab creation login in the install() method of the module, so that your tab will be created only once during the very first module installation.

Module lang not working in Prestashop 1.7.6

Just trying to create a new simple module with translation but the saving process is not working. The table 'ps_myoptions_lang' is updating with the field id_myoptions = 0 in each lang_id and nothing is saved in 'ps_myoptions'.
modules/myoptions/controllers/admin/AdminOptionsController.php
<?php
require_once(dirname(__FILE__) . './../../classes/Option.php');
class AdminOptionsController extends AdminController
{
public function __construct(){
parent::__construct();
$this->bootstrap = true; // use Bootstrap CSS
$this->table = 'myoptions'; // SQL table name, will be prefixed with _DB_PREFIX_
$this->lang = true;
$this->identifier = 'id_myoptions'; // SQL column to be used as primary key
$this->className = 'Option'; // PHP class name
$this->allow_export = true; // allow export in CSV, XLS..
$this->_defaultOrderBy = 'a.name'; // the table alias is always `a`
$this->_defaultOrderWay = 'DESC';
$this->fields_list = [
'id_myoptions' => ['title' => 'ID','class' => 'fixed-width-xs'],
'name' => ['title' => 'Name'],
];
$this->addRowAction('edit');
$this->addRowAction('details');
$this->fields_form = [
'legend' => [
'title' => 'Pasta',
'icon' => 'icon-list-ul'
],
'input' => [
['name'=>'name','type'=>'text', 'lang' => true, 'label'=>'Name','required'=>true],
],
'submit' => [
'title' => $this->trans('Save', [], 'Admin.Actions'),
]
];
}
}
modules/myoptions/classes/Options.php
<?php
class Option extends ObjectModel
{
public $id;
public $name;
public static $definition = [
'table' => 'myoptions',
'primary' => 'id_myoptions',
'multilang' => true,
'fields' => [
'name' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isAnything', 'required'=>true],
],
];
}
modules/myoptions/myoptions.php
if (!defined('_PS_VERSION_')) {
exit;
}
class Myoptions extends Module
{
protected $config_form = false;
public function __construct()
{
$this->name = 'myoptions';
$this->tab = 'administration';
$this->version = '1.0.0';
$this->author = 'abc';
$this->need_instance = 1;
/**
* Set $this->bootstrap to true if your module is compliant with bootstrap (PrestaShop 1.6)
*/
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('My Options');
$this->description = $this->l('Add additional options');
$this->ps_versions_compliancy = array('min' => '1.7', 'max' => _PS_VERSION_);
}
/**
* Don't forget to create update methods if needed:
* http://doc.prestashop.com/display/PS16/Enabling+the+Auto-Update
*/
public function install()
{
Configuration::updateValue('MYOPTIONS_LIVE_MODE', false);
include(dirname(__FILE__).'/sql/install.php');
return parent::install() &&
$this->registerHook('header') &&
$this->registerHook('backOfficeHeader') &&
$this->installTabs();
}
public function uninstall()
{
Configuration::deleteByName('MYOPTIONS_LIVE_MODE');
include(dirname(__FILE__).'/sql/uninstall.php');
return parent::uninstall();
}
public function enable($force_all = false)
{
return parent::enable($force_all)
&& $this->installTabs()
;
}
public function disable($force_all = false)
{
return parent::disable($force_all)
&& $this->uninstallTabs()
;
}
/**
* Since PS 1.7.1
* #var array
*/
public $tabs = array(
array(
'name' => array(
'en' => 'Options', // Default value should be first
'fr' => 'Options',
),
'class_name' => 'AdminOptions',
'visible' => true,
'parent_class_name' => 'AdminParentThemes',
),
);
public function installTabs()
{
$moduleName = $this->name;
$this->addTab('AdminOptions', 'Options', $moduleName, 'AdminTools');
return true;
}
public function addTab($className, $tabName, $moduleName, $parentClassName)
{
$tab = new Tab();
$tab->active = 1;
$tab->class_name = $className;
$tab->name = array();
foreach (Language::getLanguages(true) as $lang) {
$tab->name[$lang['id_lang']] = $tabName;
}
$tab->id_parent = (int) Tab::getIdFromClassName($parentClassName);
$tab->module = $moduleName;
$tab->add();
return $tab;
}
}
Is there something that I'm doing wrong?
Thanks for your answer.
Prestashop 1.7.6
PHP 7.2.25
I think I found the problem :
$sqlCreate = "CREATE TABLE `" . _DB_PREFIX_ . "myoptions` (
`id_myoptions` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id_myoptions`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
$sqlCreateLang = "CREATE TABLE `" . _DB_PREFIX_ . "myoptions_lang` (
`id_myoptions` int(11) unsigned NOT NULL AUTO_INCREMENT,
`id_lang` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id_myoptions`,`id_lang`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
Db::getInstance()->execute($sqlCreate) && Db::getInstance()->execute($sqlCreateLang);
I have the same field name in both tables. I then use it only in Lang Table and it seems to work now.

I do not see the save button on my form even though I have set it up in Admin Area Magento

I am new to mangeto framework and i am learning to create a form in admin area section. However, it has been over hours that I could not figure out the error i am receiving:
Recoverable Error: Argument 1 passed to Mage_Adminhtml_Controller_Action::_addContent() must be an instance of Mage_Core_Block_Abstract, boolean given, called in /vagrant/magento/app/code/local/MasteringMagento/Example/controllers/Adminhtml/EventController.php on line 12.
The following is my Edit.php file as well as my Form.php file
Edit.php:
class MasteringMagento_Example_Adminhtml_EventController extends Mage_Adminhtml_Controller_Action{
public function indexAction(){
$this->loadLayout();
$this->_addContent(
$this->getLayout()->createBlock('example/adminhtml_event_edit'));
//go straight to the php file to render the form. otherwise this will not perfomed.
$this->renderLayout();
}
public function saveAction(){
$eventID = $this->getRequest()->getParam('event_id');
$eventModel = Mage::getModel('example/event')->load($eventID);
if($data = $this->getRequest()->getPost()){
try{
$eventModel->addData($data)->save();
Mage::getSingleton('adminhtml/session')->addSuccess(
$this->__('Your event has been saved')
);
}catch(Exception $e){
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
}
$this->_redirect('*/*/index');
}
}
}
and Form.php file:
class MasteringMagento_Example_Block_Adminhtml_Event_Edit_Form extends Mage_Adminhtml_Block_Widget_Form{
protected function _prepareForm(){
$form = new Varien_Data_Form(array('id'=>'edit_form',
'action'=>$this->getData('action'), 'method'=>'post'));
$fieldset = $form->addFieldset('base_fieldset',
array('legend'=>Mage::helper('example')->__('General Information'),
'class'=>'fieldset-wide'));
$fieldset->addField('name', 'text', array(
'name' => 'name',
'label' => Mage::helper('example')->__('Event Name'),
'title' => Mage::helper('example')->__('Event Name'),
'required' => true
));
$dateFormatIso = Mage::app()->getLocale()->getDateFormat(
Mage_Core_Model_Locale::FORMAT_TYPE_SHORT);
$fieldset->addField('start', 'date', array(
'name' => 'start',
'format' => $dateFormatIso,
'image' => $this->getSkinUrl('images/grid-cal.gif'),
'label' => Mage::helper('example')->__('Start Date'),
'title' => Mage::helper('example')->__('Start Date'),
'required' => true
));
$fieldset->addField('end', 'date', array(
'name' => 'end',
'format' => $dateFormatIso,
'image' => $this->getSkinUrl('images/grid-cal.gif'),
'label' => Mage::helper('example')->__('End Date'),
'title' => Mage::helper('example')->__('End Date'),
'required' => true
));
$form->setUseContainer(true);
$this->setForm($form);
return parent::_prepareForm();
}
}
The error i think is from my Controller. However, if i direct the url link to the form, it will display. But if i direct to its container which is Edit.php, the error above would occurs:
class MasteringMagento_Example_Adminhtml_EventController extends Mage_Adminhtml_Controller_Action{
public function indexAction(){
$this->loadLayout();
$this->_addContent(
$this->getLayout()->createBlock('example/adminhtml_event_edit'));
//go straight to the php file to render the form. otherwise this will not perfomed.
$this->renderLayout();
}}
This is my config.xml. I did include the base class for Magento Blocks:
<blocks>
<example>
<class>MasteringMagento_Example_Block</class>
</example>
</blocks>
Please help me to identify the problem. Thanks
createBlock() is an abstract factory pattern for Blocks inside of Magento. Whenever Magento cannot resolve a factory class from this method, a boolean is returned... which is the case in your example, as the error message says.
Check your class MasteringMagento_Example_Block_Adminhtml_Event_Edit for spelling, casing, or class related errors. Also ensure that your class file is located at app/code/local/MasteringMagento/Example/Block/Adminhtml/Event/Edit.php.
In magento, every admin form block is loaded first by a form container.
Here, you call MasteringMagento_Example_Block_Adminhtml_Event_Edit class :
$this->getLayout()->createBlock('example/adminhtml_event_edit')
This class, located in app/code/local/MasteringMagento/Example/Block/Adminhtml/Post/Edit.php, should look to something like this :
<?php
/**
* MasteringMagento_Example_Block_Adminhtml_Post_Edit
*/
class MasteringMagento_Example_Block_Adminhtml_Post_Edit extends Mage_Adminhtml_Block_Widget_Form_Container
{
public function __construct()
{
// $this->_objectId = 'id';
parent::__construct();
$this->_blockGroup = 'example';
$this->_controller = 'adminhtml_post';
$this->_mode = 'edit';
$modelTitle = $this->_getModelTitle();
$this->_updateButton('save', 'label', $this->_getHelper()->__("Save $modelTitle"));
$this->_addButton('saveandcontinue', array(
'label' => $this->_getHelper()->__('Save and Continue Edit'),
'onclick' => 'saveAndContinueEdit()',
'class' => 'save',
), -100);
$this->_formScripts[] = "
function saveAndContinueEdit(){
editForm.submit($('edit_form').action+'back/edit/');
}
";
}
protected function _getHelper(){
return Mage::helper('example');
}
protected function _getModel(){
return Mage::registry('exemple_youmodel');
}
protected function _getModelTitle(){
return 'Post';
}
public function getHeaderText()
{
$model = $this->_getModel();
$modelTitle = $this->_getModelTitle();
if ($model && $model->getId()) {
return $this->_getHelper()->__("Edit $modelTitle (ID: {$model->getId()})");
}
else {
return $this->_getHelper()->__("New $modelTitle");
}
}
/**
* Get URL for back (reset) button
*
* #return string
*/
public function getBackUrl()
{
return $this->getUrl('*/*/index');
}
public function getDeleteUrl()
{
return $this->getUrl('*/*/delete', array($this->_objectId => $this->getRequest()->getParam($this->_objectId)));
}
}
As you can see, all your buttons are set in the __construct() method.
Hope it helps.

How to retrieve the model name within the table class in symfony 1.4?

I am inside a ModelTable and I need the Model name. For example: in case of EventTable I need to know the model it instantiates - Event.
Internally the following function already instantiates an correct Model:
class EventTable extends Doctrine_Table
{
public function findBySomething($something)
{
// Will return a Event
return $this->createQuery('s')->fetchOne();
}
}
What I would like to be able to do:
class EventTable extends Doctrine_Table
{
public function findBySomething($something)
{
$modelName = $this->getModelName();
echo "I will create a ".$modelName; // Will display Event
return $this->createQuery('s')->fetchOne();
}
}
How do I retrieve the model name from inside a table?
You have an array of options available for each Table (Doctrine/Table.php):
protected $_options = array(
'name' => null,
'tableName' => null,
'sequenceName' => null,
'inheritanceMap' => array(),
'enumMap' => array(),
'type' => null,
'charset' => null,
'collate' => null,
'treeImpl' => null,
'treeOptions' => array(),
'indexes' => array(),
'parents' => array(),
'joinedParents' => array(),
'queryParts' => array(),
'versioning' => null,
'subclasses' => array(),
);
So you can retrieve the model name using:
$this->getOption('name');

Php inheritance superclass variables

I try to load an entity with some details and there is a resellerId in the entity.
Now I inherit a subclass from it, and try to access the resellerId but it's not there. How to pass the attributes to the subclasses? I really need it loaded.
Thanks!
edit:
class Crm_Entity extends Crm_Abstract {
protected $_mapper = 'Crm_Mapper_Entity';
protected $_data = array(
'customerId' => '', //done
'displayName' => '', //done
'active' => '', //done
'billingMethod' => '', //done
'debitorNumber' => null, //done
'bankAccount' => null, //done
'bankAccountTown' => null, //done
'resellerOrganisationId'=> null,
'account' => null, //done
'phonenumbers' => null, //done
'calls' => null,
'tickets' => null,
'comments' => null,
'addresses' => null,
'emailaddresses' => null, //done
'actionevents' => null
);
}
class Crm_CustomerEntity extends Crm_Entity {
//foobar not done yet
}
class Crm_Person extends Crm_CustomerEntity {
protected $_data = array(
'customerId' => null,
'firstName' => '',
'middleName' => '',
'lastName' => '',
'initials' => '',
'title' => '',
'openingWord' => ''
);
}
So I need to get the resellerId passed on to the subclass.
Ok, this is clear now.
You're storing data in associative arry. AND you're redefining this array in subclass. Of course, it won't have values form superclass that way.
Move array definition to class constructor instead. Then you should have
<?php
class Crm_Entity extends Crm_Abstract
{
protected $_mapper = 'Crm_Mapper_Entity';
protected $_data;
public function __construct()
{
parent::__construct();
$newData = array(
'customerId' => '', //done
'displayName' => '', //done
'active' => '', //done
'billingMethod' => '', //done
'debitorNumber' => null, //done
'bankAccount' => null, //done
'bankAccountTown' => null, //done
'resellerOrganisationId'=> null,
'account' => null, //done
'phonenumbers' => null, //done
'calls' => null,
'tickets' => null,
'comments' => null,
'addresses' => null,
'emailaddresses' => null, //done
'actionevents' => null
);
$this->_data = $newData;
}
}
class Crm_CustomerEntity extends Crm_Entity
{
//foobar not done yet
public function __construct()
{
parent::__construct();
}
}
class Crm_Person extends Crm_CustomerEntity
{
public function __construct()
{
parent::__construct();
$newData = array(
'customerId' => null,
'firstName' => '',
'middleName' => '',
'lastName' => '',
'initials' => '',
'title' => '',
'openingWord' => ''
);
$this->_data = array_merge($this->_data, $newData);
}
}
Of course the actual design depends - if you want those mappings before you create class you should put them in some static function instead. Something like
class Crm_Person extends Crm_CustomerEntity
{
public static function getData()
{
$data = Crm_Entity::getData()
$newData = (...)
return array_merge($data, $newData);
}
}
Your question isn't really easy to understand, but I'd check the scope of your class properties. For example:
class BaseClass {
protected $resellerId;
public function setResellerId($resellerId) {
$this->resellerId = $resellerId;
}
public function getResellerId() {
return $this->resellerId;
}
// rest of class code here
}
class ChildClass extends BaseClass {
// class contents
}
$obj = new ChildClass;
$obj->setResellerId(326);
echo $obj->getResellerId(); // should print '326' to your page
The protected keyword makes your $resellerId property available in that class, and all sub-classes. Also, public classes become available in classes extending the class in which they're defined, so I can use them in my ChildClass to access the $resellerId property, which is also available in my ChildClass.
Public or protected variable from the parent class should be accessable by children inheriting from it, private variables are not reachable. If the property is public or private and you still can not reach it, more info/ the actual code is required.
There is no resellerOrganisationId keyed value in the $_data array for an instance of Crm_Person because the entire $_data array in the Crm_Entity grand-parent class is overridden by the inheritance. All you have is the $_data array as defined in the Crm_Person class.
EDIT
class Crm_Entity {
protected $_mapper = 'Crm_Mapper_Entity';
protected $_data = array(
'customerId' => '', //done
'displayName' => '', //done
'active' => '', //done
'billingMethod' => '', //done
'debitorNumber' => null, //done
'bankAccount' => null, //done
'bankAccountTown' => null, //done
'resellerOrganisationId'=> null,
'account' => null, //done
'phonenumbers' => null, //done
'calls' => null,
'tickets' => null,
'comments' => null,
'addresses' => null,
'emailaddresses' => null, //done
'actionevents' => null
);
}
class Crm_CustomerEntity extends Crm_Entity {
//foobar not done yet
}
class Crm_Person extends Crm_CustomerEntity {
public function __construct() {
$this->_data['customerId'] = null;
$this->_data['firstName'] = '';
$this->_data['middleName'] = '';
$this->_data['lastName'] = '';
$this->_data['initials'] = '';
$this->_data['title'] = '';
$this->_data['openingWord'] = '';
}
public function getData() {
return $this->_data;
}
}
$test = new Crm_Person();
var_dump($test->getdata());

Categories