How to migrate entity from XML to Drupal 7 using migrate module - php

I have created a class using migrate module but I am unable to migrate entities. my class codes are below please check it and tell me whats the problem with it??
<?php
class ItemOrderXMLMigration extends XMLMigration {
public function __construct() {
parent::__construct(MigrateGroup::getInstance('OrderFeed'));
$this->description = t('Migrate entity from XML file');
//$this->softDependencies = array('WineFileCopy');
$fields = array(
'Number' => t('Number'),
'Date' => t('Date'),
'SubTotal' => t('Sub Total'),
'Discount' => t('Discount'),
'ShippingCharges' => t('Shipping Charges'),
'ShippingChargesDiscount' => t('Shipping Charges Discount'),
'NumItems' => t('NumItems'),
'VATPercentage' => t('VAT Percentage'),
'CurrencyCode' => t('Currency Code'),
'PaymentTypeDesc' => t('Payment Type Desc'),
'OrderState' => t('Order State'),
);
$this->map = new MigrateSQLMap($this->machineName,
array(
'Number' => array(
'type' => 'varchar',
'length' => 225,
'not null' => TRUE,
)
),
MigrateDestinationEntityAPI::getKeySchema('entity_example_basic','first_example_bundle')
);
$xml_folder = DRUPAL_ROOT . '/' . drupal_get_path('module', 'products_import') . '/xml/';
$items_url = $xml_folder . 'OrderFeed.xml';
$item_xpath = '/Orders/Item'; // relative to document
$item_ID_xpath = 'Number'; // relative to item_xpath and gets assembled
// into full path /producers/producer/sourceid
$items_class = new MigrateItemsXML($items_url, $item_xpath, $item_ID_xpath);
$this->source = new MigrateSourceMultiItems($items_class, $fields);
$this->destination = new MigrateDestinationEntityAPI('entity_example_basic','first_example_bundle');
$this->addFieldMapping('field_number', 'Number')
->xpath('Number');
$this->addFieldMapping('field_subtotal', 'SubTotal')
->xpath('SubTotal');
$this->addFieldMapping('field_discount', 'Discount')
->xpath('Discount');
//$this->addUnmigratedDestinations(array('weight'));
}
}
?>
When I import it I got the save error message for all entities: Creating default object from empty value File /var/www/mig/migration/sites/all/modules/migrate_extras/entity_api.inc, line 227

Try the latest or updated migrate module https://www.drupal.org/project/migrate. I think you were using old one which were having some issues to migrate entities.

Why don't you try with a feed importer (Feeds module) using XPath parser module?. It's really easy, and you can use both an uploaded file or a source URL.

Related

Upload CSV File in Admin Controller - Custom module

