Tagalog (Wikang Tagalog) translation by Anna Nelson (you can also view the original English article)



Ang tutorial na ito ay bahagi ngserye tungkol sa pagbuo ng iyong startup gamit ang PHP sa Envato Tuts+. Sa seryeng ito, gagabayan ko kayo sa paglulunsad ng isang startup mula sa konsepto sa kasalukuyan gamit ang aking Meeting Planner app bilang isang makatotohanan na halimbawa. Bawat hakbang sa kahabaan ng proseso, ibibigay ko ang open-source code ng aking Meeting Planner app bilang halimbawa kung saan maaari mong malaman ang pinagmulan. Tatalakayin ko din angmga isyu tungkol sa negosyo kung meron tayong madaanan.
Paano diskartehan ang
mga Major na Feature Update
Nitong mga nakalipas na araw kadalasan ay nagtatrabaho ako upang magdagdag ng maliit na incremental pagsasaayos sa aking Meeting Planner. Gumagana naman ang mga basic at sinusubukan ko mgdagdag unti-unti para mapaganda ang application base sa aking pananaw at puna ng mga tao. Kung minsan, ang aking pangarap ay para sa isang mas malaking pagbabago, at ito ngayon ay maaaring maging mas mahirap na dahil ang codebase ay masyado na lumago.
Sa tutorial ngayon, ang aking tatalakayin ay tungkol sa mga paraan kung paano mag-isip para makagawa ng mga mas malaking mga pagbabago sa isang umiiral na codebase. Sa partikular, ituturo sa iyo ang mga epekto ng pagdagdag ng kakayahan para sa pagtugon sa mga kalahok para magisip ng mgkakasama at magpasya sa mga gawain, ibig sabihin, ano ang dapat nating gawin kapag nagkikita.
Kung hindi mo pa nagagawa, subukan na mag-iskedyul ng isang pulong, at ngayon ay maaari mo ring mag-iskedyul ng aktibidad. Matutulungan ka nitong maunawaan kung paano sa pamamagitan ng tutorial na ito.
Bago namin simulan, huwag kalimutan na ibahagi ang iyong mga komento at puna sa ibaba. Sinusubaybayan ko ang mga ito, at maaari mo ring maabot ako Twitter @lookahead_io. Mas lalo akong interesado kung nais mo magmungkahi ng mga bagong tampok o mga paksa para sa hinaharap na mga tutorial.
Bilang paalala, ang lahat ng mga code para sa Meeting Planner ay nakasulat sa Yii2 Framework para sa PHP. Kung gusto mong matuto nang iba pa tungkol sa Yii2, tingnan ang aming parallel series Programming Sa Yii2.
Ang Aktibidad Planning Tampok



Talaga, Meeting Planner at Simpleng Planner ay dinisenyo upang gumawa ng pag-iiskedyul ng kasing-dali ng ito ay maaaring maging. Imungkahi sa iyo ng ilang oras at lugar at ibahagi ito sa isa pang tao para sa kanila upang timbangin in sa mga pagpipilian. Pagkatapos, magpasya ka na magkakasama, at Tagaplano ng Meeting Sinusubaybayan na may mga entry sa kalendaryo, mga paalala at mga simpleng paraan upang gumawa ng mga pagsasaayos pagkatapos ng katotohanan.
Bilang halimbawa, narito ang isang video ng pag-iiskedyul ng para sa mga grupo:
Nais kong palawakin ang pag-iiskedyul ng suporta na ibinigay para sa oras at lugar na ang konsepto ng mga gawain. Halimbawa, kapag pagpaplano ng isang meetup sa iyong mga kaibigan, mahalagang kayo ay humihiling, dapat naming pumunta sa mga pelikula, magsayaw o snowboarding.
Sa ibang salita, nais kong lumikha ng isang panel tulad ng isa para sa mga oras na ipinapakita sa ibaba ngunit para sa mga aktibidad:



