1

I have a field (public_files) that accepts file uploads to which I have applied the pdfpreview module which provides a field formatter that will provide the generated image for pdf files. I have another field for cover images.

This setup is working well, and I basically default to the cover image field, and fallback to the pdf preview version of the first file if the cover image hasn't been provided. A problem arises for a section of the site where I only want to list items that have cover images. There is a complicated bug in drupal that prevents me from doing the filtering in views to only items that have a cover image or for which the first file is a pdf file.

To alleviate this, what I'd like to do is use rules to automatically populate the cover image field with the generated cover whenever there is a generated cover image, and the cover image field is empty.

Sorry for the long preamble, here is the question:

Is there any way to get at the pdf preview image and populate an image field with it in rules?

7
  • 1
    Bonjour! When to you want that populate to happen? Wild guess: either at node create OR at node update? Jul 12 '17 at 9:38
  • I was thinking at node view, might be a good time just to be sure that the preview had had a chance to be saved. I'd then need a condition to check whether the cover field already has a value and one to see if either there is a pdfpreview available or if the first file in the field is a pdf
    – UltraBob
    Jul 12 '17 at 9:48
  • That said, at node create and node update may be a much better time, if pdf preview has had a chance to do what it does by the time those events fire. I wasn't sure on that.
    – UltraBob
    Jul 12 '17 at 9:48
  • 1
    1 more question (I'm thinking about a compromise): is it acceptable to have a delay of X mins (X between say 3 and 60) before that "populate" actually happens? PS: can you read my mind already what I'm thinking of? Jul 12 '17 at 10:00
  • 1
    Unless there is some sort of "pdfpreview rules integration" module, I highly doubt this is possible with rules. Looks like custom module is the way to go on this 1.
    – No Sssweat
    Jul 13 '17 at 1:23
0

From your question, I seem to understand that this is your goal (= quote from your question):

... use rules to automatically populate the cover image field with the generated cover whenever there is a generated cover image, and the cover image field is empty.

There seem to be at least 3 ways to achieve that goal, as further detailed below ...

Solution 1

This solution elaborates on one of your comments, which is like so:

I was thinking at node view, might be a good time just to be sure that the preview had had a chance to be saved. I'd then need a condition to check whether the cover field already has a value and one to see if either there is a pdfpreview available or if the first file in the field is a pdf.

This could indeed work, but the crucial Rules challenge here is that there is no such event like "BEFORE" a node is being viewed. Because the "clue" about what Rules EVent "Content is viewed" actually means, seems to be like so:

  • The event Content is viewed is what it is: the user has (already) started viewing the content.

  • The (system) event Drupal is initializing is what you should use instead (possible combined with other Events and/or Actions), if you want to trigger some Rules "Action(s)" BEFORE the user can start viewing (= looking at) the content.

For more details, and a working sample (in Rules 'export format'), refer to How to specify a Rules event like "Content is 'going to be' viewed"?

My advice: only use this if all other options (solutions) fail. Read on for what IMO is a better solution.

Solution 2

This solution elaborates on one of your comments, which is like so:

... at node create and node update may be a much better time, if pdf preview has had a chance to do what it does by the time those events fire ...

Using this approach, you'll run into another Rules challenge ... I.e what's detailed in issue # 430274, about an event which is a variation of your event here, and somehow explains that "after saving something" actually happens "before saving something". This is not a bug, but simply how the Rules module works.

My advice: using this solution is a kind of risky, because of that above mentioned Rules challenge. Read on for what IMO is a better solution.

Solution 3

A possible compromise to avoid the kind of issues described in Solution 2, is to implement what needs to be done into a Rules Component, so that your original Rule "schedules the execution" (using the Rules Scheduler sub-module) of that Rules component. For example after only a few seconds or minutes if your cron job runs frequent enough (otherwise it'll be next time cron runs). This compromise will ensure that, at the time the Rules component is executed, the entity is for sure saved (so that can't be the reason anymore then why things don't work as expected). Read on for how you can get this to work ...

Step 1 - Create a Rules Component

Have a look at this Rules Component, in Rules export format:

{ "rules_populate_an_output_field_with_an_input_field" : {
    "LABEL" : "Populate an output field with an input field",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : { "node_to_update" : { "label" : "Node to be updated", "type" : "node" } },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "node-to-update" ], "field" : "field_image" } },
      { "NOT data_is_empty" : { "data" : [ "node-to-update:field-image" ] } },
      { "entity_has_field" : { "entity" : [ "node-to-update" ], "field" : "field_cover_image" } },
      { "data_is_empty" : { "data" : [ "node-to-update:field-cover-image" ] } }
    ],
    "DO" : [
      { "data_set" : {
          "data" : [ "node-to-update:field-cover-image" ],
          "value" : [ "node-to-update:field-image" ]
        }
      },
      { "entity_save" : { "data" : [ "node-to-update" ], "immediate" : "1" } }
    ]
  }
}