I'm trying to create an Admin Controller with a csv file uploader to process it like an array.
I can't find an efficient way to do it, I tried to use $this-> fields_form, but nothing is showing up.
Then I did a tpl file with an input file, called in initContent, but I don't know how to retrieve my file in the controller.
I need to create multiple object of different classes that I made, thanks to the csv file.
Does somebody have some documentation that could help me, I've already search through prestashop dev doc, stack overflow, ect but I've didn't see anything that could help me (maybe I didn't search the good way ?)
Waiting for your help guys !
Update :
Update :
Just found a way to upload my file, but it's upload as .tmp and can't be processed as a csv file, how can I convert a tmp file to a csv ?
Here is my code :
public function __construct()
{
parent::__construct();
// Base
$this->bootstrap = true; // use Bootstrap CSS
$this->fields_options = array(
'general' => array(
'title' => $this->l('Upload DB'),
'fields' => array(
'DB_BULB_DATA' => array(
'title' => $this->l('Upload DB'),
'type' => 'file',
'name' => 'DB_BULB_DATA'
),
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
),
);
if(isset($_FILES['DB_BULB_DATA'])){
$headers = fgetcsv(fopen($_FILES['DB_BULB_DATA']['tmp_name'], "r+"));
print_r($headers);
}
}
There is no file type name csvfile , you need to use filed type file and then hadel the csv file after upload, check file extension then process the data.
Just find out how to do it, I feel dummy 😅
I just needed to save my tmp file as a csv to be able to use it then.
Here is the full code :
<?php
class Admin<YourModuleName>Upload<YourThings>DatabaseController extends ModuleAdminController
{
public function __construct()
{
parent::__construct();
// Base
$this->bootstrap = true; // use Bootstrap CSS
$this->name = "Admin<YourModuleName>Upload<YourThings>Database";
$this->fields_options = array(
'general' => array(
'title' => $this->l('Upload DB'),
'fields' => array(
'DB_<YourThings>_DATA' => array(
'title' => $this->l('Upload DB'),
'type' => 'file',
'name' => 'DB_<YourThings>_DATA'
),
),
'submit' => array('title' => $this->l('Save')),
),
);
}
public function initContent()
{
parent::initContent();
unset($_FILES);
}
public function postProcess()
{
$fileName = '<YourThings>Db.csv';
if (!file_exists(_PS_MODULE_DIR_ . '<YourModuleName>/upload/' . $fileName)) {
if (isset($_FILES['DB_<YourThings>_DATA'])) {
$tmpPath = $_FILES['DB_<YourThings>_DATA']["tmp_name"];
move_uploaded_file($tmpPath, _PS_MODULE_DIR_ . '<YourModuleName>/upload/' . $fileName);
$uploadCsv = file(_PS_MODULE_DIR_ . '<YourModuleName>/upload/' . $fileName, FILE_SKIP_EMPTY_LINES);
$Db = array_map("str_getcsv", $uploadCsv, array_fill(0, count($uploadCsv), ';'));
$keys = array_shift($Db);
foreach ($Db as $i => $row) {
$Db[$i] = array_combine($keys, $row);
}
print_r($Db);
}
} else {
$uploadCsv = file(_PS_MODULE_DIR_ . '<YourModuleName>/upload/' . $fileName, FILE_SKIP_EMPTY_LINES);
$Db = array_map("str_getcsv", $uploadCsv, array_fill(0, count($uploadCsv), ';'));
$keys = array_shift($Db);
foreach ($Db as $i => $row) {
$Db[$i] = array_combine($keys, $row);
}
print_r($Db);
}
unset($_FILES['DB_<YourThings>_DATA']);
}
}

Prestashop WebService API - save in database HTML rich text

I am developing a php manager for prestashop via webservice. I have a module created to keep notes about orders.
From the management program I have a form with TinyMCE. But I can't save the text when it has HTML tags
webService class in prestashop module
class sellerNotas extends ObjectModel {
public $id;
public $id_seller;
public $nota;
public static $definition = array(
'table' => 'seller_notas',
'primary' => 'id',
'fields' => array(
'id' => array('type' => self::TYPE_INT),
'id_seller' => array('type' => self::TYPE_INT),
'nota' =>array('type' => self::TYPE_HTML, 'lang' => false, 'validate' => 'isCleanHtml'),
)
);
protected $webserviceParameters = array();
}
MySQL TABLE
I have no problem saving plain text without labels, the problem is when the text has labels.
I have tried htmlentities with no correct results.
create note php function
Please make sure you have used CDATA for that HTML node so it not get break due to any any component
$node = dom_import_simplexml($resources ->nota);
$no = $node -> ownerDocument;
$node -> appendChild($no -> createCDATASection($nota));
$resources ->nota= $nota;
SOLVED WITH htmlentities PHP CODE:
static function nuevaNota($idVendedor, $nota, $tienda) {
try{
$webService = webService::webServiceTienda($tienda);
$opt = [
'resource' => 'seller_notas?schema=blank'
];
$xml = $webService->get($opt);
$resources = $xml->seller_notas->children();
$resources->id_seller = intval($idVendedor);
$resources->nota = htmlentities($nota);
var_dump( $resources->nota);
$opt = [
'resource' => 'seller_notas',
'postXml' => $xml->asXML(),
];
$createdXml = $webService->add($opt);
}
catch (PrestaShopWebserviceException $e){
webService::controlErroresTienda($e, $tienda);
}
}

NuSoap, XML was empty, couldn't parse

First, I have to say that I am totally new to WSDL-based Web Services using NuSOAP. I am trying to return an array of friends list from my soap server. Please find below my code listings as is:
Server:
//File includes omitted
function getFriendList($test = ''){
$results = array();
$results[] = array('name' => 'XXXXA1', 'surname' => 'XXXXA2');
$results[] = array('name' => 'XXXXXB1', 'surname' => 'XXXXB2');
$results[] = array('name' => 'XXXXXC1', 'surname' => 'XXXXC2');
return $results;
}
//Create server instance
$server = new soap_server();
//Configure our WSDL
$server->configureWSDL('server', 'urn:server');
//Add our Complex Type data type since we want to return an array
$server->wsdl->addComplexType(
'Friend',
'complexType',
'struct',
'all',
'',
array(
'name' => array('name' => 'name', 'type' => 'xsd:string'),
'surname' => array('name' => 'surname', 'type' => 'xsd:string')
)
);
//Register our array as a response
$server->wsdl->addComplexType(
'FriendArray',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref' => 'SOAP-ENC:arrayType', 'wsdl:arrayType' => 'tns:Friend[]')
),
'tns:Friend'
);
//Register the actual function that retuns the array but in the
//return n field specify the complex type of array we added onto the wsdl
$server->register('getFriendList',
array('test' => 'xsd:string'),
array('return' => 'tns:FriendArray'),
'urn:server',
'urn:server#getFriendList',
'document',
'encoded',
'Fetch a list of friends as an array. If you\'re not here sorry.'
);
//Serve the service
$server->service($HTTP_RAW_POST_DATA = (!isset($HTTP_RAW_POST_DATA)) ? $HTTP_RAW_POST_DATA : '');
With this, I hoped that I did everything correctly. I followed the standard procedure to make it work but in vein.
On the client side, I used the soap address url in wsdl and appended it with "?wsdl", so that it give me wsdl file dynamically.
example:
//Client call
$client = new nusoap_client("http://soapserver.dev/webroot/part_three/server.php?wsdl", true);
I have also taken labour of adding some whistles and bells on my client object as shown below:
$client->soap_defencoding = 'UTF-8';
$client->decode_utf8 = false;
This doesn't seem to help at all. I had experienced an issue earlier since my function accepts no parameter, where my service died because I didnt pass any parameter that speaks of inputs in my $client->call($name, $in, $out). I ended up providing an empty array and I got this error.
Could this be related to the rpc/document parameter types of the register function?
Even using the wsdl file which I saved from my server url, I got the same error.
Can somebody please help me out here? Please!