Ang MVC architecture at ang aking code pagpapangalan scheme ay katulad na katulad sa pagitan ng mga oras ng pagpupulong at mga lugar, kaya gusali na gawain tila medyo simpleng sa ibabaw. Gayunpaman, ang desisyon na gawin ito ay may malawak na ramifications.
Ang Pagtingin sa mga Pagbabago
Mahalaga kapag magdadagdag ng isang malaking tampok ay isipin kung saan ilalagay ang code na kailangang baguhin at ang lahat ng mga lugar sa iyong application na maaaring maapekyuhan sa gagawing pagbabago.
Epekto sa pagharap sa customer
Mula sa anggulo ng disenyo,inisip ko kung paano makakaapekto ang mga gawain sa mga serbisyong humaharap sa customer:
- Babaguhin nito ang pag-aayos ng isang pulong upang payagan ang isang bagong uri, ang isang aktibidad na hinihimok ng kaganapan. Magkakaroon ng dagdag na panel sa pahina ng pagpaplano.
- Ang panel na aktibidad ay kailangang dinisenyo upang payagan ang mga tao upang pumili mula sa mga default o i-customize at idagdag ang kanilang mga sarili, hal backcountry skiing sa halip na lamang skiing, "Manuod ng Star Wars Rogue One" sa halip na "Manuod ng isang pelikula."
- Ang mga imbitasyon sa Email at kailangang meron ng puwang para sa listahan ng pagpipilian na aktibidad.
- Mga kaganapan sa kalendaryo ay nais na isama sa napiling aktibidad sa mga paksa ng meetup.
- Ang mga nagtatag ay maaaring mag nais na magpadala ng ilang mga ideya ng aktibidad sa isang kaibigan o isang pangkat na wala pang pinipiling isang lugar, kailangan ko payagan ito. Sa kasalukuyan, ang sistema ay hindi nagpapahintulot na magpadala ng imbitasyon hanggang sa magkaroon ng oras at lugar iminungkahing.
- Kung ang isang tao ay humiling ng isang pagbabago sa isang pulong, ang suporta para sa mga kahilingan sa pagbabago ay kailangang may suporta sa mga gawain kung ito ay pinalawak.
Ang mga ito ang karamihan sa mga pangunahing kaalaman. Ngayon, isipin natin ang tungkol sa code.
Epekto ng Codes
Pagsanga ng Source Code
Madalas, makakatulong magpalago ng iyong sariling code sa GitHub para maaari kang gumawa ng bagong tampok habang nagtatatag na produksyon sa antas ng codebase. Pinapayagan ka nito na bumalik at ayusin ang mga bug o gumawa ng mas maliit na incremental pagbabago habang nagtatrabaho sa isang malaking pagbabago. Ang mga tao sa GitHub ay mahigpit upang makatiyak na maintindihan ang kahalagahan ng mga koponan:
Mayroon lamang isang panuntunan: ang anumang bagay samaster
branch ay laging deployable.
Dahil ako ay nagiisa lamang at ako ay medyo magaling sa pamamahala ng aking codebase, ako ay medyo walang pakialam sa panuntunang ito.
Ngunit ang pagsanga ng code ay kapaki-pakinabang para sa pagsusuri ng mga pagbabago sa code kapag ikaw ay handa ng subukan ito. Magpapakita ako ng isang demonstration tungkol dito sa dulo ng tutorial ngayon.
Paggaya sa Common Code
Magkakaroon ng dalawang uri ng mga pulong ngayon: mga batay sa mga petsa at oras at ang mga nakapaligid na mga gawain, mga petsa, at oras. Kaya ang pulong ng modelo ay kailangang iangkop.
Para sa oras at lugar, may mga partikular na mga modelo MeetingTime at MeetingPlace pati na rin ang mga modelo para sa mga kagustuhan para sa mga sa mga kalahok, na tinatawag na MeetingTimeChoices at MeetingPlaceChoices. Maaari mong basahin ang higit pa tungkol sa pagbuo nito sa Building Your Startup With PHP: Scheduling Availability and Choices.
Kaya ang pagdaragdag ng mga gawain ay kailangan na doblehin ito, paglikha ng MeetingActivity at MeetingActivityChoices at ng kanilang kasamang controllers, mga modelo, mga tanawin, JavaScript at Ajax at database ng paglilipat.
Settings para sa Account at Meeting
Gayundin, ang mga organizers ay may preference ng iba't-ibang mga setting ng account at bawat setting para maaaring magmungkahi at pumili ang mga kalahok ng aktibidad sa pagpupulong.
Email Templates
Ang pagdagdag ng mga gawain ay makaka apekto sa mga template ng email para sa mga imbitasyon at nakumpleto pulong.
Kasaysayan at Logs ng Events
Dahil ang bawat pagbabago sa isang pulong ay naka-log, ang bawat pagpipilian na aktibidad at pagbabago ay kailangan din naka-log.
Iba pang mga Sari-saring Areas
Ang .ics Calendar file ay dapat na mabago upang isama ang aktibidad. Sa paglaon, ang API ay kailangang ma-update-at kahit na ang mga istatistika para sa administrative dashboard.
Habang ito ay tila simple kung titignant, ang pagdaragdag ng mga gawain ay talagang kinakailangan ng maraming bagong code at pagsubok.
Coding Highlights
Habang masyadong maraming bagong code para pagusapan sa isang tutorial, hana sa pamamagitan ng naka-highlight na mga aspeto mula sa ilan sa mga konsepto sa itaas.
Database Migrations
Una, nilikha ko ang database migrations. Kanina ay nabanggit ko ang paggaya sa code na merong mgkaparehong tampok na aspeto. Narito ang isang halimbawa ng MeetingActivity migration kumpara sa mga mas lumang mga MeetingTime table migration:
<?php use yii\db\Schema; use yii\db\Migration; class m161202_020757_create_meeting_activity_table extends Migration { public function up() { $tableOptions = null; if ($this->db->driverName === 'mysql') { $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; } $this->createTable('{{%meeting_activity}}', [ 'id' => Schema::TYPE_PK, 'meeting_id' => Schema::TYPE_INTEGER.' NOT NULL', 'activity' => Schema::TYPE_STRING.' NOT NULL', 'suggested_by' => Schema::TYPE_BIGINT.' NOT NULL', 'status' => Schema::TYPE_SMALLINT . ' NOT NULL DEFAULT 0', 'availability' => Schema::TYPE_SMALLINT . ' NOT NULL DEFAULT 0', 'created_at' => Schema::TYPE_INTEGER . ' NOT NULL', 'updated_at' => Schema::TYPE_INTEGER . ' NOT NULL', ], $tableOptions); $this->addForeignKey('fk_meeting_activity_meeting', '{{%meeting_activity}}', 'meeting_id', '{{%meeting}}', 'id', 'CASCADE', 'CASCADE'); $this->addForeignKey('fk_activity_suggested_by', '{{%meeting_activity}}', 'suggested_by', '{{%user}}', 'id', 'CASCADE', 'CASCADE'); } public function down() { $this->dropForeignKey('fk_activity_suggested_by', '{{%meeting_activity}}'); $this->dropForeignKey('fk_meeting_activity_meeting', '{{%meeting_activity}}'); $this->dropTable('{{%meeting_activity}}'); } }
Narito ang MeetingTime migration, at maaari mong makita ang pagkakatulad:
<?php use yii\db\Schema; use yii\db\Migration; class m141025_215833_create_meeting_time_table extends Migration { public function up() { $tableOptions = null; if ($this->db->driverName === 'mysql') { $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; } $this->createTable('{{%meeting_time}}', [ 'id' => Schema::TYPE_PK, 'meeting_id' => Schema::TYPE_INTEGER.' NOT NULL', 'start' => Schema::TYPE_INTEGER.' NOT NULL', 'suggested_by' => Schema::TYPE_BIGINT.' NOT NULL', 'status' => Schema::TYPE_SMALLINT . ' NOT NULL DEFAULT 0', 'created_at' => Schema::TYPE_INTEGER . ' NOT NULL', 'updated_at' => Schema::TYPE_INTEGER . ' NOT NULL', ], $tableOptions); $this->addForeignKey('fk_meeting_time_meeting', '{{%meeting_time}}', 'meeting_id', '{{%meeting}}', 'id', 'CASCADE', 'CASCADE'); $this->addForeignKey('fk_participant_suggested_by', '{{%meeting_time}}', 'suggested_by', '{{%user}}', 'id', 'CASCADE', 'CASCADE'); } public function down() { $this->dropForeignKey('fk_participant_suggested_by', '{{%meeting_time}}'); $this->dropForeignKey('fk_meeting_time_meeting', '{{%meeting_time}}'); $this->dropTable('{{%meeting_time}}'); } }
Sa huli, kailangan ko ng lima para sa mga sumusunod na bagong talahanayan:
- m161202_020757_create_meeting_activity_table
- m161202_021355_create_meeting_activity_choice_table, para sa pag-iimbak ng mga kagustuhan availability ng bawat kalahok pulong para sa bawat aktibidad
- m161202_024352_extend_meeting_setting_table_for_activities para sa mga setting ng isang partikular na pulong para sa pagdaragdag o pagpili ng mga gawain
- m161202_024403_extend_user_setting_table_for_activities para sa default na mga settingng account
- m161203_010030_extend_meeting_table_for_activitiesat para sa pagdaragdag is_activity upang tukuyin ang ari-arian ng isang pulong na may o walang isang aktibidad
$ ./yii migrate/up Yii Migration Tool (based on Yii v2.0.10) Total 5 new migrations to be applied: m161202_020757_create_meeting_activity_table m161202_021355_create_meeting_activity_choice_table m161202_024352_extend_meeting_setting_table_for_activities m161202_024403_extend_user_setting_table_for_activities m161203_010030_extend_meeting_table_for_activities Apply the above migrations? (yes|no) [no]:yes *** applying m161202_020757_create_meeting_activity_table > create table {{%meeting_activity}} ... done (time: 0.032s) > add foreign key fk_meeting_activity_meeting: {{%meeting_activity}} (meeting_id) references {{%meeting}} (id) ... done (time: 0.023s) > add foreign key fk_activity_suggested_by: {{%meeting_activity}} (suggested_by) references {{%user}} (id) ... done (time: 0.006s) *** applied m161202_020757_create_meeting_activity_table (time: 0.071s) *** applying m161202_021355_create_meeting_activity_choice_table > create table {{%meeting_activity_choice}} ... done (time: 0.002s) > add foreign key fk_mac_meeting_activity: {{%meeting_activity_choice}} (meeting_activity_id) references {{%meeting_activity}} (id) ... done (time: 0.006s) > add foreign key fk_mac_user_id: {{%meeting_activity_choice}} (user_id) references {{%user}} (id) ... done (time: 0.004s) *** applied m161202_021355_create_meeting_activity_choice_table (time: 0.016s) *** applying m161202_024352_extend_meeting_setting_table_for_activities > add column participant_add_activity smallint NOT NULL DEFAULT 0 to table {{%meeting_setting}} ... done (time: 0.013s) > add column participant_choose_activity smallint NOT NULL DEFAULT 0 to table {{%meeting_setting}} ... done (time: 0.019s) *** applied m161202_024352_extend_meeting_setting_table_for_activities (time: 0.034s) *** applying m161202_024403_extend_user_setting_table_for_activities > add column participant_add_activity smallint NOT NULL to table {{%user_setting}} ... done (time: 0.024s) > add column participant_choose_activity smallint NOT NULL to table {{%user_setting}} ... done (time: 0.027s) *** applied m161202_024403_extend_user_setting_table_for_activities (time: 0.055s) *** applying m161203_010030_extend_meeting_table_for_activities > add column is_activity smallint NOT NULL to table {{%meeting}} ... done (time: 0.019s) *** applied m161203_010030_extend_meeting_table_for_activities (time: 0.022s) 5 migrations were applied. Migrated up successfully.
Building MVC Framework para sa mga gawain



