0

I'm using CakePHP version 4.2 and am noticing some odd behavior from the annotate script that comes bundled with the API. For one component, the annotate script wants to default to the App\ domain that is CakePHP's default. I've changed the application name so most other classes default to the correct application name. But not this one script and so far, only for this one file.

I've included the body of the component, for review, below. You can see that the @method annotation uses the App\ domain. The trouble comes in when I use PHPStan to analyze my code. If I leave the annotation as is, PHPStan will tell me:

 ------ -------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  Line   src/Controller/Component/CartManagerComponent.php                                                                                                             
 ------ -------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  43     Property Visualize\Controller\Component\CartManagerComponent::$Controller (Visualize\Controller\AppController) does not accept App\Controller\AppController.  
  44     Call to method loadModel() on an unknown class App\Controller\AppController.                                                                                  
          Learn more at https://phpstan.org/user-guide/discovering-symbols                                                                                            
 ------ -------------------------------------------------------------------------------------------------------------------------------------------------------------- 

The file itself doesn't use the App\ domain anywhere. I'm not sure where to look for the script to figure out whats wrong. Here is the body of my component in case you see something I do not:

<?php
declare(strict_types=1);

namespace Visualize\Controller\Component;

use Authorization\Identity;
use Cake\Controller\Component;
use Cake\Log\Log;

/**
 * CartManager component
 *
 * @method \App\Controller\AppController getController()
 * @property \Visualize\Controller\AppController $Controller
 * @property \Visualize\Model\Table\CartsTable $Carts
 */
class CartManagerComponent extends Component
{
    /**
     * Default configuration.
     *
     * @var array
     */
    protected $_defaultConfig = [];

    /**
     * @var \Visualize\Controller\AppController
     */
    protected $Controller;

    /**
     * @var \Visualize\Model\Table\CartsTable
     */
    protected $Carts;

    /**
     * @param array $config The current configuration array
     * @return void
     */
    public function initialize(array $config): void
    {
        parent::initialize($config);
        $this->Controller = $this->getController();
        $this->Controller->loadModel('Carts');
    }

    /**
     * Returns the most recent active cart.
     *
     * @param \Authorization\Identity $user The User entity.
     * @return array|\Cake\Datasource\EntityInterface|null
     * @noinspection PhpUnnecessaryFullyQualifiedNameInspection
     */
    public function getUserCart(Identity $user)
    {
        $cart = $this->Controller->Carts->newEmptyEntity();
        if (!empty($this->Controller->Carts) && is_a($this->Controller->Carts, '\Visualize\Model\Table\CartsTable')) {
            $query = $this->Controller->Carts->find('userCart', ['user_id' => $user->getIdentifier()]);
            if (!$query->isEmpty()) {
                $cart = $query->first();
            } else {
                $cart->set('user_id', $user->getIdentifier());
                $this->Controller->Carts->save($cart);
            }
            if (is_object($cart) && is_a($cart, '\Cake\Datasource\EntityInterface')) {
                $session = $this->Controller->getRequest()->getSession();
                $session->write('Cart.id', $cart->id);
            }
        }

        return $cart;
    }

    /**
     * Abandons carts
     *
     * @param int $user_id The associated user ID
     * @param int $cart_id The current cart ID
     * @return void
     */
    public function pruneCarts(int $user_id, int $cart_id): void
    {
        if (!empty($this->Controller->Carts) && is_a($this->Controller->Carts, '\Visualize\Model\Table\CartsTable')) {
            // Find all the carts we didn't just create:
            $userCarts = $this->Controller->Carts->find('all', ['fields' => ['id', 'user_id', 'cart_status']])
                ->where([
                    'id !=' => $cart_id,
                    'user_id' => $user_id,
                    'cart_status' => 'active',
                ]);
            if (!$userCarts->isEmpty()) {
                $count = 0;
                foreach ($userCarts as $cart) {
                    if ($count < 5) {
                        $record = $this->Controller->Carts->newEmptyEntity();
                        $record = $this->Controller->Carts->patchEntity($record, $cart->toArray());
                        $record->set('id', $cart->id);
                        $record->set('cart_status', ABANDONED_CART);
                        if (!$this->Controller->Carts->save($record)) {
                            Log::alert('Error abandoning cart');
                        }
                    } else {
                        $this->Controller->Carts->delete($cart);
                    }
                    $count++;
                }
            }
        }
    }
}
tjb74
  • 59
  • 1
  • 2
  • 8
  • What "annotate script" and "API" are you talking about? No such thing ships with the CakePHP framework or application template. – ndm Sep 14 '21 at 12:58
  • Seeing what IDE helper does, that might be what you're referring to: **https://github.com/dereuromark/cakephp-ide-helper/blob/1.14.0/src/Annotator/ComponentAnnotator.php#L42-L44**. I'd suggest to open an issue over at GitHub, so that this can be fixed to respect the application's `App.namespace` config. – ndm Sep 14 '21 at 13:07
  • Right, you are, NDM. My mistake. I'll follow up over there, thanks. – tjb74 Sep 14 '21 at 18:06

0 Answers0