Adding a node programmatically - php

I am very new to Drupal. I need to develop a site using this CMS. I can understand creating content as an admin. But I would like to create content from code. For example I want to create articles in the backend programmatically without publishing them. So that site admin can review and publish them if he wants to. Tasks like these.Are there any references for programmers? About the structure of drupal code and where to write what things like that. Not videos I can't watch them in office.

Custom code in Drupal is generally done with the help of modules.
One way to familiarize yourself with the Drupal API could be to install the Examples.
In your Google searches, go for tutorials about writing your own modules.
THis being said, saving a node programmatically is fairly straightforward & I doubt you will have problems finding out how to do it.
Your main problem is to understand the "Drupal Way".
You can check excellent resources such as
- buildamodule.com
- drupalize.me

SOLUTION !
You can use below code to create a node programatically with drupal,
$node = new stdClass(); // Create a new node object
$node->type = 'YOUR_CONTENT_TYPE';
node_object_prepare($node); // Set some default values
$node->language = LANGUAGE_NONE;
$node->status = 0; // un-published
$node->uid = 'USER_ID';
$node->title = 'YOUR_TITLE';
$node->body['und'][0]['value'] = 'YOUR_DESCRIPTION';
$node->body['und'][0]['summary'] = 'YOUR_SHORT_DESCRIPTION';
$node->body['und'][0]['format'] = 'filtered_html';
$node = node_submit($node); //prepare node for saving
node_save($node); // save node

Related

How do I parse XML file from Wordpress for use in another CMS?

I'm finding that the resources for doing this are sparse. I'm using MODX as a CMS and want to take my existing blogs from Wordpress and use them in the new CMS. The resources are abundant for going from MODX to WP, but there's only one published method for WP to MODX, using the Articles method, which unfortunately doesn't work anymore. Whether that is because Articles hasn't been updated or the XML file from WP is incompatible.
Anyway, I'm left now with trying to do this the old fashioned way and I will not be able to bring each article over one-by-one. I want to learn how to take the exported XML file from WP and parse it into MODX, probably using PHP. But I'm unsure where to start.
Any suggestions would be helpful...yes I tried Google already. I'm not sure what to start with.
Thanks!
getFeed snippet code can be helpful for you here. You can take it's code, modify a bit and process WP feed items, something like the next:
if (!empty($url) && $modx->getService('rss', 'xmlrss.modRSSParser')) {
$rss = $modx->rss->parse($url);
if (!empty($rss) && isset($rss->items)) {
while (list($itemKey, $item) = each($rss->items)) {
foreach ($item as $k => $v) {
$item[$k] = str_replace(array('[',']'),array('[',']'),$item[$k]);
}
/// process rss items here
// f.e. add new modx resources
$newArticle = $this->modx->newObject('modResource'); //new article
$newArticle->set( 'template', ARTICLE_TEMPLATE_ID ); // replace ARTICLE_TEMPLATE_ID with actual article template id
$newArticle->set( 'pagetitle', $item['title'] ); // pagetitle
$newArticle->set( 'parent', ARTICLE_CONTAINTER_ID);
$newArticle->set( 'content', $item['description'] );
//add other valuable fields
if(!$newArticle->save()){
// modx error
}
}
}

How to clone ImageAd and ResponsiveDisplayAd

We need to update finalUrls of all the ads we have. We have several hundred ImageAd and ResponsiveDisplayAds and we don't want to lose the existing configuration and/or images. As Google doesn't allow us to update any property of a AdGroupAd apart from status, we will have to clone them using ADD operator.
While doing this we get several errors and all of them are related to ad.image. What's the correct/best way to go about these updates?
[AdError.IMAGE_ERROR # operations[0].operand.ad]
Firstly, I found out from little googling that adToCopyImageFrom is what I had to use in order to copy over image properties of an ad (ImageAd only!) in order to clone. So, if $currentAd is the AdGroupAd object containing your existing ImageAd and you are trying to create a new one $newAd and want to copy over images, here is what you can do (not sure if this is the best way but worked well for me!):
$newAd = new ImageAd();
$newAd = $ad->ad;
// Let Google do the image copying
// Remember $currentAd is a AdGroupAd and not an Ad
$newAd->adToCopyImageFrom = $currentAd->ad->id;
$newAd->id = null;
$newAd->image = null;
Similarly, for ResponsiveDisplayAd, here is what I did:
$newRespAd = new ResponsiveDisplayAd();
// Make sure you included MediaId while fetching
// $currentRespAd
$newRespAd = $currentRespAd->ad;
$newRespAd->id = null;

Listing items from a e-commerce site

I'm working on a script in php, that takes all the products URLs from an e-commerce site, for now I'm just using the function get_file_contents() and after I search for the keyword with preg_match_all() that anticipate the item url,now, my question is, can I use a more direct and efficent way to store all this link from a website and put they on my database?
I've recently created a crawler system for my client's project. Basically these are the steps i followed:
Project was based on PHP and it supports multiple type of document such a xml, json and html.
I've created a base product object with the properties i needed (title, image, price, link, category, source site)
For each web site, i'm using a parser which generally uses PhpDom library with DomXpath.
Basically, i find the product listing tag, and loop through the records and create a new product list object with products object inside it (step 2).
When parsing the web site finishes, i'm sending the whole list to my base action it checks if the product with that url is already exists if not it adds to db.
Also in my server, i'm running a cron where it checks all the product links and if the response returns 404 or 500 it adds a flag to product with 1. I'm also running an other cron which checks the links again with the flag 1. If it's still responding with error code, it removes the content from my database.
This is a sample parser code that i use. I hope it will help you through the process:
$content = file_get_contents($url);
libxml_use_internal_errors(true);
$oDom = new DomDocument;
$oDom->validateOnParse = false;
$res = $oDom->loadHTML($content);
libxml_clear_errors();
$oDom->preserveWhiteSpace = false;
$oXpath = new DOMXPath($oDom);
$productNode = $oXpath->query('//div[#class="ulist span4"]');
if($productNode){
$productsList = array();
foreach($productNode as $p){
$this->oProduct = new Products();
$productURL = $oXpath->query('div[#class="ures"]/div[#class="ures-cell"]/a', $p)->item(0);
$this->oProduct->url = $this->base.'/'.$productURL->getAttribute('href');
$this->oProduct->category = $categoryID;
$this->oProduct->productPeek = $peek;
$titleNode = $oXpath->query('div[#class="ubilgialan span12"]/div[#class="span12 uadi"]/a/span', $p)->item(0);
$this->oProduct->title = trim($titleNode->nodeValue);
$priceNode = $oXpath->query('div[#class="ubilgialan span12"]/div[#class="span8 ufytalan"]/div[#class="ufyt"]/span[#class="divdiscountprice"]/span', $p)->item(0);
$this->oProduct->price = trim($priceNode->nodeValue);
$imageNode = $oXpath->query('div[#class="ures"]/div[#class="ures-cell"]/a/img', $p)->item(0);
$this->oProduct->image = $this->base."/".$imageNode->getAttribute('src');
$productsList[] = $this->oProduct;
}
if(count($productsList) > 0){
return $productsList;
}
}

Drupal - fetch body text of a node via URL?

I'm trying to create a function to retrieve and display just the Body field of a Drupal node, based on a given URL.
Currently, I've extended the functionality of the standard Drupal RSS to do a detection method. This will happen if you enter the following url:
http://mysite.com/rss.xml/page=54
That last part is critical - it tells what node ID to load from. As far as code goes, I've modified the node_feed() function in /modules/node/node.module to do the following:
if (stristr($nids, 'page=') !== FALSE) {
$nid = substr($nids, stripos($nids, 'page=') + 5);
$result = NULL;
if ((string)(int)$nid === $nid) {
$result = db_result(db_query("SELECT `nid` FROM {node} WHERE `nid` = %s AND `type` = 'flashnode'", $nid));
}
if ($result) {
$item = node_load($result);
print($item->body);
}
exit;
}
While this works, we're worried about it for two reasons:
1) Do the results cache? This is a very heavy-load page that will be called a lot.
2) Is there an "official" way to do this? One that uses modules with caching, instead of a semi-hacky workaround?
Thanks in advance for any guidance.
-Tom
You should definitely not be hacking apart the RSS feed in order to create a URL that returns a node's body. You should create a very simple custom module: http://drupal.org/developing/modules
The Drupal module system is lets you set up a url so that something like /fetch_body/1234 calls the fetch_body() function with $nid=1234 as the parameter. As for caching, you have a lot of options in your custom module. The most obvious would be to use cache_get() and cache_set() to do simple caching on your own based on the node ID.
What version of Drupal are you using? I would highly recommend the book Pro Drupal Development, just make sure to get the edition that matches your drupal version.

