remove an Image programmatically in ezpublish - php

I have an Object in ezPublish which has an image attribute.
this attribute has an image as value that I want to remove it programmatically in PHP. ( the image value and not attribute itself )
any idea how to do it ?

For versions of eZ Publish (Legacy) prior to Oct 15, 2013, or git tag, 'v2014.03.1' including eZ Publish 4.7 the 'deleteStoredObjectAttribute' method -requires- a non-null second argument value be passed in versions of eZ Publish Legacy before the following commit:
See: https://github.com/ezsystems/ezpublish-legacy/commit/61aaa002c00ccfb86b3e02856b319f54b3405ef8
This includes eZ Publish 4.7 and thus the question author's specific use case. Which is why this answer is more accurate than all others.
Without this second non-null parameter, the aliases image files would be deleted from the filesystem but ... the image aliases information (alias references, meta data, etc) would still exist with the content object attribute content (database storage xml).
Without the second non-parameter the image would appear as still partially existing in the content object but the image preview, (IE: usage of the image path, meta data by the system) would display a broken image and thus then represent a corrupt / incomplete copy of the original content object attribute content.
For maximum Backwards Compatibility, it's best to always pass a non-null second parameter since versions of eZ Publish Legacy beyond 10/15/2013 do not even use the second parameter in any way.
The following is a complete example of the source code required to remove a content object image attribute content (and remove the related meta-data and image file from disk) the best way possible for nearly any version of eZ Publish Legacy.
// The following two variables are filled with dummy values.
// You will need to change the contents of these variables to match
// your actual use case identifiers (Content Object ID / Class Attribute Identifier)
$objectID = 42;
$objectImageAttributeIdentifier = 'profile_image';
$object = eZContentObject::fetch( $objectID );
$objectID = $object->attribute( 'id' );
$objectCurrentVersion = $object->attribute( 'current_version' );
$objectDataMap = $object->attribute( 'data_map' );
if ( isset( $objectDataMap[ $objectImageAttributeIdentifier ] ) )
{
$objectImageAttribute = $objectDataMap[ $objectImageAttributeIdentifier ];
if ( $objectImageAttribute->attribute( 'has_content' ) )
{
$objectImageDataType = $objectImageAttribute->dataType();
$objectImageDataType->deleteStoredObjectAttribute( $objectImageAttribute, $objectCurrentVersion );
eZContentCacheManager::clearContentCacheIfNeeded( $objectID );
}
}

According to eZImageType::customObjectAttributeHTTPAction(), you should use eZImageType::deleteStoredObjectAttribute().
The method's implementation shows how it is done internally. The method won't delete the attribute itself, just the external data (image, aliases, set the xml to empty).

Related

Wordpress: retrive an array with all post galleries images inside attachment.php

I'm building a custom gallery slider for a Wordpress theme and I have an architecture problem:
While I'm in the post template (single.php) I can easily retrieve an array with all post's galleries images via this code
$galleries = get_post_galleries( $post, false);
(BTW: False parameter is to have theirs url instead of the images themselves)
but when I click on a specific gallery's image, and I'm redirected to the attachment template (attachment.php), then it's impossible to have that same array.
I tried with:
$galleries = get_post_galleries( $post->post_parent, false);
but this doesn't work properly. Indeed if I build a gallery with some pictures which were originally attached to another post (a older one, for example), the post_parent parameter will refer to that old post, instead of the one which redirected me to the attachment template.
Well, this is a problem because my slider script is loaded in the attachement.php and it can't handle the right array of pictures.
I can't trigger it while in single.php because the slideshow start after clicking on a gallery image.
(For the moment I discard the idea of making a more complex script that avoid the loading of attachment.php tempalte).
I'm looking for a workaround to retrive in PHP the right array while in attachment template.
I managed to accomplish that in this way, inside the loop, in attachment.php:
// switch to the parent post, the one holding the [gallery] shortcode(s)
$post = get_post( wp_get_post_parent_id( get_the_ID( ) ), OBJECT );
setup_postdata( $post );
// get the galleries
$galleries = get_post_galleries( $post, false );
// VERY IMPORTANT: restore the original post (the attachment)
wp_reset_postdata( );
Personal note: I think the bug resides in the chain of calls:
get_post_galleries, do_shortcode_tag, gallery_shortcode
not transmitting the post ID parameter correctly so that at a certain point, the attachment ID is used instead of the one supplied by the user in the first get_post_galleries call.

