Skip links

ترکیب لاراول و وردپرس

چگونه از وردپرس در لاراول استفاده کنیم؟

لطفا در نظر داشته باشید که راه های زیادی برای انجام این کار وجود دارد و حتی پکیج هایی هم توسط دیگر توسعه دهندگان برای این کار وجود دارد. اما ما در اینجا از روش همگام سازی استفاده میکنیم تا دو محیط کاملا مجزا از هم داشته باشیم. این روش به ما این امکان را میدهد که سایت ما، کاملا برپایه لاراول باشد تا در آینده برای توسعه آن مشکلی نداشته باشیم

بعید از اینکه کدهای مربوط به همگام سازی را پیاده کنیم، می توانیم از scheduler های لاراول برای تکرار خودکار این کد توسط . هاست در زمان های تعیین شده استفاده کنیم تا داده های سایت ما همیشه بروز باشد. علاوه بر این ما در اینجا فقط پست ها، برچسب ها و دسته بندی ها را از طریق api واکشی میکنیم و مابقی موارد مانند page ها را میتوانید به صورت صفحات استاتیک blade در سایت تعبیه نمایید

api وردپرس

وردپرس به صورت پیش فرض از api پشتیبانی نمی کند. اما می توانید با استفاده از افزونه WP Rest API در سایت وردپرسی، قابلیت ارائه api را به وردپرس اضافه کنید. از آنجایی که ما در این پروژه صرفا میخواهیم یک سری اطلاعات عمومی (نظیر پست ها و لینک ها و …) را از این api واکشی و در لاراول استفاده کنیم نیازی به احراز هویت و استفاده از امکانات مدیریت وردپرس نخواهیم داشت که کار را راحت تر میکند.

کلاس ساده زیر برای دریافت لیست پست ها استفاده می شود:

class WpApi
{
    protected $url = 'http://site.com/wp-json/wp/v2/';
    public function importPosts($page = 1)
    {
        $posts = collect($this->getJson($this->url . 'posts/?_embed&filter[orderby]=modified&page=' . $page));
        foreach ($posts as $post) {
            $this->syncPost($post);
        }
    }
    protected function getJson($url)
    {
        $response = file_get_contents($url, false);
        return json_decode( $response );
    }
}

حالا اگر شما از متد WpAPI->importPosts() استفاده کنید نتایج مربوط به صفحه اول را دریافت خواهید کرد. بیایید به string query کلاس بالا نگاهی بیاندازیم. اولین پارامتر _embed  است که تمام اطلاعات اضافی نظیر دسته بندی، تصاویر و برچسب ها را به نتایج اضافه میکند. بعد از آن از یک فیلتر برای مرتب کردن نتایج بر اساس تاریخ آخرین ویرایش filter[orderby]=modified استفاده شده است.

در مرحله بعد باید اطلاعات دریافت شده را در دیتابیس خود با استفاده از متدهای زیر همگام سازی (sync) کنیم.

protected function syncPost($data)
{
    $found = Post::where('wp_id', $data->id)->first();
    if (! $found) {
        return $this->createPost($data);
    }
    if ($found and $found->updated_at->format("Y-m-d H:i:s") < $this->carbonDate($data->modified)->format("Y-m-d H:i:s")) {
        return $this->updatePost($found, $data);
    }
}
protected function carbonDate($date)
{
    return Carbon::parse($date);
}

برای این کار ما یک wp_id به جدول پست های خودمان اضافه کردیم تا شناسه پست در وردپرس را ذخیره کند. با این کار میتوانیم یک رابطه یک به یک بین دیتابیس خودمان و دیتابیس وردپرس برقرار کنیم. سپس چک میکنیم تا در صورت وجود پست آن را update کرده و در غیر اینصورت پست را در دیتابیس ذخیره میکنیم

متدهای createPost  و updatePost  دو متد ساده Eloquent لاراول برای ذخیره سازی داده ها هستند. کدهای مربوط به ساخت پست جدید به صورت زیر است:

protected function createPost($data)
{
    $post = new Post();
    $post->id = $data->id;
    $post->wp_id = $data->id;
    $post->user_id = $this->getAuthor($data->_embedded->author);
    $post->title = $data->title->rendered;
    $post->slug = $data->slug;
    $post->featured_image = $this->featuredImage($data->_embedded);
    $post->featured = ($data->sticky) ? 1 : null;
    $post->excerpt = $data->excerpt->rendered;
    $post->content = $data->content->rendered;
    $post->format = $data->format;
    $post->status = 'publish';
    $post->publishes_at = $this->carbonDate($data->date);
    $post->created_at = $this->carbonDate($data->date);
    $post->updated_at = $this->carbonDate($data->modified);
    $post->category_id = $this->getCategory($data->_embedded->{"wp:term"});
    $post->save();
    $this->syncTags($post, $data->_embedded->{"wp:term"});
    return $post;
}

در کدهای بالا مواردی نظیر author ، featured image ، category و Tags وجود دارد که از پارامتر _embed  در query string ابتدای کار مشتق شده اند. در زیر کدهای مربوط به همگام سازی این موارد را مشاهده میکنید:

public function featuredImage($data)
{
    if (property_exists($data, "wp:featuredmedia")) {
        $data = head($data->{"wp:featuredmedia"});
        if (isset($data->source_url)) {
            return $data->source_url;
        }
    }
    return null;
}
public function getCategory($data)
{
    $category = collect($data)->collapse()->where('taxonomy', 'category')->first();
    $found = Category::where('wp_id', $category->id)->first();
    if ($found) {
        return $found->id;
    }
    $cat = new Category();
    $cat->id = $category->id;
    $cat->wp_id = $category->id;
    $cat->name = $category->name;
    $cat->slug = $category->slug;
    $cat->description = '';
    $cat->save();
    return $cat->id;
}
private function syncTags(Post $post, $tags)
{
    $tags = collect($tags)->collapse()->where('taxonomy', 'post_tag')->pluck('name')->toArray();
    if (count($tags) > 0) {
        $post->setTags($tags);
    }
}

ما در این پروژه برای هر پست فقط اولین دسته مربوط به آن را در دیتابیس ذخیره میکنیم و در واقع برخلاف وردپرس برای هر یک از پست ها فقط یک دسته (اولین دسته) را در نظر میگیریم

ساخت Scheduled Command

آخرین گام برای تکمیل پروژه سشاخت یک دستور تکرارشونده برای دریافت و ذخیره اتوماتیک پست هاست.

دیدگاه خود را بنویسید