1

After adding the Anahkiasen/Polyglot package to my Laravel 4.2 project I tried to get this to work. I set up everything the way I think it's supposed to be (the documentation is kinda bad). Saving to the database doesn't seem to be a problem but when I want to read I get the following error:

Trying to get property of non-object (View: /Applications/MAMP/htdocs/*my view*.blade.php)

Models:

use Polyglot\Polyglot;

class Page extends Polyglot {

    use SoftDeletingTrait;

    protected $fillable = [
        'lang',
        'meta_title',
        'meta_description',
        'title',
        'page_title',
        'page_content',
    ];
    protected $polyglot = [
        'meta_title',
        'meta_description',
        'title',
        'page_title',
        'page_content',
    ];

    // ...
}

class PageLang extends Eloquent {

    public $timestamps = false;
    protected $fillable = [
        'page_id',
        'lang',
        'meta_title',
        'meta_description',
        'title',
        'page_title',
        'page_content',
    ];
}

My blade template:

$page->nl->title
/*
This is what's causing the error
$page->title doesn't produce errors but is, of course, empty
*/

Been stuck on this for a while now. Any help is greatly appreciated :-)

Alana Storm
  • 164,128
  • 91
  • 395
  • 599
Jack33
  • 121
  • 1
  • 9
  • FYI: Edited for code formatting. Stack Overflow (this site) uses Markdown for code formatting -- just indent thing by four spaces and they'll be automatically treated as code – Alana Storm Apr 09 '15 at 17:41

1 Answers1

2

I'm not familiar with the library, but looking at the base Polyglot class, it looks like this abstraction works by using PHP's magic __get variable to inject n localization object when you access something like $page->nl

Looking at __get,

public function __get($key)
{
    // If the relation has been loaded already, return it
    if (array_key_exists($key, $this->relations)) {
        return $this->relations[$key];
    }
    // If the model supports the locale, load and return it
    if (in_array($key, $this->getAvailable())) {
        $relation = $this->hasOne($this->getLangClass())->whereLang($key);
        if ($relation->getResults() === null) {
            $relation = $this->hasOne($this->getLangClass())->whereLang(Config::get('polyglot::fallback'));
        }
        return $this->relations[$key] = $relation->getResults();
    }
    // If the attribute is set to be automatically localized
    if ($this->polyglot) {
        if (in_array($key, $this->polyglot)) {
            /**
             * If query executed with join and a property is already there
             */
            if (isset($this->attributes[$key])) {
                return $this->attributes[$key];
            }
            $lang = Lang::getLocale();
            return $this->$lang ? $this->$lang->$key : null;
        }
    }
    return parent::__get($key);
}

there's a number of conditionals that, if failed, result in the parent's __get being called

return parent::__get($key);

In other words, the normal model behavior. That's probably what's happening above -- and since nl isn't a set object PHP complains when you try to call a method on it.

Of the three conditionals in __get, this seems like the most likely candidate for failure

    if (in_array($key, $this->getAvailable())) {
        $relation = $this->hasOne($this->getLangClass())->whereLang($key);
        if ($relation->getResults() === null) {
            $relation = $this->hasOne($this->getLangClass())->whereLang(Config::get('polyglot::fallback'));
        }
        return $this->relations[$key] = $relation->getResults();
    }

If your specific case, it's going to look like

    if (in_array('nl', $this->getAvailable())) {
        //...
    }

Looking at getAvailable()

protected function getAvailable()
{
    return Config::get('polyglot::locales');
}

it looks for a configuration field named Config::get('polyglot::locales');. I'd check if calling that configuration field returns nl as a configured locale

var_dump(Config::get('polyglot::locales'));

My guess would be it doesn't, possibly because you didn't run the artisan command to publish the configuration for the package

php artisan config:publish anahkiasen/polyglot
Alana Storm
  • 164,128
  • 91
  • 395
  • 599
  • That's an awesome answer, made me understand it too! I did create my own config file with the artisan command however the `Config::get('polyglot::locales')` variable was empty. I added an array with the languages I support, including 'nl' for dutch. However I'm still getting an error and this is because, even though the application knows about a possible dutch record, there wasn't actually a dutch record in the database. It would be fancier if Polyglot returned an empty array (or the fallback language, if I set one) rather than throwing errors. – Jack33 Apr 09 '15 at 20:08
  • I marked it as the right answer, however I can't upvote since I have less than 15 points :-( – Jack33 Apr 09 '15 at 20:09