TypeError when array value is empty

Created on 10 March 2024, 4 months ago
Updated 26 March 2024, 3 months ago

This is just a coding error in my custom plugin but I can't seem to get any fix to work. My computed field just creates a URL linking books on out site to Amazon. I use a 10 character code either the ISBN or ASIN of the book, and insert that into the URL from my plugin. if for some reason the book does not have either of the 10 digit codes, the plugin fails with:
TypeError: Drupal\buy_amazon\Plugin\ComputedField\Computedbuyamazon::computeValue(): Return value must be of type array, none returned in Drupal\buy_amazon\Plugin\ComputedField\Computedbuyamazon->computeValue() (line 45 of modules/custom/buy_amazon/src/Plugin/ComputedField/Computedbuyamazon.php).

My entire plugin looks like this:

namespace Drupal\buy_amazon\Plugin\ComputedField;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\computed_field\Field\ComputedFieldDefinitionWithValuePluginInterface;
use Drupal\computed_field\Plugin\ComputedField\ComputedFieldBase;
use Drupal\Component\Plugin\ConfigurableInterface;
use Drupal\Core\Plugin\PluginFormInterface;

/**
 * @ComputedField(
 *   id = "buy_amazon_computedbuyamazon",
 *   label = @Translation("Computed buy Amazon"),
 *   field_type = "text",
 * )
 */
class Computedbuyamazon extends ComputedFieldBase {

  /**
   * {@inheritdoc}
   */
  public function computeValue(EntityInterface $host_entity, ComputedFieldDefinitionWithValuePluginInterface $computed_field_definition): array {
    // Returns the value for a computed field.
	if(!empty($host_entity->field_isbn10->value)) {
		$ISBN = $host_entity->field_isbn10->value;
	}else{
		if(!empty($host_entity->field_amazon_asin->value)) {
			$ISBN = $host_entity->field_amazon_asin->value;
		}else{
			$ISBN = '';
		}
	}
	if(!empty($ISBN)) {
		$value = '<a href="http://www.amazon.com/gp/product/'.$ISBN.'/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN='.$ISBN.'&linkCode=as2&tag=MYIDCODE"  target="_blank">Amazon.com</a><img src="https://www.assoc-amazon.com/e/ir?t=MYIDCODE&l=as2&o=1&a='.$ISBN.'" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />';
        return [
            0 => [
            'value' => $value,
            'format' => 'full_html',
            ],
        ];    
	}    
  }

}

If both fields: field_amazon_asin, and field_isbn10 are empty, it throws the error. I tried adding an else{return;} in the last if but that did not work. How to I tell computed field to just ignore everything if I don't have the correct values?

πŸ’¬ Support request
Status

Fixed

Version

4.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States wxman

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @wxman
  • Status changed to Fixed 4 months ago
  • πŸ‡¬πŸ‡§United Kingdom joachim

    You need to do what it tells you and return at least an empty array.

    Also, BTW, I think there's a mistake in your code because there's no point setting $ISBN = ''; if you're then going to ignore an empty $ISBN.

  • πŸ‡ΊπŸ‡ΈUnited States wxman

    You were correct about the mistake. Leftovers from other try's. If you want to see something scary, I asked Bing's Copilot: "how can I improve this PHP code". I pasted my original plugin code into it, and not only did it fix/improve it, it recognized that it was for linking to Amazon Associates. It came back with this:

    class Computedbuyamazon extends ComputedFieldBase {
    
        /**
         * {@inheritdoc}
         */
        public function computeValue(EntityInterface $host_entity, ComputedFieldDefinitionWithValuePluginInterface $computed_field_definition): array {
            $ISBN = $this->getISBN($host_entity);
    
            if (!empty($ISBN)) {
                $value = $this->generateAmazonLink($ISBN);
            } else {
                $value = '';
            }
    
            return [
                0 => [
                    'value' => $value,
                    'format' => 'full_html',
                ],
            ];
        }
    
        /**
         * Get the ISBN from either field_isbn10 or field_amazon_asin.
         *
         * @param EntityInterface $host_entity
         * @return string|null
         */
        private function getISBN(EntityInterface $host_entity): ?string {
            if (!empty($host_entity->field_isbn10->value)) {
                return $host_entity->field_isbn10->value;
            } elseif (!empty($host_entity->field_amazon_asin->value)) {
                return $host_entity->field_amazon_asin->value;
            }
            return null;
        }
    
        /**
         * Generate the Amazon link and image HTML.
         *
         * @param string $ISBN
         * @return string
         */
        private function generateAmazonLink(string $ISBN): string {
            $link = '<a href="https://www.amazon.com/gp/product/' . $ISBN . '/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=' . $ISBN . '&linkCode=as2&tag=thelittim04-20" target="_blank">Amazon.com</a>';
            $image = '<img src="https://www.assoc-amazon.com/e/ir?t=thelittim04-20&l=as2&o=1&a=' . $ISBN . '" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />';
    
            return $link . $image;
        }
    }
    

    It works perfectly. The AI even gave me pointers and explained why it suggested what it did. Scary!

  • πŸ‡¬πŸ‡§United Kingdom joachim

    When there is no ISBN you should return an empty value, not an array with a 0 delta and empty in that.

    Otherwise, your field will output a label with no content, and your Twig templates will think they have a value to work with.

  • πŸ‡ΊπŸ‡ΈUnited States wxman

    @joachim Okay this is working as shown, so which are you saying needs to be changed?

  • πŸ‡¬πŸ‡§United Kingdom joachim

    I'm minded to close any issues that mention AI anyway, on account of its obscene carbon footprint and shady practices with IP, but if you're questioning my advice over the regurgitated rubbish from fancy autocomplete, I am definitely out of this issue.

  • πŸ‡ΊπŸ‡ΈUnited States wxman

    @joachim I'm not questioning your advice at all. You are much better at working on this that I will ever be. I was just confused as to which value needs to be changed. I thought if the value comes up empty the view just doesn't show it.

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

Production build 0.69.0 2024