This Rules Component used a "node" (the node to be updated) as a parameter.

This is what the Rules Conditions in the above Rules Component are about:

  • It uses a parameter "Node to be updated".
  • It processes the fields with machine names field_cover_image and field_image (adapt the machine names to fit your own field names, prior to trying to import this Rules Component in your own site).
  • It has a rules condition "Entity has field" (twice) to make those fields available for subsequent processing.
  • It has a Rules Condition for each of both fields to check that their initial value (before the Rules Component's actions will be triggered), to match your requirement like "... populate the cover image field with the generated cover whenever there is a generated cover image, and the cover image field is empty...".

This is what the Rules Actions in the above Rules Component do:

  • Set the value of field field_cover_image equal to the value of field field_image.
  • Save the node (to ensure the updated value actually gets saved ...).

Step 2 - Create a Rule to schedule the Rules Component

This one is pretty easy, here is a rule (in Rules export format) that will "schedule" the execution of the Rules Component from the previous step:

{ "rules_schedule_image_population" : {
    "LABEL" : "Schedule image population",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "rules_scheduler" ],
    "ON" : { "node_insert" : [], "node_update" : [] },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_cover_image" } }
    ],
    "DO" : [
      { "schedule" : {
          "component" : "rules_populate_an_output_field_with_an_input_field",
          "date" : "+1 min",
          "identifier" : "Schedule-image-population-[node:nid]",
          "param_node_to_update" : [ "node" ]
        }
      }
    ]
  }
}

The rule uses as Rules Event "After creating a new node", or "After updating an existing node".

To avoid wasting resources, we only want to trigger the Rules Action for nodes that do have that field_cover_image field we want to populate (hence the Rules Condition).

And all this rule has to do (as Rules Action), is to schedule the execution of the Rules Component from the previous step. Adapt the delay to fit your needs (I've set it to just 1 min).

My advice: go for solution 3 (tested in my own setup, works like a charm ...)

Easy, no?

8
  • Thank you for this, but I think you are missing the point of the question. I need to know how I can get at an image generated by the pdfpreview module in order to populate the field_cover_image field. The source field is a file field, and so directly copying the value of the field doesn't work. The rest of the info about when to trigger is quite useful, but not the question. If the answer to my question is buried in there I'm afraid I missed it.
    – UltraBob
    Jul 12 '17 at 22:29
  • Hey @UltraBob , sorry to read your prior comment. Read the update I applied to my answer, .i.e the copy/paste from your question I added from the 3rd paragraph from your question. Now what? Jul 13 '17 at 8:56
  • Dear @Pierre.Vriens, I think the thing that your answer is missing, from the stated goal you quoted, is the word generated. I'm uploading a PDF file, the pdfpreview module is creating an image from that pdf file. I'm trying to determine how to get at that image that pdfpreview is creating with rules. If I was just trying to move an image from one image field to another image field, I think your solution would do the trick beautifully. If I'm missing the section where you ARE grabbing the generated image, please gently point it out to me, it is entirely possible I'm missing it.
    – UltraBob
    Jul 13 '17 at 9:15
  • Could I use views rules to pull up the image and use it in rules that way?
    – UltraBob
    Jul 14 '17 at 8:46
  • 1
    @UltraBob Hm, looks like we're making progress ... good news! I plan to add another "Solution" (= 4), which details how I'd get it to work using Views Rules then ... And I'll probably do so "before" next week ... Jul 14 '17 at 9:23

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.