How to Import xPath fields of XML to Pimcore DataDirector dataport raw data fields? - import

Pimcore has powerfull plugin DataDirector for import automation.
It proposes manual configuration of fields to import and their mapping to Pimcore fields https://www.youtube.com/watch?v=nyhKJTzTq-4&list=PL4-QRNfdsdKIfzQIP-c9hRruXf0r48fjt
It works fine if you have 10-50 fields.
How to import that configuration from some csv file whan you have 700+ fields?

There is no ability to import using interface of commandline DataDirector API.
I tried to request such functionality creation from vendor -- it costs.
I tried to edit it in MySQL but it is strictly coupled to other data, see: SELECT sourceconfig FROM plugin_pim_dataport;
Solution:
Each dataport can be exported and imported to JSON. This is our chance.
create sample dataport using your source XML
export it to sample.json
unserialize $json_a['plugin_pim_dataport']['sourceconfig'] and $json_a['plugin_pim_rawitemField'] containers
$string = file_get_contents(
"sample.json"
);
$json_a = json_decode($string, true);
$sourceConfig = $json_a['plugin_pim_dataport']['sourceconfig'];
$sourceConfig = unserialize($sourceConfig, ['allowed_classes' => false]);
$fieldsConfig = $json_a['plugin_pim_rawitemField'];
add new fields to them from any source e.g. CSV
while (($data = fgetcsv($handle, 1000, ",")) !== false) {
$row++;
$id = $max + 1 + $row;
$data = $this->addField($id, $data[0], $data[1]);
$sourceConfig['fields']['field_' . ($id + 1)] = $data['sourceConfig'];
$fieldsConfig[$id] = $data['fieldsConfig'];
}
public function addField(
$id,
$name = 'ObjectBrick/Field',
$xpath = '//*[.//MainContainer = "systeme"]//*[.//Description = "SomeAttribute"]/anyPath/SampleContainer'
) {
$res = [];
$res['fieldsConfig'] = [
"dataportId" => "1",
"fieldNo" => $id + 1,
"name" => $name,
"priority" => $id
];
$res['sourceConfig'] = [
'xpath' => $xpath,
'multiValues' => false,
];
return $res;
}
serialize, save to JSON, import to your dataport.

Related

How to prevent SQL injection in PhalconPHP when using sql in model?

Let's say I am building a search that finds all the teacher and got an input where the user can put in the search term. I tried reading the phalcon documentation but I only see things like binding parameters. I read the other thread about needing prepare statements do I need that in Phalcon as well?
And my function in the model would be something like this:
public function findTeachers($q, $userId, $isUser, $page, $limit, $sort)
{
$sql = 'SELECT id FROM tags WHERE name LIKE "%' . $q . '%"';
$result = new Resultset(null, $this,
$this->getReadConnection()->query($sql, array()));
$tagResult = $result->toArray();
$tagList = array();
foreach ($tagResult as $key => $value) {
$tagList[] = $value['id'];
....
}
}
My question is for the Phalcon framework is there any settings or formats I should code for this line $sql = 'SELECT id FROM tags WHERE name LIKE "%' . $q . '%"';
And also any general recommendation for preventing SQL Injection in PhalconPHP controllers and index would be appreciated.
For reference:
My controller:
public function searchAction()
{
$this->view->disable();
$q = $this->request->get("q");
$sort = $this->request->get("sort");
$searchUserModel = new SearchUsers();
$loginUser = $this->component->user->getSessionUser();
if (!$loginUser) {
$loginUser = new stdClass;
$loginUser->id = '';
}
$page = $this->request->get("page");
$limit = 2;
if (!$page){
$page = 1;
}
$list = $searchUserModel->findTeachers($q, $loginUser->id, ($loginUser->id)?true:false, $page, $limit, $sort);
if ($list){
$list['status'] = true;
}
echo json_encode($list);
}
My Ajax:
function(cb){
$.ajax({
url: '/search/search?q=' + mapObject.q + '&sort=<?php echo $sort;?>' + '&page=' + mapObject.page,
data:{},
success: function(res) {
//console.log(res);
var result = JSON.parse(res);
if (!result.status){
return cb(null, result.list);
}else{
return cb(null, []);
}
},
error: function(xhr, ajaxOptions, thrownError) {
cb(null, []);
}
});
with q being the user's search term.
You should bind the query parameter to avoid an SQL injection. From what I can remember Phalcon can be a bit funny with putting the '%' wildcard in the conditions value so I put them in the bind.
This would be better than just filtering the query.
$tags = Tags::find([
'conditions' => 'name LIKE :name:',
'bind' => [
'name' => "%" . $q . "%"
]
])
Phalcon\Filter is helpful when interacting with the database.
In your controller you can say, remove everything except letters and numbers from $q.
$q = $this->request->get("q");
$q = $this->filter->sanitize($q, 'alphanum');
The shortest way for requests:
$q = $this->request->get('q', 'alphanum');

How to inserting data from install.xml file into mysql database in moodle

In moodle site (use moodle Version 2.6.3), I have generated install.xml file by XMLDB editor, but it's use only to create table in database during plugin installation. I want to insert some default rows in the table also.
Any body can help me how to edit in install.xml file for insert data
To add data after an install, create a file called yourplugin/db/install.php with
UPDATE: added xml parser
defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir . '/xmlize.php');
function xmldb_yourpluginname_install() {
global $CFG, $OUTPUT, $DB;
// Your add data code here.
$xmltext = file_get_contents('import.xml');
$records = parse_xml($xmltext, 'records', 'record');
foreach ($records as $record) {
$DB->insert_record('yourtablename', $record);
}
}
/**
* Converts XML text into an array of stdclass objects.
*
* #param type $text - xmltext
* #param type $elementnames - plural name of elements
* #param type $elementname - name of element
* #return array|boolean - array of record objects
*/
function parse_xml($text, $elementnames, $elementname) {
// Seems that xmlize needs a lot of memory.
ini_set('memory_limit', '256M');
// Ensure content is UTF-8.
$content = xmlize($text, 1, 'UTF-8');
$records = array();
if (!empty($content[$elementnames]['#'][$elementname])) {
$rows = $content[$elementnames]['#'][$elementname];
foreach ($rows as $row) {
$fields = $row['#'];
$row = new stdClass();
foreach ($fields as $fieldname => $fieldvalue) {
$row->$fieldname = $fieldvalue[0]['#'];
}
$records[] = $row;
}
return $records;
}
return false;
}