Prestashop error "invalid security token"

im creating a new module for prestashop 1.5.6 and im having some problems with it.
The module has to send sms to the costumers and it has to be an option of the back-Office menu.
I have created the module with the install and uninstall functions and added the tabs to the back-office menu, but im a newbie in prestashop so i don´t know how to make the AdminMyModuleController.php and when i try to click the tab of the module it says "INVALID SECURITY TOKEN", i don´t know how resolve this issue because i don´t know much of security.
If someone can add me on facebook or whatever to help me would be amazing.
Here is the code of the mymodule.php:
private function _createTab()
{
// Tab Raiz
$data = array(
'id_tab' => '',
'id_parent' => 0,
'class_name' => 'Empty',
'module' => 'mymodule',
'position' => 14, 'active' => 1
);
/* Insert the data to the tab table*/
$res = Db::getInstance()->insert('tab', $data);
//Get last insert id from db which will be the new tab id
$id_tabP = Db::getInstance()->Insert_ID();
//Define tab multi language data
$data_lang = array(
'id_tab' => $id_tabP,
'id_lang' => Configuration::get('PS_LANG_DEFAULT'),
'name' => 'SMS a clientes'
);
// Now insert the tab lang data
$res &= Db::getInstance()->insert('tab_lang', $data_lang);
// Tab Configuracion
$data = array(
'id_tab' => '',
'id_parent' => $id_tabP,
'class_name' => 'AdminMymodule',
'module' => 'mymodule',
'position' => 1, 'active' => 1
);
$res = Db::getInstance()->insert('tab', $data);
$id_tab = Db::getInstance()->Insert_ID();
$data_lang = array(
'id_tab' => $id_tab,
'id_lang' => Configuration::get('PS_LANG_DEFAULT'),
'name' => 'Configuracion'
);
$res &= Db::getInstance()->insert('tab_lang', $data_lang);
// Tab Enviar Sms
$data = array(
'id_tab' => '',
'id_parent' => $id_tabP,
'class_name' => 'AdminEnviar',
'module' => 'mymodule',
'position' => 1, 'active' => 1
);
$res = Db::getInstance()->insert('tab', $data);
$id_tab = Db::getInstance()->Insert_ID();
$data_lang = array(
'id_tab' => $id_tab,
'id_lang' => Configuration::get('PS_LANG_DEFAULT'),
'name' => 'Enviar SMS'
);
$res &= Db::getInstance()->insert('tab_lang', $data_lang);
return true;
}
Thanks
As Lliw said, you must use InstallModuleTab function.
private function installModuleTab($tabClass, $tabName, $idTabParent)
{
$pass = true;
$tab = new Tab();
$tab->name = $tabName;
$tab->class_name = $tabClass;
$tab->module = $this->name; // defined in __construct() function
$tab->id_parent = $idTabParent;
$pass = $tab->save();
return($pass);
}
You can put all in your Install function. For example for your first tab:
public function install()
{
if(!parent::install()
|| !$this->installModuleTab('Empty', array(1 => 'SMS a clientes'), $idTabParent = 0))
return false;
return true;
}
You can set languages with the following array:
array(1 => 'SMS a clientes', 2 => 'Language 2', 3 => 'Language 3')
Then you must create the AdminMyModuleController.php file
It's the wrong way to create a module tab. You should use this function in your install() :
$this->installModuleTab('AdminMyModule', array(1 => 'Attribute description'), $idTabParent = 9);
Then create an AdminMyModuleController.php in your module folder/controllers/admin/AdminMyModuleController.php
But you will need to set some function to see something displayed, i'll make a tutorial for that but until i do it, you can look in another admincontroller from the prestashop core and do the same.

