First of all, thank you for getting iCal importing working on D7, this is great!

For this issue though,I'm trying to override the location being imported by a given ICS file. Instead of parsing and mapping that value, I want to set it to a string. I've created an iCal Feed Importer and it is importing and working just fine. I then used Features to save it to code. I implemented the Features module and enabled it, and again, it imported fine. The trouble started when I wrote code like this in that Feature-created module to alter the value of the location:

<?php
/**
 * Overriding the value of location
 */
function event_importers_feeds_after_parse(FeedsSource $source, FeedsParserResult $result) {

  if($result->title == 'generic-title'){
    foreach($result->items as $item_key => &$item) {
      if ($item_key == "field_location"){
        $item = 'Generic Value';
      }
    }
  }
?>

I get this error:
Fatal error: Call to a member function getProperty() on a non-object in /var/www/webdev/drupal/sites/all/modules/date_ical/includes/DateIcalFeedsParser.inc on line 63 Call Stack: 0.0001 648896 1. {main}() /var/www/webdev/drupal/index.php:0 0.2331 51667744 2. menu_execute_active_handler() /var/www/webdev/drupal/index.php:21 0.2337 51837208 3. call_user_func_array() /var/www/webdev/drupal/includes/menu.inc:517 0.2337 51837632 4. drupal_get_form() /var/www/webdev/drupal/includes/menu.inc:517 0.2337 51838648 5. drupal_build_form() /var/www/webdev/drupal/includes/form.inc:131 0.2424 52319720 6. drupal_process_form() /var/www/webdev/drupal/includes/form.inc:374 0.2440 52369848 7. form_execute_handlers() /var/www/webdev/drupal/includes/form.inc:860 0.2440 52373408 8. feeds_import_form_submit() /var/www/webdev/drupal/includes/form.inc:1464 0.2966 56089568 9. FeedsSource->startImport() /var/www/webdev/drupal/sites/all/modules/feeds/feeds.pages.inc:109 0.2998 56811368 10. FeedsSource->startBackgroundJob() /var/www/webdev/drupal/sites/all/modules/feeds/includes/FeedsSource.inc:243 0.2998 56811368 11. FeedsSource->import() /var/www/webdev/drupal/sites/all/modules/feeds/includes/FeedsSource.inc:677 32.3652 148500864 12. FeedsProcessor->process() /var/www/webdev/drupal/sites/all/modules/feeds/includes/FeedsSource.inc:358 32.3657 148501992 13. FeedsNodeProcessor->existingEntityId() /var/www/webdev/drupal/sites/all/modules/feeds/plugins/FeedsProcessor.inc:183 32.3657 148501992 14. FeedsProcessor->existingEntityId() /var/www/webdev/drupal/sites/all/modules/feeds/plugins/FeedsNodeProcessor.inc:356 32.3658 148512472 15. FeedsProcessor->uniqueTargets() /var/www/webdev/drupal/sites/all/modules/feeds/plugins/FeedsProcessor.inc:672 32.3659 148513568 16. DateIcalFeedsParser->getSourceElement() /var/www/webdev/drupal/sites/all/modules/feeds/plugins/FeedsProcessor.inc:708

I get the same error when I set Feeds Tamper to rewrite the results of the parsing for the location field too.

Any ideas on what's going on here?

Comments

coredumperror’s picture

After a quick perusal of the Date iCal code, the first thing that comes to mind is that you may be implementing your hook in a way that's incompatible with Date iCal. My first suggestion would be to either JIT Debug your hook or print our the original value of $item before you force it into a string. The line that's generating the traceback you posted expects $result->currentItem() to be a DateICalIcalcreatorComponent object ($result being the same FeedsParserResult object as in your hook, I think), rather than a string, which seems to be what's causing the error.

If this advice doesn't help, let me know and I'll dig deeper into this issue. I've never used hook_feeds_after_parse() before, so it'd take me some time to get a proper debug setup going.

cdmo’s picture

You're right, $item is an object, however I'm unable to find the element on that object to set its value...

if($result->title == 'generic-title'){
    foreach($result->items as $item_key => &$item) {
      # insert logic to find and set value of field_location
      }
    }
  }

