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;
Related
I am currently facing a strange behaviour on shopware 6.
What I need is to get order's documents informations when the order is refunded (invoice number & creditNote number).
Here is how I am getting the documentEntity in the orderRepository:
$criteria = new Criteria([$orderId]);
$criteria->addAssociation('lineItems');
$criteria->addAssociation('documents');
$orderObject = $this->orderRepository->search($criteria, $context);
$documents = $orderObject->first()->getDocuments();
Normal behaviour
When the order state is set to "refunded_partially", $documents perfectly contains what it should.
The problem
When the order state is set to "refunded", $documents is empty and I have no errors in logs.
Maybe I overlooked but I saw no differences between the dump I made on $orderObject when it's "refunded" and when it's "refunded_partially".
Does someone have a clue on how to manage this correctly?
AS this one is pretty tricky to do, I recommand you to use a specific event to work with documents. The event is triggered when a document is created for an order (invoice, credit note, etc.)
Example here
I'm using PHP-EWS (https://github.com/jamesiarmes/php-ews) inside a cakePHP application. The goal is to read E-Mails from a "Public Folder" from the exchange server.
The Problem is I can only read the first "Dimension" of public folders and can't find a way to get the subdirectorys.
The folder I have to read from is 4 levels deep.
$this->connect();
// start building the find folder request
$request = new FindFolderType();
$request->Traversal = FolderQueryTraversalType::SHALLOW;
$request->FolderShape = new FolderResponseShapeType();
$request->FolderShape->BaseShape = DefaultShapeNamesType::ALL_PROPERTIES;
// configure the view
$request->IndexedPageFolderView = new IndexedPageViewType();
$request->IndexedPageFolderView->BasePoint = 'Beginning';
$request->IndexedPageFolderView->Offset = 0;
// set the starting folder
$request->ParentFolderIds = new NonEmptyArrayOfBaseFolderIdsType();
$request->ParentFolderIds->DistinguishedFolderId = new DistinguishedFolderIdType();
$request->ParentFolderIds->DistinguishedFolderId->Id = DistinguishedFolderIdNameType::PUBLIC_FOLDERS_ROOT;
// request
$response = $this->ews->FindFolder($request);
If I change "Traversal" to DEEP I get the error .
DEEP TRAVERSAL queries are not allowed for public folders.
I also tried to change
$request->IndexedPageFolderView->BasePoint
To things like "end" "second", it didn't change anything so I could not figure out what it does and how to use it.
I can't get the subdirectory Folder id (for changing the start point) either because it gets never selected.
Thank you for your help.
Very good question. Unfortunately the library that you've chosen is out of date and unmaintained. I personally would suggest you use my more up to date one, garethp/php-ews.
I don't know if this is the best solution, but what I would suggest is to get the first level folder, then the second and so on. So if you know the directory structure of your folders, and it looked something like this
- Folder 1
- Subfolder 1
- Subfolder 2
- Subfolder 3 (Target)
- Folder 2
- Folder 3
Then first you'd get Folder 1, which would be a child of DistinguishedFolderIdNameType::PUBLIC_FOLDERS_ROOT. Then you would get Subfolder 1 which would be a child of Folder 1, then get Subfolder 2, then Subfolder 3. I can't advise you on how you would manage that with the library you're currently using, but with mine it would look something like
$api = MailAPI::withUsernameAndPassword($host, $username, $password);
$folder1 = $api->getFolderByDisplayName('Folder1', Enumeration\DistinguishedFolderIdNameType::PUBLICFOLDERSROOT);
$subFolder1 = $api->getFolderByDisplayName('Subfolder1', $folder1->getFolderId());
$subFolder2 = $api->getFolderByDisplayName('Subfolder2', $subfolder1->getFolderId());
$subFolder3 = $api->getFolderByDisplayName('Subfolder3', $subfolder2->getFolderId());
$api->setFolderId($subFolder3->getFolderId());
Obviously that's a lot of calls, so if you're using that folder ID often, I would save the FolderID to a database for quicker retrieval later
Anyone know if/where there is documentation for valid ObjectList filter arrays?
The project's entry on github has a tiny blurb on it directing me to the API documentation, but that also fails to have a comprehensive list, and a search on 'filters' talks about containers only, not the object themselves.
I have a list of videos, each in four different formats named the same thing (sans filetype). Using the php-opencloud API, I want to GET only one of those video formats (to grab the unique filename rather than all its different formats).
I figured using a filter is the way to go, but I can't find any solid documentation.
Someone has got to have done this before. Help a noob out?
Most of the links on this page are dead now. Here's a current link to the php-opencloud documentation, which includes an example of using a prefix to filter the objectList results:
http://docs.php-opencloud.com/en/latest/services/object-store/objects.html#list-objects-in-a-container
I didn't find documentation of this, but apparently when the Rackspace Cloud Files documentation mentions arguments in a query string, those translate to arguments in an objectList method call like this:
GET /v1/MossoCloudFS_0672d7fa-9f85-4a81-a3ab-adb66a880123/AppleType?limit=2&marker=grannysmith
equals
$container->objectList(array('limit'=>'2', 'marker'=>'grannysmith'));
As Glen's pointed out, there isn't support (at the moment) for the service to apply filters on objects. The only thing which you might be interested in is supplying a prefix, which allows you to refine the objects returned based on how the filenames start. So if you sent 'bobcatscuddling' as the prefix, you'd get back all associated video formats for that one recording.
Your only option, it seems, is to get back all objects and iterate over the collection:
use OpenCloud\Rackspace;
$connection = new Rackspace(RACKSPACE_US, array(
'username' => 'foo',
'apiKey' => 'bar'
));
$service = $connection->objectStore('cloudFiles', 'DFW', 'publicURL');
$container = $service->container('CONTAINER_NAME');
$processedObjects = array();
$marker = '';
while ($marker !== null) {
$objects = $container->objectList('marker' => $marker);
$total = $objects->count();
$count = 0;
while ($object = $objects->next()) {
// Extract the filename
$filename = pathinfo($object->name, PATHINFO_FILENAME);
// Make sure you only deal with the filename once (i.e. to ignore different extensions)
if (!in_array($processedObjects, $filename)) {
// You can do your DB check here...
// Stock the array
$processedObjects[] = $filename;
}
$count++;
$marker = ($count == $total) ? $object->name : null;
}
}
What you'll notice is that you're incrementing the marker and making a new request for each 10,000 objects. I haven't tested this, but it'll probably lead you in the right direction.
Unfortunately, the underlying API doesn't support filtering for objects in Swift/Cloud Files containers (cf. http://docs.rackspace.com/files/api/v1/cf-devguide/content/List_Objects-d1e1284.html). The $filter parameter is supported as part of the shared code, but it doesn't actually do anything with Cloud Files here.
I'll see if I can get the docs updated to reflect that.
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
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.