How to create nodes using node_save?

I'm trying to migrate my current html site into drupal. I have over 80,000 pages I have to migrate so I thought instead of sitting infront of a computer for 50 years I would create a module. I was able to create a script that extracts the html from each directory and now I got to a road block where I need to create a node. I'm trying to create a new node using node_save(), but when node_save is executed, I get a PDOException error with everything I try. I'm passing in $node, which is an array which is then casted into an object.
PDOException: in field_sql_storage_field_storage_write() (line 424 of /srv/www/htdocs/modules/field/modules/field_sql_storage/field_sql_storage.module).
This is how we are currently creating the node, but it produces an error:
$node= array(
'uid' => $user->uid,
'name' => $user->name,
'type' => 'page',
'language' => LANGUAGE_NONE,
'title' => $html['title'],
'status' => 1,
'promote' => 0,
'sticky' => 0,
'created' => (int)REQUEST_TIME,
'revision' => 0,
'comment' => '1',
'menu' => array(
'enabled' => 0,
'mlid' => 0,
'module' => 'menu',
'hidden' => 0,
'has_children' => 0,
'customized' => 0,
'options' => array(),
'expanded' => 0,
'parent_depth_limit' => 8,
'link_title' => '',
'description' => '',
'parent' => 'main-menu:0',
'weight' => '0',
'plid' => '0',
'menu_name' => 'main-menu',
),
'path' => array(
'alias' => '',
'pid' => null,
'source' => null,
'language' => LANGUAGE_NONE,
'pathauto' => 1,
),
'nid' => null,
'vid' => null,
'changed' => '',
'additional_settings__active_tab' => 'edit-menu',
'log' => '',
'date' => '',
'submit' => 'Save',
'preview' => 'Preview',
'private' => 0,
'op' => 'Save',
'body' => array(LANGUAGE_NONE => array(
array(
'value' => $html['html'],
'summary' => $link,
'format' => 'full_html',
),
)),
'validated' => true,
);
node_save((object)$node);
// Small hack to link revisions to our test user.
db_update('node_revision')
->fields(array('uid' => $node->uid))
->condition('vid', $node->vid)
->execute();
Usually I create a bulkimport.php script in the document root to do this kind of thing.
Here is the code I use for Drupal 7:
<?php
define('DRUPAL_ROOT', getcwd());
include_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
function _create_node($title="", $body="", $language="und") {
$node = (object)array();
$node->uid = '1';
$node->name = 'admin';
$node->type = 'page';
$node->status = 1;
$node->promote = 0;
$node->sticky = 0;
$node->revision = 1;
$node->language = $language;
$node->title = $title;
$node->body[$language][0] = array(
'value' => $body,
'format' => 'full_html',
);
$node->teaser = '';
$node->log = 'Auto Imported Node';
node_submit($node);
node_save($node);
return $node;
} ### function _create_node
$sith = array(
'Darth Vader' => 'Master: Darth Sidious',
'Darth Sidious' => 'Master: Darth Plagous',
'Darth Maul' => 'Master: Darth Sidious',
'Darth Tyranous' => 'Master: Darth Sidious',
);
foreach($sith as $title=>$body) {
print "Creating Node. Title:[".$title."] \tBody:[".$body."] ";
$node = _create_node($title, $body);
print "\t... Created Node ID: [".$node->nid."]\n";
#print_r($node);
} ### foreach
I was getting exactly the same error as in your original post -
PDOException: in field_sql_storage_field_storage_write()
- etc.
I was already using the stdClass code style shown in the comments above.
The problem turned out to be the pound signs and accented chars in the string I was assigning to the Body field; the strings were coming from a Windows text file.
Converting the string to the Drupal target encoding (UTF-8) worked for me:
$cleaned_string = mb_convert_encoding($html['html'], "UTF-8", "Windows-1252");
$node->body[LANGUAGE_NONE][0]['value'] = $cleaned_string;
$node->body[LANGUAGE_NONE][0]['format'] = 'plain_text';
node_save($node);
Hope this helps someone.
are you using some CMS engine, or it is custom-written website?
in first case, look here http://drupal.org/documentation/migrate
I strongly recommend you to look at the given modules, they should help. Also, as an option, to migrate DB.
You don't need a lot of those blank fields. Also, you can cast the node as an object rather than an array converted to an object.
Your code should be able to be accomplished with this much shorter snippet:
$node = new stdClass();
$node->title = $html['title'];
$node->type = 'page';
$node->body['und'][0]['value'] = $html['html'];
node_save($node);
Also, there's a number of methods that have been developed to mass-import nodes into Drupal - I am a fan of the Feeds module (http://drupal.org/project/feeds). This may require writing a method of exporting your existing content to an intermediary format (CSV or XML), but it works reliably and you can re-import nodes to update content when required.

Categories