Event در کیک پی اچ پی

رویداد و یا Event در کیک پی اچی پی نسخه ۲٫۱ به بعد اضافه شده است . و قاعده کار آن بدین صورت است که اگر یک تغییری در برنامه شما ایجاد شود یک قطعه کد دیگر در جای دیگر اجرا می شود . این باعث خواهد شد که کدهای ما خیلی بیشتر ماژولار باشد. و هر قسمت از کد در بخش مربوط به خود اجرا شود .

متاسفانه داکیومنت کیک پی اچ پی در زمینه رویداد خیلی ضعیف است ، که باعث شده که سوالات زیادی راجع به این موضوع در سایت satackOverflow پرسیده شود.

سناریو

سایتی که کار ثبت نام کاربری را انجام می دهد، وقتی یک کاربر ثبت نام انجام می دهد، در حالت پیش فرض غیر فعال است و کاربر باید برای فعال کردن اکانت خود بر روی لینک فعال سازی کلیک کند.

یک راه برای ارسال ایمیل فعال سازی بدین صورت است که در مدل user بدین صورت عمل کنیم.

<?php
class User extends AppModel {
    
    public function afterSave($created, $options = array()) {
        if ($created) {
            $email = new CakeEmail();
            $email->to($this->data[$this->alias]['email']);
            $email->from(array(
                'noreply@example.com' => 'Your Site'
            ));
            $email->subject('Activate your account');
            $email->format('text');
            $email->template('new_user');
            $email->viewVars(array(
                'user' => $this->data[$this->alias]
            ));
            $email->send();
        }
    }
}

که به صورت استاندارد این کار را ما نباید در مدل user انجام دهیم. چون کار مدل ایجاد و حذف و ویرایش یک رکورد است و نباید در آن ایمیل ارسال کنیم .

۱- وقتی یک رخداد اتفاق می افتد.

ارسال ایمیل را از متد afterSave حذف می کنیم. و به جای آن یک event اعمال می کنیم.

<?php
    App::uses('CakeEvent', 'Event');
    
    class User extends AppModel {
        
        public function afterSave($created, $options = array()) {
            if ($created) {
                $event = new CakeEvent('Model.User.created', $this, array(
                    'id' => $this->id,
                    'data' => $this->data[$this->alias]
                ));
                $this->getEventManager()->dispatch($event);
            }
        }
    }
    

توجه داشته باشید که ما در ابتدای کد event را هم معرفی کردیم.
و ما یک نمونه از کلاس event ایجاد می کنیم و به آن سه پارامتر پاس می دهیم.
۱- نام رویداد
۲- یک موضوع ( $this )
3- و چند دیتایی که به این رویداد مرتبط است. که ما میخواهیم برای ای دی مشخص شده اطلاعات جدید ذخیره کنیم.

که خود نام رویداد به سه قسمت تقسیم می شود. قسمت اول نام مدل، قسمت دوم نام مدل مرتبط و قسمت سوم نام اتفاقی که قرار است رخ دهد

پس ما از نام رویداد متوجه می شویم زمانی که یک کاربر ایجاد می شود یک رویداد رخ می دهد.

۲- ایجاد کردن یک ناظریا شنونده

پس ما تا اینجا یک رویداد را ایجاد کردیم. حال میخواهیم قسمتی را ایجاد کنیم که همیشه در حال شنود باشد که چه زمانی این رویداد اجرا می شود .
در فایل UserListener.php قطعه کد زیر را می نویسیم.

<?php
    App::uses('CakeEventListener', 'Event');
    
    class UserListener implements CakeEventListener {
        
    public function implementedEvents() {
        return array(
            'Model.User.created' => 'sendActivationEmail'
        );
    }
     }
     

حالا ما باید یک متد sendActivationEmail ایجاد کنیم.

public function sendActivationEmail(CakeEvent $event) {
        // TODO
    }
    

این متد یک آرگومان دارد : یک نمونه از CakeEvent . در حقیقت این یک نمونه کلاسی است که شما در مدل user ایجاد کردید، ساخته می شود . که در آنجا ما تعدادی داده ارسال کردیم ( ای دی رکورد و داده ای برای رکورد جاری ) . خوب این اطلاعات حالا در این قسمت برای ما قابل دسترس است .
خوب در اینجا ما کد خود را ادامه می دهیم.

public function sendActivationEmail(CakeEvent $event) {
        $this->User = ClassRegistry::init('User');
        
        $activationKey = Security::generateAuthKey();
        
        $this->User->id = $event->data['id'];
        $this->User->set(array(
            'active' => false,
            'activation_key' => $activationKey
        ));
        $this->User->save();
        
        $email = new CakeEmail();
        $email->from(array(
            'noreply@example.com' => 'Your Site'
        ));
        $email->to($event->data['user']['email']);
        $email->subject('Activate your account');
        $email->template('new_user');
        $email->viewVars(array(
            'firstName' => $event->data['user']['first_name'],
            'activationKey' => $activationKey
        ));
        $email->emailFormat('text');
        $email->send();
    }
    

کد بالا این کار ها را نجام می دهد .

  • یک نمونه از مدل user ایجاد می کند که به صورت عادی ما در کلاس event خود آن را نداریم.
  • یک کد فعال سازی برای کاربر جاری ایجاد میکنیم.
  • کد فعال سازی را برای کاربر جاری با آی دی که قبلا به آن پاس دادیم، ذخیره میکنیم
  • کد فعالسازی را برای کاربر ارسال می کنیم.

تا اینجای کار ما دو قسمت از سه قسمت کار را انجام دادیم. یک ، رخدادهایی که اتفاق می افتند، و اتفاقی که باید در هنگام روی دادن event انجام گیرد. ما فقط باید این دوقسمت را به همدیگر متصل کنیم.
یک راه برای اینکار این است که در فایل app/Config/bootstrap.php ما نیاز داریم که یک نمونه از کلاس شنونده رویداد را صدا بزنیم و آن را به مدل User پیوست attach کنیم. در پایین فایل bootstrap.php خود کد زیر را وارد کنید.

App::uses('ClassRegistry', 'Utility');
    App::uses('UserListener', 'Event');
    
    $user = ClassRegistry::init('User');
    $user->getEventManager()->attach(new UserListener())
    

با انجام این کد ها هر زمانی که یک کاربر ایجاد می شود ، این شنونده و تمام شنونده هایی که به این رویداد پیوست شده اند اجرا خواهند شد .


postLink در فرم هلپر کیک پی اچ پی

این متد یک لینک اچ تی ام ال ایجاد میکند که دسترسی به آن از طریق متد post پست خواهد بود . این متد یک تگ فرم ایجاد خواهد کرد، پس برای استفاده از این متد توجه داشته باشید که در داخل یک تگ فرم این لینک را ایجاد نکنید. در عوض می توانید از یک دکمه submit در فرم خود استفاده کنید.


تابع strcasecmp در php

این تابع در Php دو رشته را به هم مقایسه می کند، بدون در نظر گرفتن حروف کوچک و بزرگ .

  • اگر دو مقدار برابر باشند، مقدار صفر را بر میگرداند
  • اگر رشته اول بزرگتر از دومی باشد ، مقدار مثبت بر میگرداند ( عدد مثبت نشان دهنده مقدار کاراکترهای اضافی آن است .
  • اگر رشته دوم بزرگتر باشد ، مقدار منفی بر می گرداند .