Reading node field values in module code using Drupal 6

I have created a custom module and am using hook_block to programmatically create some blocks.
My question is how can I access field values including CCK fields for the current node within my module?
I basically want to get a value from a CCK field and use the value when building my block for that page.
Getting at the current node is an awkward pain in the posterior. Standard practice is to do something like this:
if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == '') {
$node = node_load(arg(1));
// Collect output.
}
arg() pulls elements out of the Drupal path. Since all nodes (regardless of what a path alias might show you) appears at node/#, by checking for 'node' and that the second element is a number, you are fairly well guaranteed to have your hands on a node. Checking the third path element allows you to avoid processing on the node edit form and other pages that hang off a specific node.
CCK Values are loaded into the node, and usually look something like this:
// Text field. Structure also works for number fields.
$text = $node->field_my_text_field[0]['value']
// Node Reference field.
$nref = $node->field_my_nref_field[0]['nid']
// User Reference field.
$uref = $node->field_my_uref_field[0]['uid']
The "0" array element specifies the delta of the field. Any given field can actually process multiple values, and the array structure in CCK assumes this possibility even if you restrict the field to a single value.
In Drupal 6 there is a built-in Drupal function to get the node object.
if ($node = menu_get_object()) {
…
}
Read more here http://api.drupal.org/api/function/menu_get_item/6.

Difference between hook_node_type() and hook_nodeapi()

I'm trying to understand the difference between hook_node_type and hook_nodeapi
I've tried to use hook_node_type with the story node and a simple dsm but got nothing.
function mymod_node_story($op, $info){
dsm($info);
}
hook_node_type is made to hook into when a node type is changed. Fx if you want to allow comments on node type story etc.
hook_nodeapi is used to be able to hook into the different processes that can happen to an actual node, like when a node is saved, when it's being viewed etc.
There's not a hook for specific nodes, but instead you usually do something like this.
function module_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
if ($node->type == 'story') {
switch ($op) {
case 'load':
...
}
}
}
hook_node_type() is invoked each time a content type is deleted, or renamed. The purpose of the hook is to rename the Drupal variables used for the content type (which is automatically done for any form field included in the content type edit form, from node_type_form_submit()), or to delete the Drupal variables containing values for the content type that has been deleted.
hook_nodeapi() is invoked for each node when it's loaded from the database, the node edit form is shown, the node is visualized, when the node is being indexed from the search module, when a RSS feed, or the node is saved. A module should implement hook_nodeapi() to alter nodes for content types implemented by other modules.

Drupal - How to update a CCK NodeReference field programmatically?

