Hi everyone,
When i use macro to save submissions of "admin/build/modules" it uses stdclass object for saving parameters values (as u can see in the attached file). and after i try to import it , it show me below error?

Fatal error: Call to undefined method stdClass::__set_state() in D:\Developing\Projects\Web\Sites\Ace Rainbow\site\weblog\sites\all\modules\devel\macro.module(167) : eval()'d code on line 6

What i already did to fix (but ) :
- check my core patched to see this error is not because of them , result : it's not
- using irc support channel to asking for help , result : below suggestion by qpo
- applying changes recommended by this article (http://www.lullabot.com/articles/moving-cck-field-changes-from-dev-to-live) : result : no luck!
- searching for stdClass to see what's it exactly, result : not very useful information but i find out that it's a Zend engine built in class, but which version of zend engine?! i don't know

workaround : although it's not a solution but i removed all of the modules page save macro and enabled modules i remembered by hand.

I will be thankful if you help me.

Regards

CommentFileSizeAuthor
#4 macro.module.patch1.81 KBtej_arora
#4 macro.module.patch1.81 KBtej_arora
macro.txt131.83 KBsinasalek

Comments

moshe weitzman’s picture

what are you trying to do?

sinasalek’s picture

I want to import saved macro's created on development version of site into live website. the only problem is if i enable or disable modules via Drupal modules administration page, saved macro's are not importable due to the Fatal error syntax error i mentioned before.
Fatal error: Call to undefined method stdClass::__set_state()

Regards

sinasalek’s picture

Some more details ,

In php5 devel macro generate this :

$macro[0]['form_id'] = 'system_modules';
$macro[0]['values']  = array (
  'validation_modules' => 
  array (
    'aggregator' => 
    stdClass::__set_state(array(
       'filename' => 'modules/aggregator/aggregator.module',
       'basename' => 'aggregator.module',
...

In php4 it generates this :

$macro[0]['form_id'] = 'system_modules';
$macro[0]['values']  = array (
  'validation_modules' => 
  array (
    'aggregator' => 
    class stdClass {
      var $filename = 'modules/aggregator/aggregator.module';
      var $basename = 'aggregator.module';
      var $name = 'aggregator';
      var $type = 'module';
      ...

If you try to import the macro which generated with the same php version you will get this :
PHP5 : Call to undefined method stdClass::__set_state()
PHP4 : parse error, unexpected T_CLASS

I think it's a bug becuase macro.devel canno import what it is just exported.
This issue only happens if you submit "admin/build/modules" after you enabled macro recording and try to export & import the saved macro(s)

tej_arora’s picture

StatusFileSize
new1.81 KB
new1.81 KB

The "bug" isn't really in the macro module.

The macro, as generated by var_export (which macro module uses), is quite useless because there is no way to add a __set_state method to stdClass in the user application. This is an anomalous dead-end. The spirit behind __set_state is that for user defined object types, the user has an opportunity to control the export by defining __set_state. The generated macro has __set_state because var_export thinks that the values in the passed in the array are 'objects'. We do know that Drupal code does not use PHP Classes (from what I've seen so far), and relies on multi-dimensional arrays. So the 'object' really is an array. There are other such arrays in drupal that appear like 'objects' in a debugger, e.g. $node, and $user... My colleague believes that this is because anything drupal stores in a db is retrieved as an 'object'.

Here are possible workarounds, with the assumption that we do not use class types anywhere in drupal:
1) Completely erase "stdClass::__set_state" from the macro. In other words replace all occurences of "stdClass::__set_state()" with "". The edited macro will work just fine.
2) define your own class mystdClass as follows, and replace all occurences of "stdClass" in the macro with "mystdClass".

class mystdClass
{
  public static function __set_state(array $a) {
    $v = var_export($a, TRUE);
    return $v;
  }
}

3) make a change to macro.module (patch attached). This change recurses through the variable passed to var_export and sets it up as a data structure that does not have anything for which is_object would return TRUE.

Hope this helps.

tej_arora’s picture

In the previous post, there was a typo... in suggestion number (1).
It should read:

Completely erase "stdClass::__set_state" from the macro. In other words replace all occurences of "stdClass::__set_state(XXX)" with "XXX". The edited macro will work just fine.

sinasalek’s picture

Priority: Normal » Critical
Status: Active » Reviewed & tested by the community

Hi, thank you for notifying me and providing the patch.
Now i understand the root of the problem. it's strange that no reported this bug before me. cause according to your explanation it does not work in most of circumstances.

I did some investigation about the issue again, and it looks like your suggested workaround currently is the best way. :))

I tested the patch and it works well.

Regards

moshe weitzman’s picture

Status: Reviewed & tested by the community » Fixed

committed. thanks.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.