Forums / Developer / Ajax attribute edition - help on transaction error ???

Ajax attribute edition - help on transaction error ???

Author Message

H-Works Agency

Thursday 26 February 2009 8:13:45 am

Hello,

I am using ajax to allow seemless content object attribute update.

My question is : "Is my technique the right one ?" Sometime it corrupt my database table and i don't know why. I have transaction errors that led one time to a total database restoration.

The problem i face is that sometimes it works and sometime it leed to a transaction error...which is very disturbing.

Here is the code in the page targeted by my ajax function :

<?php

$http = eZHTTPTool::instance();

// Execute code only if everybody is here
if ( $http->hasVariable( 'language' ) &&
     $http->hasVariable( 'contentObjectID' ) &&
     $http->hasVariable( 'attributeIdentifier' ) &&
     $http->hasVariable( 'value' )
   )
{
	$response = '';
	//$response = 'Work in progress';

	$value_new = htmlspecialchars(urldecode($http->variable( 'value' )));
	$contentObjectID = $http->variable( 'contentObjectID' );
	$attribute_identifier = $http->variable( 'attributeIdentifier' );
	$languageCode = $http->variable( 'language' );

	// Verify that language code exists in our siteaccess
	$language = eZContentLanguage::fetchByLocale( $languageCode );

	// Fetch object to update
	$contentObject = eZContentObject::fetch($contentObjectID);

	// Check if object exists && if new value is non empty && if language exists
	if($contentObject && $language)
	//if($contentObject && $language && $value_new != '')
	{
		// Retrieve attribute - returns an array
		$contentObjectAttributes = $contentObject->fetchAttributesByIdentifier(array($attribute_identifier), $contentObject->attribute('current_version'), $languageCode);

		//print_r($contentObject);

		// We check that this attribute exists
		if($contentObjectAttributes)
		{
			// Only one attribute so we have only one loop
			foreach($contentObjectAttributes as $key => $contentObjectAttribute)
			{
				$value_old = $contentObjectAttribute->toString();
			}

			// By default we return old value
			$response = $value_old;

			//echo $value_old, " : ",  $value_new,"<br>\n";

			// Create a new version & update attribute only if value has changed
			if($value_old != $value_new)
			{
				// CreateNewVersion is transaction unsafe
				$db = eZDB::instance();

				// Start to record
				$db->begin();

				// Get last version of those attributes
				$newVersion = $contentObject->createNewVersion( false, true, $languageCode, false );

				if($newVersion)
				{
					// It seems that "store" method, in function of datatype, implement his own begin/commit
					$new_version_id = $newVersion->attribute( "version" );

					$newContentObjectAttributes = $contentObject->fetchAttributesByIdentifier(array($attribute_identifier), $new_version_id, $languageCode);
					foreach($newContentObjectAttributes as $key => $newContentObjectAttribute)
					{
						$newContentObjectAttribute->fromString($value_new);
						$newContentObjectAttribute->store();
					}

					// Publish object new version
					$operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $contentObjectID,
														     'version' => $new_version_id ) );
					// If result is made then commit all
					if($operationResult['status'])
					{
						// If new version was created then return new value
						$response = $value_new;
					}
				}

				$db->commit();
			}
			else
			{
				//$response = 'No change';
			}
		}
		else
		{
			//$response = 'Attribute not found';
		}
	}
	else
	{
		//$response = 'No object, or language not found, or empty new value';
	}

	header( $_SERVER['SERVER_PROTOCOL'] . ' 200 ' );

	header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + MAX_AGE ) . ' GMT' );
	header( 'Cache-Control: cache, max-age=' . MAX_AGE . ', post-check=' . MAX_AGE . ', pre-check=' . MAX_AGE );
	header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s', $node->ModifiedSubNode ) . ' GMT' );
	header( 'Pragma: cache' );
	header( 'Content-Type: text/html' );
	header( 'Content-Length: '.strlen( $response) );

	echo $response;
}
else
{
	header( $_SERVER['SERVER_PROTOCOL'] . ' 404 ' );
}

eZExecution::cleanExit();

?>

EZP is Great

kracker (the)

Wednesday 15 July 2009 1:45:55 am

Sorry,

I didn't take time to read your code. It looks very clean at a glance and you have lots of eZp history under your own belt Martin.

But something new has been in the works which i've heard amazing reports via irc about from other developers working with eZ.

Checkout this new upcoming solution for creating content objects which is available now and by all reports i've heard it just simply -works-.

<i>http://pubsvn.ez.no/nextgen/trunk/tests/toolkit/extras/kernelwrapper/README
http://pubsvn.ez.no/nextgen/trunk/tests/toolkit/extras/kernelwrapper</i>

I hear this is functional right now, available for testing as separate and in the future will be integrated further (or something, possibly re-branded or something, not certain)

Happy hacking ...

Cheers,
<i>//kracker

Theme: Drake - Best I Ever Had ... (From me to eZ Publish)</i>

Member since: 2001.07.13 || http://ezpedia.se7enx.com/

H-Works Agency

Wednesday 15 July 2009 1:53:13 am

Uhm interesting i am gonna check this out.

Thanx !

EZP is Great

Matthieu Sévère

Wednesday 15 July 2009 3:51:39 am

Yes it seems very interesting but only for creating new content ... It seems that you can load a node and manipulate it, but it's a good start !

--
eZ certified developer: http://ez.no/certification/verify/346216

H-Works Agency

Wednesday 15 July 2009 4:24:07 am

The problem on this topic is, like often in ezp dev, the lack of documentation of the API.

- How to create an object with php ?
- How to modify an object attribute in the current version ?
- How to modify an object attribute and create a new version ?
- How to compare object versions ?

...etc

For now the response to those questions is "digg the code in /kernel & /lib and try".

At the end it usually works but first it dramatically impact developpement time and thus ezpublish adoption and second - without directives - we are never shure of using the right technique/function/class.

EZP is Great