How do I create a node from a cron job in drupal?

In a custom module for drupal 4.7 I hacked together a node object and passed it to node_save($node) to create nodes. This hack appears to no longer work in drupal 6. While I'm sure this hack could be fixed I'm curious if there is a standard solution to create nodes without a form. In this case the data is pulled in from a custom feed on another website.
The best practices method of making this happen is to utilize drupal_execute. drupal_execute will run standard validation and basic node operations so that things behave the way the system expects. drupal_execute has its quirks and is slightly less intuitive than simply a node_save, but, in Drupal 6, you can utilize drupal_execute in the following fashion.
$form_id = 'xxxx_node_form'; // where xxxx is the node type
$form_state = array();
$form_state['values']['type'] = 'xxxx'; // same as above
$form_state['values']['title'] = 'My Node Title';
// ... repeat for all fields that you need to save
// this is required to get node form submits to work correctly
$form_state['submit_handlers'] = array('node_form_submit');
$node = new stdClass();
// I don't believe anything is required here, though
// fields did seem to be required in D5
drupal_execute($form_id, $form_state, $node);
node_save() still works fine in Drupal 6; you'll need a couple of specific pieces of data in place to make it work.
$node = new stdClass();
$node->type = 'story';
$node->title = 'This is a title';
$node->body = 'This is the body.';
$node->teaser = 'This is the teaser.';
$node->uid = 1;
$node->status = 1;
$node->promote = 1;
node_save($node);
'Status' and 'Promote' are easy to overlook -- if you don't set those, the node will remain unpublished and unpromoted, and you'll only see if you go to the content administration screen.
I don't know of a standard API for creating a node pragmatically. But this is what I've gleaned from building a module that does what you're trying to do.
Make sure the important fields are set: uid, name, type, language, title, body, filter (see node_add() and node_form())
Pass the node through node_object_prepare() so other modules can add to the $node object.
One more answer I discovered was to use the example from the blogapi module in drupal core. The fact that it is in core gives me a bit more confidence that it will continue to work in future versions.
There are some good answers above, but in the specific example of turning an ingested feed item into a node, you could also take the approach of using the simplefeed module (http://wwww.drupal.org/project/simplefeed). This module uses the simplepie engine to ingest feeds and turns individual items from each feed into nodes. I realize that this doesn't specifically address the issue of creating nodes from cron, but it might be an easier solution to your problem overall.

Categories