Also, I'm unfamiliar with how to "JIT Debug" it, but usually I try to kprint_r() or drupal_set_message() the output of a particular object or array. The weird thing that is happening is that when I force an import by clicking the Import button at /import/name_of_importer it will hit a 30 second timeout (the ICS has a couple thousand events) and before it gives you the 30 second timeout error message it will indeed print out the object ($result or $item) when I use kprint_r().

However, when I try to drill down to result->items[0] (the DateIcalIcalcreatorComponent) it just displays that number of the array and it doesn't respond to clicks. So, I can't tell what to target in my foreach(). I'm guessing the array is just incomplete because the timeout prevented from rendering all the way. If I try to kpr() $item, it will similarly just show the DateIcalIcalcreatorComponent object that isn't clickable.

It doesn't time out when the cron runs, but I'm not sure there's a way to print the object during a cron.

I also tried to have the $result object printed to a file on my server, but that didn't work either. And the problem here isn't permissions because the txt file I'm appending to is 777 on the server.

Finally, if I try to kpr or dsm the output of a different feed, an ICS that only has one event, on Import click, it just seems to ignore the kpr or dsm requests and imports the ics successfully and quietly.

Kinda befuddled here. Also, alternatively, is there a better/known way to set the value of a field to a string on import?

Thanks for any help.

coredumperror’s picture

My first thought is that you might want to try using the dd() function, rather than kpr() or the like. dd() will print out the object to the file /tmp/drupal_debug.txt, so you won't have to worry about the browser being uncooperative.

As for "JiT Debugging", that's where you attach a debugger to your PHP code and place breakpoints, so that you can look at the code running live (JiT stands for Just in Time, though I'm not sure why it's called that). I only know how to set up JiT debugging with Eclipse, so if you're using another IDE, you'll have to find an alternative to this solution. I originally wrote this guide for my colleagues, who all use Macs, so if you don't use a Mac, you'll need to adjust these instructions a bit.

