3

I generate/update several articles through a PHP script (in the cli folder) that parses an external data source (custom tables). This works well.

Now, if an article has not yet an image, the script must give it a random one.

foreach($arr_articles as $custom_id => $article_data)
{
    // test if article exists
    $sql = 'SELECT '.$db->quoteName('item_id')
        .' FROM '.$db->quoteName($db_prefix.'fields_values')
        .' WHERE '.$db->quoteName('field_id').' = 14 ' # my custom id
        .' AND '.$db->quoteName('value').' = '.$db->quote($custom_id);

    $db->setQuery($sql);
    $article_id = $db->loadResult();

    $jarticle = JTable::getInstance('content');

    $article_has_image = False;

    if(!is_null($article_id))
    {
        // article exists, load it
        $jarticle->load($article_id);

        // and look for its images
        $images = json_decode($jarticle->images);
        if(isset($images->image_fulltext) && !empty($images->image_fulltext))
        {
            $article_has_image = True;
        }
    }
    if(! $article_has_image)
    {
         //set new one
         $filepath = getRandomImage();
         $jarticle->set('image_fulltext',$filepath);
    }
    //do more stuff, update custom fields...
    //save
    $jarticle->store();
}

getRandomImage() gets an absolute filepath on the server.

My attempt with $jarticle->set('image_fulltext',$filepath); does not seems to do anything, is there a better way to set the images (fulltext_image and intro_image) ?

2

I don't see set() in the JTable docs. You also need to remember to re-encode the full column value before storing. The following is an untested snippet.

$db = JFactory::getDbo();
$query = $db->getQuery(true)
            ->select(db->qn("item_id"))
            ->from($db->qn("#__fields_values"));  // build all of the non-changing clauses for the query
$where = [$db->qn('field_id') . " = 14"];  // declare the first condition for the WHERE clause

foreach ($arr_articles as $custom_id => $article_data)
{
    // only modify the where clause within the loop (re-use the rest of the query string)
    $where[1] = $db->qn('value') . ' = ' . (int)$custom_id;  // declare the new/second condition for the WHERE clause
    $query->clear('where')->where($where);  // append fresh where conditions to query

    $article_id = $db->setQuery($query)->loadResult();
    if ($article_id)
    {
        $jarticle = JTable::getInstance('content');  // I am not sure if this can be declared before the foreach (reused like $db)
        $jarticle->load($article_id);
        $imageData = json_decode($jarticle->images);  // string to object
        if(empty($imageData->image_fulltext))
        {
            $imageData->image_fulltext = getRandomImage();  // modify object property
            $jarticle->images = json_encode($imageData);  // object back to string and overwrite the fetched property
        }
        //do more stuff, update custom fields...
        $jarticle->store();
    }
}
  • 1
    I've refined my snippet to be more efficient (fewer iterated calls). If it is too confusing, see my first version in the edit history. – mickmackusa Sep 5 at 12:43
  • Thanks for your answer and time! I finally have some time to spend on this subject, I try to apply your suggestions and will update the issue once I figured it out ;) – nicolallias Sep 18 at 7:46
  • 1
    My attempt of $jarticle->set('image_fulltext',$filepath); did not work, your $imageData->image_fulltext = getRandomImage(); $jarticle->images = json_encode($imageData); did the trick! Thank you very much :) – nicolallias Sep 18 at 9:10

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.