0

I have run myself into a serious problem. I have a custom CCK datatype in Drupal6 in combination with an autocomplete widget on a text field. I have defined php code in the web configuration for the "allowed values list", but the code I wrote is faulty and uses up all memory (three nested foreach loops, returned array gets way too large, 2G mem limit reached).

Unfortunately, I cannot access the Drupal6 instance at all, as it seems the faulty php code is executed on all pages (not sure about this, but did reboot the server and still could not log in).

I guess it would be best just to delete the faulty PHP code for the Autocomplete widget from the backend, but I am unable to find it in the Postgres database. Can anyone give me a hint as to where in the database this code is stored?

Any other hint as to how to resolve this problem will be highly appreciated.

  • I don't immediately know where the code is stored, but a low tech way to solve it would be "drush sql-dump | grep [code]". Also, never ever put PHP in the db. – Letharion Jan 14 '14 at 13:02
  • Letharion, after this experience I fully agree with your notion. However, I was of the wrong assumption that even if the code was messed up, I would be still able to go to the edit page and edit it. But seemingly the code gets invoked on other pages than the "new/edit mydatatype" as well, this would be greatly inefficient, or am I mistaken? – Michael Jan 15 '14 at 8:58
  • I'm guessing that you're in the unfortunate situation where the caches got cleared by saving the php code, and they fail to regenerate because of the code, so it's attempted again and again and again. There's this particular reason, and then about 10 other reasons to not have code in the db, so just never do it. :) – Letharion Jan 15 '14 at 9:57
2

Try looking in the content_node_field table, under the global settings value:

mysql> desc content_node_field;
+-----------------+--------------+------+-----+---------+-------+
| Field           | Type         | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+-------+
| field_name      | varchar(32)  | NO   | PRI |         |       |
| type            | varchar(127) | NO   |     |         |       |
| global_settings | mediumtext   | NO   |     | NULL    |       |
| required        | tinyint(4)   | NO   |     | 0       |       |
| multiple        | tinyint(4)   | NO   |     | 0       |       |
| db_storage      | tinyint(4)   | NO   |     | 1       |       |
| module          | varchar(127) | NO   |     |         |       |
| db_columns      | mediumtext   | NO   |     | NULL    |       |
| active          | tinyint(4)   | NO   |     | 0       |       |
| locked          | tinyint(4)   | NO   |     | 0       |       |
+-----------------+--------------+------+-----+---------+-------+

I just did a test, defining an arbitrary PHP string (print "Hello Stack Exchange";) under allowed values for a field (field_test2) and found the following:

mysql> select global_settings from content_node_field where field_name = "field_test2";

+----------------------------------------------------------------------------------------------------------------------------------------------------+
| global_settings                                                                                                                                    |
+----------------------------------------------------------------------------------------------------------------------------------------------------+
| a:4:{s:15:"text_processing";s:1:"0";s:10:"max_length";s:0:"";s:14:"allowed_values";s:0:"";s:18:"allowed_values_php";s:31:"print "Hello Stack Exchange";";} |
+----------------------------------------------------------------------------------------------------------------------------------------------------+

The string you are looking for is at the end (s:31:"print "Hello Stack Exchange";";) and it's serialized with the character count at the front. If you want to zero this out, it would look like:

a:4:{s:15:"text_processing";s:1:"0";s:10:"max_length";s:0:"";s:14:"allowed_values";s:0:"";s:18:"allowed_values_php";s:0:"";}
|improve this answer|||||
  • 1
    Beat me to it. Whenever I've put php code in here, I've just put in a function, eg, return _foo(); that is defined in a custom module instead of the actual inline code. This way if things go crazy, you can at least edit your function easily instead of digging through the db. – Jimajamma Jan 14 '14 at 14:20
  • Also, if you do edit this directly via mysql or however, you may need to flush caches as this info is also stored up in cache_content inside cid content_type_info:LANGUAGE – Jimajamma Jan 14 '14 at 14:23
  • Thank you very much, this solved it perfectly. I temporarily disabled the module to avoid any more lock ups, issued a psql command: update content_node_field set global_settings = 'a:4:{s:15:"text_processing";i:0;s:10:"max_length";s:0:"";s:14:"allowed_values";s:0:"";s:18:"allowed_values_php";s:0:"";}' where field_name = 'field_fragment_label_id'; and runs drush cc all and enabled the module again. – Michael Jan 14 '14 at 14:24
  • Thanks for the assist on this @jimajamma - solid advice, especially like the tip of using a function instead of inline PHP code. – schnippy Jan 14 '14 at 15:30
  • Jimajamma, thanks for the good suggestion. I will try to do this, I'd rather have a file with the code to edit than a serialized string hidden somewhere in the db. Or I even might have to modify the autocomplete package, because the number of possible values is probably way to large to pass an array around with all options (need all combinations AAA000000 - ZZZ999999) – Michael Jan 15 '14 at 8:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.