Ginamit ko ang kakayahan ng Yii Gii scaffolding na lumikha ng modelo, controller, at paunang mga tanawin. Tinalakay ko dati ang mga paglilipat at Gii mas maaga sa serye.
JavaScript at jQuery Pagbabago
At mayroon din namang matibay na pandagdag sa JavaScript at jQuery ginagamit, lalo na ngayon na nakikipag-ugnayan sa mga elemento ng pagpaplano para sa isang pulong na tapos na ay gumagamit ng Ajax, nang hindi na kailangan i-refresh ang pahina.
Dito, halimbawa, ay ang code loop upang makita kung ang isang pulong ng oras ay napili:
// respond to change in meeting_time $(document).on("click", '[id^=btn_mt_]', function(event) { current_id = $(this).attr('id'); $(this).addClass("btn-primary"); $(this).removeClass("btn-default"); $('[id^=btn_mt_]').each(function(index) { if ($(this).attr('id')!=current_id) { $(this).addClass("btn-default"); $(this).removeClass("btn-primary"); } }); $.ajax({ url: $('#url_prefix').val()+'/meeting-time/choose', data: {id: $('#meeting_id').val(), 'val': current_id}, success: function(data) { displayNotifier('choosetime'); refreshSend(); refreshFinalize(); return true; } }); });
Sa pamamagitan ng paggamit ng isang pangkaraniwang scheme para sa pagpapangalan, ang pagsulat ng code para sa mga aktibidad ay replicable mula sa:
// respond to change in meeting_activity $(document).on("click", '[id^=btn_ma_]', function(event) { current_id = $(this).attr('id'); $(this).addClass("btn-primary"); $(this).removeClass("btn-default"); $('[id^=btn_ma_]').each(function(index) { if ($(this).attr('id')!=current_id) { $(this).addClass("btn-default"); $(this).removeClass("btn-primary"); } }); $.ajax({ url: $('#url_prefix').val()+'/meeting-activity/choose', data: {id: $('#meeting_id').val(), 'val': current_id}, success: function(data) { displayNotifier('chooseactivity'); refreshSend(); refreshFinalize(); return true; } }); });
Iba pang mga pag-andar, tulad ng mga na ipakita ang mga tugon sa mga gumagamit, kailangan lang upang patagalin para sa mga aktibidad:
function displayNotifier(mode) { if (notifierOkay) { if (mode == 'time') { $('#notifierTime').show(); } else if (mode == 'place') { $('#notifierPlace').show(); } else if (mode == 'chooseplace') { $('#notifierChoosePlace').show(); } else if (mode == 'choosetime') { $('#notifierChooseTime').show(); } else if (mode == 'activity') { $('#notifierPlace').show(); } else if (mode == 'chooseactivity') { $('#notifierChooseActivity').show(); } else { alert("We\'ll automatically notify the organizer when you're done making changes."); } notifierOkay=false; } }
Kahit na may tampok na kaya reflective sa katangian ng umiiral nang mga tampok, ang mga karagdagan ng bagong code ay malawak. Narito ang higit pa sa mga JavaScript, halimbawa. Ang code na ito ay sumasaklaw ng maraming higit pa sa mga interactive na pag-andar ajax ng beses pagtugon sa pahina sa pagpaplano:
function showActivity() { if ($('#addActivity').hasClass( "hidden")) { $('#addActivity').removeClass("hidden"); $('.activity-form').removeClass("hidden"); } else { $('#addActivity').addClass("hidden"); $('.activity-form').addClass("hidden"); } }; function cancelActivity() { $('#addActivity').addClass("hidden"); $('.activity-form').addClass("hidden"); } function addActivity(id) { activity = $('#meeting_activity').val(); // ajax submit subject and message $.ajax({ url: $('#url_prefix').val()+'/meeting-activity/add', data: { id: id, activity: encodeURIComponent(activity), }, success: function(data) { $('#meeting_activity').val(''); loadActivityChoices(id); insertActivity(id); displayAlert('activityMessage','activityMsg1'); return true; } }); $('#addActivity').addClass('hidden'); } function insertActivity(id) { $.ajax({ url: $('#url_prefix').val()+'/meeting-activity/insertactivity', data: { id: id, }, type: 'GET', success: function(data) { $("#meeting-activity-list").html(data).removeClass('hidden'); $("input[name='meeting-activity-choice']").map(function(){ //$(this).bootstrapSwitch(); $(this).bootstrapSwitch('onText','<i class="glyphicon glyphicon-thumbs-up"></i> yes'); $(this).bootstrapSwitch('offText','<i class="glyphicon glyphicon-thumbs-down"></i> no'); $(this).bootstrapSwitch('onColor','success'); $(this).bootstrapSwitch('offColor','danger'); $(this).bootstrapSwitch('handleWidth',50); $(this).bootstrapSwitch('labelWidth',1); $(this).bootstrapSwitch('size','small'); }); }, }); refreshSend(); refreshFinalize(); } function getActivities(id) { $.ajax({ url: $('#url_prefix').val()+'/meeting-activity/getactivity', data: { id: id, }, type: 'GET', success: function(data) { $('#meeting-activity-list').html(data); }, }); }
Framework karagdagan
Tiyak, mayroong mga modelo, controllers at mga pagtingin na nagkaroon na idaragdag. Narito ang isang sipi mula sa modelo ng MeetingActivity.php na naglilista ng isang bilang ng mga default na aktibidad ang user ay maaaring gumamit ng mabilis na Typeahead:
<?php namespace frontend\models; use Yii; use yii\db\ActiveRecord; use common\components\MiscHelpers; use frontend\models\Participant; /** * This is the model class for table "{{%meeting_activity}}". * * @property integer $id * @property integer $meeting_id * @property string $activity * @property integer $availability * @property integer $suggested_by * @property integer $status * @property integer $created_at * @property integer $updated_at * * @property User $suggestedBy * @property Meeting $meeting * @property MeetingActivityChoice[] $meetingActivityChoices */ class MeetingActivity extends \yii\db\ActiveRecord { const STATUS_SUGGESTED =0; const STATUS_SELECTED =10; // the chosen date time const STATUS_REMOVED =20; const MEETING_LIMIT = 7; public $url_prefix; /** * @inheritdoc */ public static function tableName() { return '{{%meeting_activity}}'; } public function behaviors() { return [ /*[ 'class' => SluggableBehavior::className(), 'attribute' => 'name', 'immutable' => true, 'ensureUnique'=>true, ],*/ 'timestamp' => [ 'class' => 'yii\behaviors\TimestampBehavior', 'attributes' => [ ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'], ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'], ], ], ]; } /** * @inheritdoc */ public function rules() { return [ [['meeting_id', 'activity', 'suggested_by',], 'required'], [['meeting_id', 'suggested_by', 'status', 'created_at', 'updated_at'], 'integer'], [['activity'], 'string', 'max' => 255], [['suggested_by'], 'exist', 'skipOnError' => true, 'targetClass' => \common\models\User::className(), 'targetAttribute' => ['suggested_by' => 'id']], [['meeting_id'], 'exist', 'skipOnError' => true, 'targetClass' => Meeting::className(), 'targetAttribute' => ['meeting_id' => 'id']], ]; } public static function defaultActivityList() { $activities = [ Yii::t('frontend','Bachelor party'), Yii::t('frontend','Birthday party'), Yii::t('frontend','Breakfast'), Yii::t('frontend','Brunch'), Yii::t('frontend','Coffee, Tea, Juice Bar, et al.'), Yii::t('frontend','Concert'), Yii::t('frontend','Counseling'), Yii::t('frontend','Cycling'), Yii::t('frontend','Dessert'), Yii::t('frontend','Dinner'), Yii::t('frontend','Dog walking'), Yii::t('frontend','Drinks'), Yii::t('frontend','Dancing'), Yii::t('frontend','Bar'), Yii::t('frontend','Movies'), Yii::t('frontend','Happy hour'), Yii::t('frontend','Hiking'), Yii::t('frontend','Lunch'), Yii::t('frontend','Meditation'), Yii::t('frontend','Netflix and chill'), Yii::t('frontend','Party'), Yii::t('frontend','Protest'), Yii::t('frontend','Theater'), Yii::t('frontend','Play board games'), Yii::t('frontend','Play scrabble'), Yii::t('frontend','Play video games'), Yii::t('frontend','Running'), Yii::t('frontend','Shopping'), Yii::t('frontend','Skiing'), Yii::t('frontend','Snowboarding'), Yii::t('frontend','Snowshoeing'), Yii::t('frontend','Stand up comedy'), Yii::t('frontend','Walking'), Yii::t('frontend','Watch movies'), Yii::t('frontend','Watch sports'), Yii::t('frontend','Volunteer'), Yii::t('frontend','Yoga'), ]; return $activities; }



At narito ang isang
sipi ng /frontend/views/activity/_form.php sa TypeaheadBasic widget gamit ang
nasa itaas na defaultActivityList ()
:
<?php $activities=MeetingActivity::defaultActivityList(); echo $form->field($model, 'activity')->label(Yii::t('frontend','Suggest an activity'))->widget(TypeaheadBasic::classname(), [ 'data' => $activities, 'options' => ['placeholder' => Yii::t('frontend','enter your suggestions'), 'id'=>'meeting_activity', //'class'=>'input-large form-control' ], 'pluginOptions' => ['highlight'=>true], ]); ?>
Ngunit maraming mga
pagbabago sa code sa labas ng mga karaniwang pangangailangan ng framework.
Narito ang canSend()
modelo ng Meeting.php, ang function na tumutukoy kung ang
user ay pinapayagan upang magpadala ng isang imbitasyon para sa isang pulong. Tinutukoy nito kung
ang isang pulong ay nakamit ang minimum na mga kinakailangan para sa
pagpapadala, tulad ng pagkakaroon ng isang oras at aktibidad o oras at lugar.
Sa ibaba, maaari mong makita kung paano ang isang bagong seksyon ay maidagdag para sa mga aktibidad:
public function canSend($sender_id) { // check if an invite can be sent // req: a participant, at least one place, at least one time $cntPlaces = 0; foreach($this->meetingPlaces as $mp) { if ($mp->status!=MeetingPlace::STATUS_REMOVED) { $cntPlaces+=1; } } $cntTimes = 0; foreach($this->meetingTimes as $mt) { if ($mt->status!=MeetingTime::STATUS_REMOVED) { $cntTimes+=1; } } $cntActivities =0; // for either type of meeting if ($this->is_activity==Meeting::IS_ACTIVITY) { foreach($this->meetingActivities as $ma) { if ($ma->status!=MeetingActivity::STATUS_REMOVED) { $cntActivities+=1; } } } if ($this->owner_id == $sender_id && count($this->participants)>0 && ($cntPlaces>0 || $this->isVirtual() || ($this->is_activity == Meeting::IS_ACTIVITY && $cntActivities>0)) && $cntTimes>0 && ($this->is_activity == Meeting::NOT_ACTIVITY || ($this->is_activity == Meeting::IS_ACTIVITY && $cntActivities>0)) ) { $this->isReadyToSend = true; } else { $this->isReadyToSend = false; } return $this->isReadyToSend; }
Email Template
Ang pag-update sa mga layout ng email ay nangailangan ng konting pagiisip tungkol sa disenyo at kung paano pinakamahusay ipapakita ang mga gawain sa pagtugon sa mga paanyaya at mga pagkumpirma. Narito ang isang sample ng mga update ng email na imbitasyon:



Mahalaga, kung ang isang pulong ay isang aktibidad, pagkatapos ay ang imbitasyon ay nagsasama ng isang malawak na hanay sa itaas ng oras at lugar, muli kinokopya ng isang pulutong ng mga umiiral na code para sa mga oras at lugar:
<?php if ($is_activity==Meeting::IS_ACTIVITY) {?> <tr> <td style="color:#777; font-family:Helvetica, Arial, sans-serif; font-size:14px; line-height:21px; text-align:center; border-collapse:collapse; padding:8px 20px; width:280px" align="center" width="280"> <table cellspacing="0" cellpadding="0" width="100%" style="border-collapse:separate"> <tr> <td style="color:#777; font-family:Helvetica, Arial, sans-serif; font-size:14px; line-height:21px; text-align:center; border-collapse:collapse; background-color:#fff; border:1px solid #ccc; border-radius:5px; padding:12px 15px 15px; width:498px" align="center" bgcolor="#ffffff" width="498"> <table cellpadding="0" cellspacing="0" width="100%" style="border-collapse:collapse"> <tr> <td style="color:#777; font-family:Helvetica, Arial, sans-serif; font-size:14px; line-height:21px; text-align:left; border-collapse:collapse" align="left"> <span style="color:#4d4d4d; font-size:18px; font-weight:700; line-height:1.3; padding:5px 0">Possible Activities</span><br> <?php foreach($activities as $activity) { ?> <?php echo $activity->activity; ?><br /> <?php } ?> <br /> <?php if ($meetingSettings->participant_add_activity) { ?> <?php echo HTML::a(Yii::t('frontend','suggest an activity'),$links['addactivity']); ?><br /> <?php } ?> </td> </tr> </table> </td> </tr> </table> </td> </tr> <?php } ?>
Na sumasalamin sa Pagbabago
Sa paglaon, ang tampok na aktibidad ay nangangailangan ng isang malaking bagong sangay ng code. Narito ang mga pull request:
$ cd /var/www/mp && git pull origin master remote: Counting objects: 183, done. remote: Compressing objects: 100% (183/183), done. remote: Total 183 (delta 115), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (183/183), 111.48 KiB | 0 bytes/s, done. Resolving deltas: 100% (115/115), done. From github.com:newscloud/mp * branch master -> FETCH_HEAD 923b514..cd16262 master -> origin/master Updating 923b514..cd16262 Fast-forward common/components/MiscHelpers.php | 8 +-- common/mail/finalize-html.php | 28 ++++++++- common/mail/invitation-html.php | 39 ++++++++++++- composer.lock | 228 +++++++++++++++++++++++++++++++++++++----------------------------------- console/migrations/m161202_020757_create_meeting_activity_table.php | 35 +++++++++++ console/migrations/m161202_021355_create_meeting_activity_choice_table.php | 34 +++++++++++ console/migrations/m161202_024352_extend_meeting_setting_table_for_activities.php | 22 +++++++ console/migrations/m161202_024403_extend_user_setting_table_for_activities.php | 24 ++++++++ console/migrations/m161203_010030_extend_meeting_table_for_activities.php | 22 +++++++ frontend/assets/AppAsset.php | 2 +- frontend/assets/HomeAsset.php | 2 +- frontend/assets/MapAsset.php | 2 +- frontend/assets/MeetingAsset.php | 2 +- frontend/config/main.php | 1 + frontend/controllers/DaemonController.php | 2 +- frontend/controllers/MeetingActivityChoiceController.php | 70 ++++++++++++++++++++++ frontend/controllers/MeetingActivityController.php | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/controllers/MeetingController.php | 94 ++++++++++++++++++++++++++++-- frontend/controllers/MeetingTimeController.php | 4 +- frontend/models/Fix.php | 9 +-- frontend/models/Meeting.php | 125 ++++++++++++++++++++++++++++++++++------ frontend/models/MeetingActivity.php | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/models/MeetingActivityChoice.php | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/models/MeetingLog.php | 43 +++++++++++++- frontend/models/MeetingPlaceChoice.php | 3 +- frontend/models/MeetingTimeChoice.php | 3 +- frontend/models/Participant.php | 2 + frontend/views/meeting-activity/_choices.php | 42 ++++++++++++++ frontend/views/meeting-activity/_form.php | 46 +++++++++++++++ frontend/views/meeting-activity/_list.php | 78 +++++++++++++++++++++++++ frontend/views/meeting-activity/_panel.php | 81 ++++++++++++++++++++++++++ frontend/views/meeting-activity/_search.php | 39 +++++++++++++ frontend/views/meeting-activity/_thread.php | 15 +++++ frontend/views/meeting-activity/create.php | 21 +++++++ frontend/views/meeting-activity/index.php | 42 ++++++++++++++ frontend/views/meeting-activity/update.php | 23 ++++++++ frontend/views/meeting-setting/_form.php | 2 + frontend/views/meeting-time/_panel.php | 2 +- frontend/views/meeting-time/view.php | 4 +- frontend/views/meeting/_command_bar_planning.php | 11 +++- frontend/views/meeting/_grid.php | 9 ++- frontend/views/meeting/_panel_what.php | 1 + frontend/views/meeting/view.php | 22 +++++-- frontend/views/meeting/view_confirmed.php | 19 ++++++ frontend/views/meeting/viewactivity.php | 40 +++++++++++++ frontend/views/participant/_panel.php | 4 +- frontend/views/user-setting/_form.php | 7 ++- frontend/web/css/site.css | 9 ++- frontend/web/js/meeting.js | 284 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- 49 files changed, 2027 insertions(+), 257 deletions(-) create mode 100644 console/migrations/m161202_020757_create_meeting_activity_table.php create mode 100644 console/migrations/m161202_021355_create_meeting_activity_choice_table.php create mode 100644 console/migrations/m161202_024352_extend_meeting_setting_table_for_activities.php create mode 100644 console/migrations/m161202_024403_extend_user_setting_table_for_activities.php create mode 100644 console/migrations/m161203_010030_extend_meeting_table_for_activities.php create mode 100644 frontend/controllers/MeetingActivityChoiceController.php create mode 100644 frontend/controllers/MeetingActivityController.php create mode 100644 frontend/models/MeetingActivity.php create mode 100644 frontend/models/MeetingActivityChoice.php create mode 100644 frontend/views/meeting-activity/_choices.php create mode 100644 frontend/views/meeting-activity/_form.php create mode 100644 frontend/views/meeting-activity/_list.php create mode 100644 frontend/views/meeting-activity/_panel.php create mode 100644 frontend/views/meeting-activity/_search.php create mode 100644 frontend/views/meeting-activity/_thread.php create mode 100644 frontend/views/meeting-activity/create.php create mode 100644 frontend/views/meeting-activity/index.php create mode 100644 frontend/views/meeting-activity/update.php create mode 100644 frontend/views/meeting/viewactivity.php
Ito ay malaki kaya nagpasya ako na gumawa ng isang nakatutuwang video ng pag-scroll sa lahat ng mga pagbabago sa GitHub na may kasamang naaangkop na musikang tumutugtog sa background ... enjoy:
Sa pangkalahatan, ang pagtatayo ng mga aktibidad na tampok ay mahirap at kapaki-pakinabang para sa akin ang mag-isip tungkol sa site architecture at kung paano gumawa ng mabilis, matatag na pag-unlad sa codebase ng start-up na pang isang-tao. Gamitin paggaya, ngunit pagisipan muna ang pangkalahatang saklaw.
Ang tampok na aktibidad ay ngtalakay ng higit pang mga lugar kaysa sa inaasahan ko.
Ang pagpaplano nang maaga ay makakatulong sa iyo para maiwasan ang pagkakaipit sa walang katapusang coding traps para sa mga bagong tampok. Kung ikaw ay malagay sa isang malalim na kanal, isang bangungot ng coding na parang hindi natatapos, i-check mga pagbabago sa iyong mga tampok branch, bumalik sa master, at gumawa ng ibang bagay. Ito ay nakakatutulong upang ma-clear ang iyong ulo.
Ako ay bahagyang
naiba ng diskarte sa paggabay sa iyo sa episode na ito, at Umaasa ako na ito ay
kapaki-pakinabang.
Magkaroon ka bang mga sariling mga saloobin? Mga ideya? Feedback? Maaari mo akong maabot sa akin Twitter @lookahead_io direkta. Abangan ang ibang mga susunod na tutorial dito sa Building Your Startup With PHP series. Madami pang mga nakakagulat na bagay.
Muli, kung hindi mo pa nasubukan ang Meeting Planner o Simple Planner, sige at iiskedyul ang iyong unang pulong: