XF 2.2 Proper way to use assertRecordExists

briansol

Well-known member
I'm trying to leverage the assertRecordExists functionality and i'm not getting consistent results.

the base code looks like:

Code:
$finder->where('x', $params['slug']); 
$x= $finder->fetchOne();

$x= $this->assertRecordExists('NS\Addon:X', $x['id'], null, null);

if(!$x)
{
       throw $this->exception($this->notFound('X Not Found in our Database'));
}

When i test a record that exists, it functions correctly.

When i test a record that doesn't exist, it throws an exception:
Code:
ErrorException: [E_WARNING] Trying to access array offset on value of type null in src\addons\NS\Addon\Pub\Controller\MyController.php at line 224

224 is the assertRecordExists line.

Which makes sense as $x is null when the record can't be found in the database. But, then I can't see the correct usage of this assertion as it must not fail with an exception if the record doesn't exist, right? as that's kind of the whole point of this functionality in the first place.
 
Controllers are usually designed to work with primary keys; assertRecordExists is no exception: It does only work with primary keys.

So if column slug is not your primary key it simply won't work.
 
It's not, slug is a unique col but id is the primary key.

Ok, so in that case, is something like this stupid or redundant? It seems to work but it seems convoluted and the 'ID Found' message never seems to fire.

Code:
$finder->where('x', $params['slug']); 
            $x= $finder->fetchOne();

            if($x){
                $x= $this->assertRecordExists('NS\addon:X', $x['id'], null, null);
    
                if(!$x)
                {
                    throw $this->exception($this->notFound('ID found but X Not Found in our Database'));
                }
            }        
            else {
                throw $this->exception($this->notFound('X Not Found in our Database'));
            }
 
That would be redundant, yes. Note that the assert* methods already throw an exception when necessary, there is no need to do so manually. Since you can't use this one, just write your own.

PHP:
public function assertThingExists($slug, $with = null, $phraseKey = null)
{
    $thing = $this->em()->findOne('My:Thing', ['slug' => $slug], $with);
    if (!$thing)
    {
        if (!$phraseKey)
        {
            $phraseKey = 'requested_page_not_found';
        }

        throw $this->exception($this->notFound(\XF::phrase($phraseKey)));
    }

    return $thing;
}
 
Thanks, i'm struggling with the correct location of this function.

The rest of the assertion functions seem to live in the abstract controller class. So, I assume i need to put it in my controller which extends that class.

But i have about 15 different controllers (one per major category of items each with multiple actions). I had it all in one at first but broke it out by major route.

So, i need a more global section that that else i'll have multiple instances of this same function. Ideas?
 
Just make your own abstract controller and have your controllers extend that.

PHP:
<?php

namespace My\AddOn\Pub\Controller;

abstract class AbstractController extends \XF\Pub\Controller\AbstractController
{
    // ...
}
 
Top Bottom