Install XDebug (http://xdebug.org/) and associated tools:
sudo port install php5-xdebug

Copy the following lines into /opt/local/etc/php5/php.ini:

[xdebug]
xdebug.remote_enable=On
xdebug.remote_handler="dbgp"
xdebug.remote_mode="req"
xdebug.remote_port=9000
xdebug.remote_host="localhost"
xdebug.remote_log=/path/to/wherever/you/want/your/logs

Restart Apache.

If you don't already have it, install the latest PDT plugin for Eclipse (http://wiki.eclipse.org/PDT/Installation). Then, configure the PHP Debug settings:
* Open the Eclipse Preferences dialog (Cmd-, hotkey, or Eclipse -> Preferences menu)
* Go to PHP -> Debug
* Select XDebug from the PHP Debugger dropdown.
* Click Configure..., then double-click on the XDebug ... 9000 line.
* Set Accept remote session (JIT) to "localhost".
* Uncheck "Show super globals in variable view". You can add the ones you want to look at to the Expressions tab in the debugger, rather than having them clutter up the Variables tab.

If you're using Firefox, install easy XDebug (https://addons.mozilla.org/en-US/firefox/addon/easy-xdebug). If you're using Chrome, install XDebug helper (https://chrome.google.com/webstore/detail/xdebug-helper/eadndfjplgieldjb...). These make debugging far easier than it would be without them.

I've not used the Firefox extension, but it should be easy enough to figure out. The Chrome one works by adding a little bug icon onto the right side of your address bar. Clicking it while on the site you'd like to debug will give you a dropdown, in which you should select the green "Debug" icon. Now whenever your browser makes a request to the server, Eclipse's debugger will be contacted by your browser and it will capture your site's runtime. In Eclipse, you can place a breakpoint by double-clicking in the gutter on a line.

While you're deubgging in Eclipse, you'll see the Variables tab in the upper-right corner. That tab will display the values of all the variables in the current scope. So, if you place a breakpoint on the line with if ($item_key == "field_location"){, you'll be able to look at that Variables tab to see the value of $item. You can use the "Step Over" button (it looks like an arrow hopping over one dot) to the left of the Variables tab to advance the program one line at a time.

cdmo’s picture

So, for your first suggestion, dd() worked great, that's a really handy function, thank you. The bad news now though is that it looks like the DateIcalIcalcreatorComponent object contains an object called compenent:protected. When I try to access the contents, i.e.

function event_importers_feeds_after_parse(FeedsSource $source, FeedsParserResult $result) {
dd($result->items[0]->component);  // tried dd($result->items[0]->component->location['value']); too
}

I get this error:

Fatal error: Cannot access protected property DateIcalIcalcreatorComponent::$component in /var/www/webdev/drupal/sites/all/modules/event_importers/event_importers.feeds_importer_default.inc on line 167 Call Stack: 0.0190 649152 1. {main}() /var/www/webdev/drupal/index.php:0 15.0168 52328544 2. menu_execute_active_handler() /var/www/webdev/drupal/index.php:21 15.0798 52498040 3. call_user_func_array() /var/www/webdev/drupal/includes/menu.inc:517 15.0799 52498464 4. drupal_get_form() /var/www/webdev/drupal/includes/menu.inc:517 15.0799 52499488 5. drupal_build_form() /var/www/webdev/drupal/includes/form.inc:131 15.3454 52980456 6. drupal_process_form() /var/www/webdev/drupal/includes/form.inc:374 15.3520 53030368 7. form_execute_handlers() /var/www/webdev/drupal/includes/form.inc:860 15.3521 53033928 8. feeds_import_form_submit() /var/www/webdev/drupal/includes/form.inc:1464 15.3586 53034032 9. FeedsSource->startImport() /var/www/webdev/drupal/sites/all/modules/feeds/feeds.pages.inc:109 15.6744 53755792 10. FeedsSource->startBackgroundJob() /var/www/webdev/drupal/sites/all/modules/feeds/includes/FeedsSource.inc:243 15.6744 53755792 11. FeedsSource->import() /var/www/webdev/drupal/sites/all/modules/feeds/includes/FeedsSource.inc:677 19.6516 62961496 12. module_invoke_all() /var/www/webdev/drupal/sites/all/modules/feeds/includes/FeedsSource.inc:355 19.6732 62981848 13. call_user_func_array() /var/www/webdev/drupal/includes/module.inc:857 19.6732 62982272 14. event_importers_feeds_after_parse() /var/www/webdev/drupal/includes/module.inc:857

So, I guess I can't change the values of this object?

In terms of the Xdebug stuff, I'm going to work at this again some time, but I wasn't able to get it to work. I suspect this is due to the fact that I'm using MAMP locally which has its own implementation of xdebug...

coredumperror’s picture

StatusFileSize
new515 bytes

Try this patch. It sets the $component attribute of DateIcalIcalcreatorComponent to public, which will let you view and edit it.

cdmo’s picture

Yup, that did the trick! I'm now able to override the location field on events being parsed in. Thanks a ton for your extremely fast support on this!

function event_importers_feeds_after_parse(FeedsSource $source, FeedsParserResult $result) {
  if($result->title == 'generic-title'){
    foreach ($result->items as $value) {
      $value->component->location['value'] = "Overriden String";
    }
  }
}
coredumperror’s picture

Status: Active » Fixed

Great, glad to hear that it worked! I'll go ahead and push this patch to the dev build of Date iCal, and it'll go live whenever a new official release comes out.

Status: Fixed » Closed (fixed)

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

technikh’s picture

Status: Closed (fixed) » Active

feeds tamper module is not working with date ical. http://drupal.org/project/feeds_tamper

I get this error
PHP Fatal error: Cannot use object of type DateIcalIcalcreatorComponent as array in /***************/sites/all/modules/feeds_tamper/feeds_tamper.module on line 53

coredumperror’s picture

Status: Active » Closed (fixed)

Please open a new issue for your specific problem, rather than re-opening this one.