I'm trying to create a node (B type) & assign it to a A type node's CCK nodereference field using node_save() method.
$node_type_A = node_load($some_nid);
$node_type_A->field_type_B_node_ref[]['nid'] = $node_type_B_nid;
$node_type_A = node_submit($node_type_A);
node_save($node_type_A);
As the result, a new B type node will be created, but no reference will be assigned to the A type node. any help would be appreciated.
GApple is right, the format is correct, but there are couple of things that you might want to care about.
Delta Value
First you need to know the delta value of the latest node reference attached to $node_type_A, the delta is actually a partial index, when combined with vid field of the $node_type_A, they become the index for node reference table in the database. In other words, its a count for $node_type_B which are referenced in $node_type_A, ok?
GApple is right again, you have to exactly say where to add the new reference. When you got that delta value you can exactly say where to append (delta+1) the new reference. Here it is:
function get_current_delta($node_vid){
return db_result(db_query("SELECT delta FROM {content_field_type_A_node_ref}
WHERE vid = '%d'
ORDER BY delta DESC
LIMIT 1", $node_vid));
}
Adding the new reference
We got delta! so we can attach the new $node_type_B node to our $node_type_A node:
// Loading type_A node.
$node_type_A = node_load($some_nid);
// Getting current delta value.
$current_delta = get_current_delta($node_type_A->vid);
// "Appending" a node reference based on delta.
$node_type_A->field_type_B_node_ref += array($current_delta + 1 => array('nid' => $node_type_B_nid));
Resaving the updated node
Optionally call node_submit() to populate some essential fields in the node object and save it by utilizing node_save(). After all, you need to call content_insert() to make the node completely saved asidelong with its CCK fields:
// Resaving the updated node.
$node_type_A = node_submit($node_type_A);
node_save($node_type_A);
content_insert($node_type_A);
Flushing the content cache
Probably the most important part, this was killin' me for couple of days. CCK has a cache table in the database called cache_content (take a look at its structure), after resaving the updated node, you will notice that nothing has changed in the $node_type_A theme output even though that the tables are updated. We have to remove a record from that content cache table, this will force Drupal to show the latest snapshot of the data. You can define the following as a function:
db_query("DELETE FROM {cache_content} WHERE cid = '%s'", 'content:' . $node_type_A->nid . ':' . $node_type_A->vid);
Hope it helps ;)
I just checked one of my own modules that does something similar for the object format, and $node_type_A->field_type_B_node_ref[]['nid'] should be correct.
One thing to check for is that when you load the node, CCK may pre-populate the node reference array with an empty value. If you have configured the field to only allow one value, by using the array append operator (field_type_B_node_ref[]) it will create a second entry that will be ignored (field_type_B_node_ref[1]), instead of overwriting the existing value (field_type_B_node_ref[0]). Try explicitly specifying the array key if possible.
Great post, but one correction: don't flush cache entries by manually querying the DB. In the event someone is using memcache or any other external cache it's going to fail.
cache_clear_all() is your friend for clearing.
Suggested code, direct from the CCK module:
cache_clear_all('content:'. $node_type_A->nid .':'. $node_type_A->vid, content_cache_tablename());
I show CCK storing node references as $node->field_node_reference[0]['items'][0]['nid'], not $node->field_node_reference[0]['nid']. Have you tried mimicking that?
"Flushing the content cache" This works for me, especially if you get a data from node_load()

Drupal: replacing field value in View

I have Drupal 5 View (must be "Views 1" so), which contains Event_StartTime field, which shows up normally for the fields that have a real date inside. But I also have a number of records with Event_StartTime field value like Dec 31 1969 - 8:00pm which looks bad in view and I need to replace them with some custom label, like "No Date Available".
Can I somehow inject this condition (if value = x show value y) into view?
Even when I print in "No Date Available" into SQL, the view will show empty field.
To sum up, the general problem is that View fields are kind of limiting, and sometimes you just need to replace some field value, but it's either "date or nothing" or "node-reference id or nothing".
P.S. The situation might be a bit complicated because I use "Bonus: Views Export" module which makes my view return CSV data.
I'm not really familiar with Views1 anymore, but I think you have at least two options:
At the theming level - you could override the field template and put a check for the particular date value in there, replacing it when found. Of course this check would depend on the formatting of the dates, so if you ever change that, you'd need to adjust the check as well.
At the view generation level - you could execute the view 'manually' from code and inspect the views object right after instantiation and/or after execution, but before rendering (See her for an example of manipulationg the view object in Views2). You could manipulate the result property after execution, but before rendering, or you might be able to put a pre-render callback in there right after instantiation (but I'm not sure if this is already possible in Views1).
Building off of Henrik's comment, theming seems to me to be the best place to do this. You would need to add a function to your template.php file to override that specific view. See the Views 1 theming documentation. Based on this documentation, you create a function with the name of your view of the form
function THEMENAME_view_view_VIEWNAME($view, $type, $nodes, $level = NULL, $args = NULL)
to theme the whole view. $nodes is an array of partially-loaded node objects that are included in your view. You can load each node and check the values of the Event_StartTime field with something like this:
foreach ($nodes as $id => $node) {
$temp_node = node_load($node->nid);
//now check value of Event_StartTime assuming that is what you named the field
if ($temp_node->Event_StartTime === 'Dec 31 1969 - 8:00pm') {
$temp_node->Event_StartTime = 'No Date Available';
}
//output the fields of your view . . .
}
I only showed how to check the value of the Event\_StartTime field, and I am not sure what the actual value is. Dec 31 1969 is before the dates returned by the time() function, so if this does not work you might want to check if Event_StartTime === '', which may be true if the event field is just left empty. You will still have to theme the rest of your fields and output them as HTML, which might be too much of a pain just to change the output of one field. You can also override the output of individual fields. I have not done this so I couldn't walk you through it, but the link I gave above has some documentation on overriding field theming functions.

Categories