Oxwall は Skalfa LLC が開発している PHP製のオープンソースフレームワークです。VirtualBox + CentOS 7に開発環境を構築して、プラグインチュートリアルを試した時のメモ書き。
* プラグイン開発のチュートリアルの詳細のコードの説明等は割愛しておりますので、内容を確認したい人は、直接、本家のチュートリアルを参照してください。
1. CentoOS-7 + VirtualBox 環境構築はこちらを参照してください
* アカウント名は、”oxwall”などに適宜変更してください。
2. AMPのインストール
2.1 PHP/HTTP install
[oxwall@localhost ~]$ sudo yum install -y epel-release [oxwall@localhost ~]$ sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm [oxwall@localhost ~]$ sudo yum -y install --enablerepo=remi,remi-php70 php php-devel php-mbstring php-pdo php-gd php-mysql php-xml [oxwall@localhost ~]$ sudo yum -y --enablerepo=remi,remi-php70 install php-pecl-zip [oxwall@localhost ~]$ sudo yum -y --enablerepo=remi,remi-php70 install php-pecl-mysql
2.2 MySQL install
[oxwall@localhost ~]$ sudo yum -y localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm [oxwall@localhost ~]$ sudo yum -y install mysql mysql-devel mysql-server mysql-utilities [oxwall@localhost ~]$ sudo systemctl start mysqld [oxwall@localhost ~]$ sudo systemctl enable mysqld [oxwall@localhost ~]$ sudo cat /var/log/mysqld.log | grep password 2018-01-29T02:35:32.202031Z 1 [Note] A temporary password is generated for root@localhost: o6K;lud#>kGa [oxwall@localhost ~]$ sudo mysql_secure_installation
* パスワード “o6K;lud#>kGa” は、MySQL(mysql_secure_installation)のセットアップで入力します。入力後、新しいパスワード(大文字+記号+数字+6文字以上)を設定、Remove Anonymous users、Disallow root login remotely、Remove test database and access to it、 Reload privilege tables now等を設定して終了。
2.3 HTTP setup
[oxwall@localhost ~]$ sudo vi /etc/httpd/conf/httpd.conf
151 AllowOverride All
[oxwall@localhost ~]$ sudo vi /etc/sysconfig/selinux
7 SELINUX=disabled
[oxwall@localhost ~]$ sudo systemctl start httpd [oxwall@localhost ~]$ sudo systemctl enable httpd [oxwall@localhost ~]$ sudo firewall-cmd --permanent --zone=public --add-service=http [oxwall@localhost ~]$ sudo firewall-cmd --reload
2.4 Reboot
[oxwall@localhost ~]$ sudo reboot
2.5 ここで、VirtualBoxの外から HTTPアクセス(192.168.56.101)が可能になります。
3. Oxwall インストール・セットアップ
3.1 Oxwall本体と phpMyAdminをダウンロードして解凍
[root@localhost ~]$ cd /var/www/html [root@localhost ~]$ sudo su [root@localhost html]# wget https://developers.oxwall.com/dl/oxwall-1.8.4.1.zip [root@localhost html]# unzip oxwall-1.8.4.1.zip [root@localhost html]# wget https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.tar.gz [root@localhost html]# tar -xvzf phpMyAdmin-latest-all-languages.tar.gz [root@localhost html]# mv phpMyAdmin-4.7.7-all-languages phpMyAdmin [root@localhost html]# sudo groupadd www [root@localhost html]# sudo usermod -a -G www oxwall [root@localhost html]# sudo chown -R root:www /var/www [root@localhost html]# sudo chmod 2775 /var/www
[root@localhost html]# vi .htaccess
14 RewriteCond %{REQUEST_URI} !(^/phpMyAdmin/)
3.1 データベースを作成shます。http://192.168.56.101/phpMyAdmin へアクセスして、rootでログインします。
3.2 MySQL DBを作成します。 [New ] -> Name: oxwall_db , Collation: utf8_general_ci -> [Create]
3.3 HTTPを再起動
[root@localhost html]# systemctl restart httpd
3.4 http://192.168.56.101 へアクセスするとセットアップが開始します。
3.5 適切な情報を入力して -> [CONTINUE]
3.6 先ほど作成したデータベースの情報を入力 -> [CONTINUE]
3.6 スクロールビューの中身をコピーして、ow_includes/config.phpへ貼り付け
3.7 Cronの設定
[root@localhost html]# crontab -e
*/1 * * * * /bin/php /var/www/html/ow_cron/run.php
3.7 Install folderを削除してから、ページを再読み込みします。
[root@localhost html]# rm -rf ow_install
4. プラグイン開発
4.1 Developer keyを取得します。Oxwall Store へアクセスします。
– サインアップします(必要な情報を入力してください)※登録は無料
– [STORE] -> [DEVELOPER TOOL] と移動して、”Your Developer Key”の下の部分をコピーしておきます。
4.3 Plugin files 用のフォルダを作成し、必要なファイルを生成します。
[root@localhost html]# cd /var/www/html/ow_plugins [root@localhost ow_plugins]# mkdir crashcourse [root@localhost ow_plugins]# cd crashcourse [root@localhost crashcourse]# touch init.php
[root@localhost crashcourse]# vi plugin.xml
<?xml version="1.0" encoding="UTF-8"?> <plugin> <name>Crash Course</name> <key>crashcourse</key> <description>"Tutorial" page with the ability to choose departments (email addresses).</description> <author>UBUNIFU INC.</author> <authorEmail>xxx@ubunifu.co</authorEmail> <authorUrl>https://ubunifu.co</authorUrl> <developerKey>your_developer_key_here</developerKey> <build>1</build> <copyright>(C) 2018 UBUNIFU INC. All rights reserved.</copyright> <license>The BSD License</license> <licenseUrl>http://www.opensource.org/licenses/bsd-license.php</licenseUrl> </plugin>
[root@localhost crashcourse]# touch install.php [root@localhost crashcourse]# touch uninstall.php [root@localhost crashcourse]# touch activate.php [root@localhost crashcourse]# touch deactivate.php
[root@localhost crashcourse]# echo "<?php" >> install.php [root@localhost crashcourse]# echo "BOL_LanguageService::getInstance()->addPrefix('crashcourse', 'Crash Course');" >> install.php
4.4 Plugin installation ※この状態でプラグインのインストールを試す事が出来ます。
– Go to Admin area → Plugins → Available Plugins. Click Install on your new plugin.
4.5 Creating a page
[root@localhost crashcourse]# mkdir controllers [root@localhost crashcourse]# mkdir views [root@localhost crashcourse]# mkdir views/controllers [root@localhost crashcourse]# touch controllers/crash.php [root@localhost crashcourse]# touch views/controllers/crash_index.html
[root@localhost crashcourse]# vi controllers/crash.php
<?php class CRASHCOURSE_CTRL_Crash extends OW_ActionController { public function index() { $this->setPageTitle(OW::getLanguage()->text('crashcourse', 'index_page_title')); $this->setPageHeading(OW::getLanguage()->text('crashcourse', 'index_page_heading')); } }
– http://192.168.56.101/crashcourse/crash/index へアクセスします。
– プロフィールの情報を聞かれたら適当な値を入力し -> [CONTINUE]
– http://192.168.56.101/crashcourse/crash/index (再度、アクセス)
* この説明の中ではローカライゼーションは省いています。ローカライゼーションも試したい方は、ここにアクセスし、http://192.168.56.101/admin/settings/dev-tools/languages Keyと Textのペアを追加してください。尚、UNINSTALLすると消えてしまうので、EXPORTしておくことをおすすめします(この話は、別の機会にでも)
4.6 Page routing
– リダイレクトを指定します
[root@localhost crashcourse]# vi init.php
<?php OW::getRouter()->addRoute(new OW_Route('crashcourse.index', 'crash', "CRASHCOURSE_CTRL_Crash", 'index'));
– http://192.168.56.101/crash こちらのアドレスでアクセスが可能になりました。
– 下部のメニューにリンクを追加します。
[root@localhost crashcourse]# vi activate.php
<?php OW::getNavigation()->addMenuItem(OW_Navigation::BOTTOM, 'crashcourse.index', 'crashcourse', 'bottom_menu_item', OW_Navigation::VISIBLE_FOR_ALL);
[root@localhost crashcourse]# vi deactivate.php
<?php OW::getNavigation()->deleteMenuItem('crashcourse', 'bottom_menu_item');
– [Installed plugins] ページにいき、Crash Courseを一旦 DEACTIVATEして、再び、ACTIVATEします。この段階で、下部のメニューに追加されたことがわかります。
4.7 Using forms
– 問い合わせフォームのメインページを作成していきます。まずは、Controller から。
[root@localhost crashcourse]# vi controllers/crash.php
<?php class CRASHCOURSE_CTRL_Crash extends OW_ActionController { public function index() { $this->setPageTitle(OW::getLanguage()->text('crashcourse', 'index_page_title')); $this->setPageHeading(OW::getLanguage()->text('crashcourse', 'index_page_heading')); $contactEmails = array( 'admin@site.com' => 'Site administration', 'support@site.com' => 'Technical support', 'billing@site.com' => 'Billing department' ); $form = new Form('contact_form'); $fieldTo = new Selectbox('to'); foreach ( $contactEmails as $email => $label ) { $fieldTo->addOption($email, $label); } $fieldTo->setRequired(); $fieldTo->setHasInvitation(false); $fieldTo->setLabel($this->text('crashcourse', 'form_label_to')); $form->addElement($fieldTo); $fieldFrom = new TextField('from'); $fieldFrom->setLabel($this->text('crashcourse', 'form_label_from')); $fieldFrom->setRequired(); $fieldFrom->addValidator(new EmailValidator()); $form->addElement($fieldFrom); $fieldSubject = new TextField('subject'); $fieldSubject->setLabel($this->text('crashcourse', 'form_label_subject')); $fieldSubject->setRequired(); $form->addElement($fieldSubject); $fieldMessage = new Textarea('message'); $fieldMessage->setLabel($this->text('crashcourse', 'form_label_message')); $fieldMessage->setRequired(); $form->addElement($fieldMessage); // Using captcha here to prevent bot spam $fieldCaptcha = new CaptchaField('captcha'); $fieldCaptcha->setLabel($this->text('crashcourse', 'form_label_captcha')); $form->addElement($fieldCaptcha); $submit = new Submit('send'); $submit->setValue($this->text('crashcourse', 'form_label_submit')); $form->addElement($submit); $this->addForm($form); if ( OW::getRequest()->isPost() ) { if ( $form->isValid($_POST) ) { $data = $form->getValues(); $mail = OW::getMailer()->createMail(); $mail->addRecipientEmail($data['to']); $mail->setSender($data['from']); $mail->setSubject($data['subject']); $mail->setTextContent($data['message']); OW::getMailer()->addToQueue($mail); OW::getSession()->set('crashcourse.dept', $contactEmails[$data['to']]); $this->redirectToAction('sent'); } } } public function sent() { $dept = null; if ( OW::getSession()->isKeySet('crashcourse.dept') ) { $dept = OW::getSession()->get('crashcourse.dept'); OW::getSession()->delete('crashcourse.dept'); } else { $this->redirectToAction('index'); } $feedback = $this->text('crashcourse', 'message_sent', ( $dept === null ) ? null : array('dept' => $dept)); $this->assign('feedback', $feedback); } private function text( $prefix, $key, array $vars = null ) { return OW::getLanguage()->text($prefix, $key, $vars); } }
– 次に Viewを作成します
[root@localhost crashcourse]# vi views/controllers/crash_index.html
{form name='contact_form'} <table class="ow_table_1 ow_form ow_automargin ow_superwide"> <tr class="ow_alt1"> <td class="ow_label">{label name='to'}</td> <td class="ow_value">{input name='to'}{error name='to'}</td> </tr> <tr class="ow_alt2"> <td class="ow_label">{label name='from'}</td> <td class="ow_value">{input name='from'}{error name='from'}</td> </tr> <tr class="ow_alt1"> <td class="ow_label">{label name='subject'}</td> <td class="ow_value">{input name='subject'}{error name='subject'}</td> </tr> <tr class="ow_alt2"> <td class="ow_label">{label name='message'}</td> <td class="ow_value">{input name='message'}{error name='message'}</td> </tr> <tr class="ow_alt1"> <td class="ow_label">{label name='captcha'}</td> <td class="ow_value ow_center">{input name='captcha'}{error name='captcha'}</td> </tr> <tr> <td class="ow_center" colspan="2">{submit name='send' class='ow_button ow_ic_mail'}</td> </tr> </table> {/form}
– 送信ボタンが押下された Viewを作成します
[root@localhost crashcourse]# vi views/controllers/crash_sent.html
<div class="ow_center">{$feedback}</div>
4.8 キャッシュクリアを行うプラグインをインストールします ※ここで長い時間はまったのですが、Oxwallは、Controllerや Viewをキャッシュしている為、クリアしてあげないと、変更した内容が反映されませんのでご注意ください。
– https://developers.oxwall.com/store/item/579 へアクセス
– ダウンロードボタンをクリックしてプラグインをダウンロード
– プラグインをアップロードする為に、FTPの設定を行います
[root@localhost html]# yum install -y vsftpd ftp
[root@localhost html]# vi /etc/vsftpd/user_list
#root
[root@localhost html]# vi /etc/vsftpd/ftpusers
#root
[root@localhost html]# echo "setsebool -P ftp_home_dir on" >> /etc/sysconfig/selinux [root@localhost html]# firewall-cmd --permanent --add-port=21/tcp [root@localhost html]# firewall-cmd --reload [root@localhost html]# systemctl enable vsftpd [root@localhost html]# systemctl start vsftpd
– [Add new] -> [Choose file] -> “Casheextreme.zip” -> [UPLOAD]
– FTPに失敗しますので正しいログイン情報を入力します。host: 192.168.56.101, Login: root, Password: ****, -> [ENTER]
– アップロードできたら [Available Plugin]から [INSTALL]
– [Installed Plugin] -> Cache Extreme -> [SETTINGS] -> [CLEAN IT UP] でキャッシュクリア
– http://192.168.56.101/crash フォームの表示が出来ました
4.9 Using database
– 現状では、宛先がハードコーディングされているので、宛先をデータベースへ格納する為の処理を作成します。
[root@localhost crashcourse]# mkdir bol [root@localhost crashcourse]# touch bol/department.php [root@localhost crashcourse]# touch bol/department_dao.php [root@localhost crashcourse]# touch bol/service.php
[root@localhost crashcourse]# vi bol/department.php
<?php class CRASHCOURSE_BOL_Department extends OW_Entity { /** * @var string */ public $email; }
[root@localhost crashcourse]# vi bol/department_dao.php
<?php class CRASHCOURSE_BOL_DepartmentDao extends OW_BaseDao { /** * Constructor. * */ protected function __construct() { parent::__construct(); } /** * Singleton instance. * * @var CRASHCOURSE_BOL_DepartmentDao */ private static $classInstance; /** * Returns an instance of class (singleton pattern implementation). * * @return CRASHCOURSE_BOL_DepartmentDao */ public static function getInstance() { if ( self::$classInstance === null ) { self::$classInstance = new self(); } return self::$classInstance; } /** * @see OW_BaseDao::getDtoClassName() * */ public function getDtoClassName() { return 'CRASHCOURSE_BOL_Department'; } /** * @see OW_BaseDao::getTableName() * */ public function getTableName() { return OW_DB_PREFIX . 'crashcourse_department'; } }
[root@localhost crashcourse]# vi bol/service.php
<?php class CRASHCOURSE_BOL_Service { /** * Singleton instance. * * @var CRASHCOURSE_BOL_Service */ private static $classInstance; /** * Returns an instance of class (singleton pattern implementation). * * @return CRASHCOURSE_BOL_Service */ public static function getInstance() { if ( self::$classInstance === null ) { self::$classInstance = new self(); } return self::$classInstance; } private function __construct() { } public function getDepartmentLabel( $id ) { return OW::getLanguage()->text('crashcourse', $this->getDepartmentKey($id)); } public function addDepartment( $email, $label ) { $contact = new CRASHCOURSE_BOL_Department(); $contact->email = $email; CRASHCOURSE_BOL_DepartmentDao::getInstance()->save($contact); BOL_LanguageService::getInstance()->addValue( OW::getLanguage()->getCurrentId(), 'crashcourse', $this->getDepartmentKey($contact->id), trim($label)); } public function deleteDepartment( $id ) { $id = (int) $id; if ( $id > 0 ) { $key = BOL_LanguageService::getInstance()->findKey('crashcourse', $this->getDepartmentKey($id)); BOL_LanguageService::getInstance()->deleteKey($key->id, true); CRASHCOURSE_BOL_DepartmentDao::getInstance()->deleteById($id); } } private function getDepartmentKey( $name ) { return 'dept_' . trim($name); } public function getDepartmentList() { return CRASHCOURSE_BOL_DepartmentDao::getInstance()->findAll(); } }
[root@localhost crashcourse]# vi install.php
<?php BOL_LanguageService::getInstance()->addPrefix('crashcourse', 'Crash Course'); $sql = "CREATE TABLE `" . OW_DB_PREFIX . "crashcourse_department` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `email` VARCHAR(200) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM ROW_FORMAT=DEFAULT"; OW::getDbo()->query($sql);
4.10 Creating Settings page in Admin area
– 宛先を入力する管理画面の Controller を作成します
[root@localhost crashcourse]# vi controllers/admin.php
<?php class CRASHCOURSE_CTRL_Admin extends ADMIN_CTRL_Abstract { public function dept() { $this->setPageTitle(OW::getLanguage()->text('crashcourse', 'admin_dept_title')); $this->setPageHeading(OW::getLanguage()->text('crashcourse', 'admin_dept_heading')); $contactEmails = array(); $deleteUrls = array(); $contacts = CRASHCOURSE_BOL_Service::getInstance()->getDepartmentList(); foreach ( $contacts as $contact ) { /* @var $contact CRASHCOURSE_BOL_Department */ $contactEmails[$contact->id]['name'] = $contact->id; $contactEmails[$contact->id]['email'] = $contact->email; $contactEmails[$contact->id]['label'] = CRASHCOURSE_BOL_Service::getInstance()->getDepartmentLabel($contact->id); $deleteUrls[$contact->id] = OW::getRouter()->urlFor(__CLASS__, 'delete', array('id' => $contact->id)); } $this->assign('contacts', $contactEmails); $this->assign('deleteUrls', $deleteUrls); $form = new Form('add_dept'); $this->addForm($form); $fieldEmail = new TextField('email'); $fieldEmail->setRequired(); $fieldEmail->addValidator(new EmailValidator()); $fieldEmail->setInvitation(OW::getLanguage()->text('crashcourse', 'label_invitation_email')); $fieldEmail->setHasInvitation(true); $form->addElement($fieldEmail); $fieldLabel = new TextField('label'); $fieldLabel->setRequired(); $fieldLabel->setInvitation(OW::getLanguage()->text('crashcourse', 'label_invitation_label')); $fieldLabel->setHasInvitation(true); $form->addElement($fieldLabel); $submit = new Submit('add'); $submit->setValue(OW::getLanguage()->text('crashcourse', 'form_add_dept_submit')); $form->addElement($submit); if ( OW::getRequest()->isPost() ) { if ( $form->isValid($_POST) ) { $data = $form->getValues(); CRASHCOURSE_BOL_Service::getInstance()->addDepartment($data['email'], $data['label']); $this->redirect(); } } } public function delete( $params ) { if ( isset($params['id']) ) { CRASHCOURSE_BOL_Service::getInstance()->deleteDepartment((int) $params['id']); } $this->redirect(OW::getRouter()->urlForRoute('crashcourse.admin')); } }
– 管理画面の Viewを作成します
[root@localhost crashcourse]# vi views/controllers/admin_dept.html
<table class="ow_table_1 ow_automargin" style="width: 400px;"> {foreach from=$contacts item=contact} <tr class="{cycle values='ow_alt1,ow_alt2'}"> <td width="1"><a href="{$deleteUrls[$contact.name]}" onclick="return confirm('{text key="base+are_you_sure"}');" style="width:16px; height:16px; display:block; margin:0 auto;background-repeat:no-repeat;background-position: 50% 50%;" class="ow_ic_delete"></a></td> <td>{$contact.email}</td> <td>{$contact.label}</td> </tr> {/foreach} </table> {form name='add_dept'} <table class="ow_table_1 ow_form ow_automargin" style="width: 400px;"> <tr class="ow_alt1"> <td class="ow_value">{input name='email'}</td> <td class="ow_value">{input name='label'}</td> </tr> <tr> <td class="ow_center" colspan="2">{submit name='add' class='ow_button ow_ic_save'}</td> </tr> </table> {/form}
– 再びキャッシュをクリアします(やり方は上部参照)
– [Installed plugin] -> Crash Course -> [UNINSTALL]
– [Available plugin] -> Crash Course -> [INSTALL]
– http://192.168.56.101/crashcourse/admin/dept 管理画面が表示されます。部署名とメールアドレスを指定して [SUBMIT]すると登録されます。
– ハードコーディングされている箇所 controllers/crash.php を修正します
[root@localhost crashcourse]# vi controllers/crash.php
<?php class CRASHCOURSE_CTRL_Crash extends OW_ActionController { public function index() { $this->setPageTitle(OW::getLanguage()->text('crashcourse', 'index_page_title')); $this->setPageHeading(OW::getLanguage()->text('crashcourse', 'index_page_heading')); $contactEmails = array(); $contacts = CRASHCOURSE_BOL_Service::getInstance()->getDepartmentList(); foreach ( $contacts as $contact ) { /* @var $contact CRASHCOURSE_BOL_Department */ $contactEmails[$contact->email] = CRASHCOURSE_BOL_Service::getInstance()->getDepartmentLabel($contact->id); } $form = new Form('contact_form'); $fieldTo = new Selectbox('to'); foreach ( $contactEmails as $email => $label ) { $fieldTo->addOption($email, $label); } $fieldTo->setRequired(); $fieldTo->setHasInvitation(false); $fieldTo->setLabel($this->text('crashcourse', 'form_label_to')); $form->addElement($fieldTo); $fieldFrom = new TextField('from'); $fieldFrom->setLabel($this->text('crashcourse', 'form_label_from')); $fieldFrom->setRequired(); $fieldFrom->addValidator(new EmailValidator()); $form->addElement($fieldFrom); $fieldSubject = new TextField('subject'); $fieldSubject->setLabel($this->text('crashcourse', 'form_label_subject')); $fieldSubject->setRequired(); $form->addElement($fieldSubject); $fieldMessage = new Textarea('message'); $fieldMessage->setLabel($this->text('crashcourse', 'form_label_message')); $fieldMessage->setRequired(); $form->addElement($fieldMessage); // Using captcha here to prevent bot spam $fieldCaptcha = new CaptchaField('captcha'); $fieldCaptcha->setLabel($this->text('crashcourse', 'form_label_captcha')); $form->addElement($fieldCaptcha); $submit = new Submit('send'); $submit->setValue($this->text('crashcourse', 'form_label_submit')); $form->addElement($submit); $this->addForm($form); if ( OW::getRequest()->isPost() ) { if ( $form->isValid($_POST) ) { $data = $form->getValues(); $mail = OW::getMailer()->createMail(); $mail->addRecipientEmail($data['to']); $mail->setSender($data['from']); $mail->setSubject($data['subject']); $mail->setTextContent($data['message']); OW::getMailer()->addToQueue($mail); OW::getSession()->set('crashcourse.dept', $contactEmails[$data['to']]); $this->redirectToAction('sent'); } } } public function sent() { $dept = null; if ( OW::getSession()->isKeySet('crashcourse.dept') ) { $dept = OW::getSession()->get('crashcourse.dept'); OW::getSession()->delete('crashcourse.dept'); } else { $this->redirectToAction('index'); } $feedback = $this->text('crashcourse', 'message_sent', ( $dept === null ) ? null : array('dept' => $dept)); $this->assign('feedback', $feedback); } private function text( $prefix, $key, array $vars = null ) { return OW::getLanguage()->text($prefix, $key, $vars); } }
– http://192.168.56.101/crash へアクセスすると、宛先がプルダウン(登録してある場合)表示されます。
– [SETTING]ボタンを追加します
[root@localhost crashcourse]# vi init.php
<?php OW::getRouter()->addRoute(new OW_Route('crashcourse.index', 'crash', "CRASHCOURSE_CTRL_Crash", 'index')); OW::getRouter()->addRoute(new OW_Route('crashcourse.admin', 'admin/plugins/crashcourse', "CRASHCOURSE_CTRL_Admin", 'dept'));
[root@localhost crashcourse]# vi install.php
<?php BOL_LanguageService::getInstance()->addPrefix('crashcourse', 'Crash Course'); $sql = "CREATE TABLE `" . OW_DB_PREFIX . "crashcourse_department` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `email` VARCHAR(200) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM ROW_FORMAT=DEFAULT"; OW::getDbo()->query($sql); OW::getPluginManager()->addPluginSettingsRouteName('crashcourse', 'crashcourse.admin');
– 再びキャッシュクリア
– [Installed plugin] -> Crash Course -> [UNINSTALL]
– [Available plugin] -> Crash Course -> [INSTALL]
– [Installed plugin] -> Crash Course -> [SETTINGS]
以上、長かったですが。これでチュートリアルのチュートリアルは終わりです 😃 お疲れ様でした.
- Tags
- CentOS, Oxwall, VirtualBox