how to query eXist using XPath?

I decided to use eXist as a database for an application that I am writing in Perl and
I am experimenting with it. The problem is that I have stored a .xml document with the following structure
<foo-bar00>
<perfdata datum="GigabitEthernet3_0_18">
<cli cmd="whatsup" detail="GigabitEthernet3/0/18" find="" given="">
<input_rate>3</input_rate>
<output_rate>3</output_rate>
</cli>
</perfdata>
<timeline>2011-5-23T11:15:33</timeline>
</foo-bar00>
and it is located in the "/db/LAB/foo-bar00/2011/5/23/11_15_33.xml" collection.
I can successfully query it, like
my $xquery = 'doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")' ;
or $xquery can be equal to
= doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")/foo-bar00/perfdata/cli/data(output_rate)
or
= doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")/foo-bar00/data(timeline)
my ($rc1, $set) = $eXist->executeQuery($xquery) ;
my ($rc2, $count) = $eXist->numberOfResults($set) ;
my ($rc3, #data) = $eXist->retrieveResults($set) ;
$eXist->releaseResultSet($set) ;
print Dumper(#data) ;
And the result is :
$VAR1 = {
'hitCount' => 1,
'foo-bar00' => {
'perfdata' => {
'cli' => {
'given' => '',
'detail' => 'GigabitEthernet3/0/18',
'input_rate' => '3',
'cmd' => 'whatsup',
'output_rate' => '3',
'find' => ''
},
'datum' => 'GigabitEthernet3_0_18'
},
'timeline' => '2011-5-23T11:15:33'
}
};
---> Given that I know the xml document that I want to retrieve info from.
---> Given that I want to retrieve the timeline information.
When I am writing :
my $db_xml_doc = "/db/LAB/foo-bar00/2011/5/23/11_15_33.xml" ;
my ($db_rc, $db_datum) = $eXist->queryXPath("/foo-bar00/timeline", $db_xml_doc, "") ;
print Dumper($db_datum) ;
The result is :
$VAR1 = {
'hash' => 1717362942,
'id' => 3,
'results' => [
{
'node_id' => '1.2',
'document' => '/db/LAB/foo-bar00/2011/5/23/11_15_33.xml'
}
]
};
The question is : How can I retrieve the "timeline" info ? Seems that the "node_id" variable (=1.2) can points to the "timeline" info, but how can I use it ?
Thank you.
use XML::LibXML qw( );
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file('a.xml');
my $root = $doc->documentElement();
my ($timeline) = $root->findnodes('timeline');
if ($timeline) {
print("Exists: ", $timeline->textContent(), "\n");
}
or
my ($timeline) = $root->findnodes('timeline/text()');
if ($timeline) {
print("Exists: ", $timeline->getValue(), "\n");
}
I could have used /foo-bar00/timeline instead of timeline, but I didn't see the need.
Don't know if you're still interested, but you could either retrieve the doc as DOM and apply an xquery to the DOM, or, probably better, only pull out the info you want in the query that you submit to the server.
Something like this:
for $p in doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")//output_rate
return
<vlaue>$p</value>

Write config in Zend Framework with APPLICATION_PATH

For an application I'd like to create some kind of setup-steps. In one of the steps the database configuration is written to the application.ini file. This all works, but something very strange happens: All the paths to the directories (library, layout, ...) are changed from paths with APPLICATION_PATH . to full paths. As you can imagine, this isn't very systemfriendly. Any idea how I can prevent that?
I update the application.ini with this code:
# read existing configuration
$config = new Zend_Config_Ini(
$location,
null,
array('skipExtends' => true,
'allowModifications' => true));
# add new values
$config->production->doctrine->connection = array();
$config->production->doctrine->connection->host = $data['server'];
$config->production->doctrine->connection->user = $data['username'];
$config->production->doctrine->connection->password = $data['password'];
$config->production->doctrine->connection->database = $data['database'];
# write new configuration
$writer = new Zend_Config_Writer_Ini(
array(
'config' => $config,
'filename' => $location));
$writer->write();
Since Zend_Config_Ini uses the default ini scanning mode (INI_SCANNER_NORMAL), it will parse all options and replace constants with their respective values. What you could do, is call parse_ini_file directly, using the INI_SCANNER_RAW mode, so the options aren't parsed.
ie. use
$config = parse_ini_file('/path/to/your.ini', TRUE, INI_SCANNER_RAW);
You will get an associative array that you can manipulate as you see fit, and afterwards you can write that back with the following snippet (from the comments):
function write_ini_file($assoc_arr, $path, $has_sections=FALSE) {
$content = "";
if ($has_sections) {
foreach ($assoc_arr as $key=>$elem) {
$content .= "[".$key."]\n";
foreach ($elem as $key2=>$elem2) {
if(is_array($elem2))
{
for($i=0;$i<count($elem2);$i++)
{
$content .= $key2."[] = ".$elem2[$i]."\n";
}
}
else if($elem2=="") $content .= $key2." = \n";
else $content .= $key2." = ".$elem2."\n";
}
}
}
else {
foreach ($assoc_arr as $key=>$elem) {
if(is_array($elem))
{
for($i=0;$i<count($elem);$i++)
{
$content .= $key2."[] = ".$elem[$i]."\n";
}
}
else if($elem=="") $content .= $key2." = \n";
else $content .= $key2." = ".$elem."\n";
}
}
if (!$handle = fopen($path, 'w')) {
return false;
}
if (!fwrite($handle, $content)) {
return false;
}
fclose($handle);
return true;
}
ie. call it with :
write_ini_file($config, '/path/to/your.ini', TRUE);
after manipulating the $config array. Just make sure you add double quotes to the option values where needed...
Or alternatively - instead of using that function - you could try writing it back using Zend_Config_Writer_Ini, after converting the array back to a Zend_Config object, I guess that should work as well...
I'm guess you could iterate over the values, checking for a match between the value of APPLICATION_PATH, and replacing it with string literal APPLICATION_PATH.
That is if you know that APPLICATION_PATH contains the string '/home/david/apps/myapp/application' and you find a config value '/home/david/apps/myapp/application/views/helpers', then you do some kind of replacement of the leading string '/home/david/apps/myapp/application' with the string 'APPLICATION_PATH', ending up with 'APPLICATION_PATH "/views/helpers"'.
Kind of a kludge, but something like that might work.
This is a long shot - but have you tried running your Zend_Config_Writer_Ini code while the APPLICATION_PATH constant is not defined? It should interpret it as the literal string 'APPLICATION_PATH' and could possibly work.

Example Perl code for generating XML from XSD using XML::Compile

Can anybody please show me an example for generating XML from XSD using XML::Compile::Schema.
I am trying to post my script which I am trying along with the XSD but I am not able to do that. so I am looking for a any sample example.
I wrote a tutorial on this a while ago: http://blogs.perl.org/users/brian_e_lozier/2011/10/using-xmlcompile-to-output-xsd-compliant-xml.html
In short words, you'll need to do:
Convert the XSD format to Perl hash structure
Construct this Hash, fill in the data
Convert the Hash to XML
Packages required:
XML::Compile::Schema
XML::LibXML::Document
Following code create a Perl structure from XSD definition.
use XML::Compile::Schema;
use Data::Dumper;
my $filename = $ARGV[0] || "";
if(!$filename){
warn "Please provide the WSDL definition file.";
exit 10;
}
my $schema = XML::Compile::Schema->new($filename);
my $hash;
print Dumper $schema->template('PERL' => 'Application');
Then the Perl data structure created by this program looks like:
{
MakeName =>
{
UniqueID => "anything",
_ => "example", },
MakeDetails =>
{
Name =>
{
UniqueID => "anything",
_ => "example", },
},
};
So the rest of your job will create the same structure in your program, fill in the content like:
my $hash = {
MakeName => {
UniqueID => 'xxxx',
_ => 'Name of the Make',
},
OtherFields => foo_bar_get_other_hash(),
};
....
## breathtaking moment, create the XML from this $hash
my $schema = XML::Compile::Schema->new("/opt/data/your.xsd");
my $doc = XML::LibXML::Document->new();
my $writer = $schema->compile(WRITER => 'Application');
my $xml;
## Create $xml in the memory based on the Schema and your $hash
eval{ $xml = $writer->($doc, $hash);};
if($#){
# Useful if the format is invalid against the Schema definition
# Or if there are other errors may occurs
$err_msg = $#->{message}->toString();
return ("", $err_msg);
}
## If you want save this $xml to file, convert it to string format first
$doc->setDocumentElement($xml);
my $ori_content = $doc->toString(1);
## Now $ori_content holds the full XML content.