Crearea punerii în funcțiune trimiterea mementourilor

Ce veți crea

Acest tutorial face parte din programul Build Your Startup With PHP pe Envato Tuts +. În această serie, vă conduc prin lansarea unui startup de la concept la realitate, utilizând aplicația mea Planificator de întâlniri ca exemplu de viață reală. Fiecare pas de-a lungul drumului, voi lansa codul Planificatorului de Întâlniri ca exemple de sursă deschisă pe care le puteți învăța. Voi aborda, de asemenea, problemele de afaceri legate de pornire în momentul în care apar.

În acest tutorial în două părți, descriu cum am construit infrastructura pentru mementouri și livrarea lor. Astăzi, vă voi îndruma prin monitorizarea momentului de livrare a mementourilor și a modului de trimitere a e-mailurilor.

Dacă nu ați încercat încă Planificatorul de întâlniri, continuați și programați prima dvs. întâlnire. Particip la comentariile de mai jos, deci spune-mi ce crezi! Sunt interesat în special dacă doriți să sugerați noi caracteristici sau subiecte pentru tutoriale viitoare.

Ca un memento, întregul cod pentru Planificatorul întâlnirilor este scris în cadrul Yii2 Framework for PHP. Dacă doriți să aflați mai multe despre Yii2, consultați seria noastră paralelă Programming With Yii2.

Timp de monitorizare pentru mementouri

Odată cu trecerea timpului, trebuie să urmărim MeetingReminder tabelul pentru a ști când să livreze mementouri. În mod ideal, dorim ca mementourile să fie livrate exact la timp, de ex. la minut.

Rularea sarcinilor de fundal

Timpul de timp depinde de modul în care executăm în mod regulat sarcini de bază pentru monitorizare. În prezent, în stadiul nostru de pre-alfa, le conduc la fiecare cinci minute:

# m h dom mon dow comanda * / 5 * * * * wget -O / dev / null http://meetingplanner.io/daemon/frequent

Acest script solicită MeetingReminder :: check (), care găsește întâlniri de întâlnire care se datorează și solicită proces() lor:

/ / cron frecvente sarcină va apela pentru a verifica pe memento-uri cu caracter obligatoriu funcția statică funcția publică () $ mrs = MeetingReminder :: find () -> unde ('due_at<='.time().' and status='.MeetingReminder::STATUS_PENDING)->toate(); foreach ($ mrs ca $ mr) // procesează fiecare reamintire a întâlnirii MeetingReminder :: process ($ mr); 

Procesarea unei mementouri

MeetingReminder :: proces () adună detaliile necesare pentru a crea un e-mail de reamintire. Aceasta include destinatarul mementoului, detaliile întâlnirii și ora:

($ mr) // preluarea memento-ului // livrarea e-mailului sau a SMS-urilor // trimiterea actualizărilor despre schimbările recente ale întâlnirilor făcute de $ user_id $ user_id = $ mr-> user_id; $ meeting_id = $ mr-> meeting_id; $ mtg = Întâlnire :: findOne ($ meeting_id); // trimiteți doar mementouri pentru întâlniri confirmate dacă ($ mtg-> status! = Meeting :: STATUS_CONFIRMED) return false; // trimiteți doar memento-urile care au mai puțin de o zi întârziată - de făcut - eliminați după perioada de testare dacă (() () - ($ mr-> due_at)> (24 * 3600 + 1)) return false; $ u = \ common \ models \ Utilizator :: findOne ($ user_id); // asigurați-vă că există o cheie auth pentru utilizatorul destinatar dacă (gol ($ u-> auth_key)) return false;  // pregătește datele pentru mesaj // obține timpul $ select_time = Întâlnire :: getChosenTime ($ meeting_id); $ timezone = MiscHelpers :: fetchUserTimezone ($ user_id); $ display_time = Întâlnire :: friendlyDateFromTimestamp ($ selected_time-> start, $ timezone); // a lua locul $ selected_place = Întâlnire :: getChosenPlace ($ meeting_id); $ a = ['user_id' => $ user_id, 'auth_key' => $ u-> auth_key, 'email' => $ u-> email, 'username' => $ u-> username]; // verificați dacă e-mailul este bine și bine din acest sender_id dacă (User :: checkEmailDelivery ($ user_id, 0)) // Construiți linkurile absolute către întâlnire și comenzile $ links = ['home' => MiscHelpers :: buildCommand ($ mtg-> id, întâlnire :: COMMAND_HOME, 0, $ a ['user_id'], $ a ['auth_key']), 'view' => MiscHelpers :: buildCommand ($ mtg-> id, ($ Mtg-> id, Întâlnire :: COMMAND_FOOTER_EMAIL, 0, $ a ['user_id'], $ a ['auth_key'], 'footer_email' ], $ a ['auth_key']), 'footer_block' => MiscHelpers :: buildCommand ($ mtg-> id, întâlnire :: COMMAND_FOOTER_BLOCK, 0, $ a ['user_id'], $ a [' , 'footer_block_all' => MiscHelpers :: buildCommand ($ mtg-> id, întâlnire :: COMMAND_FOOTER_BLOCK_ALL, 0, $ a ['user_id'], $ a ['auth_key']), 'running_late' => MiscHelpers :: buildCommand ($ mtg-> id, întâlnire :: COMMAND_RUNNING_LATE, 0, $ a ['user_id'], $ a ['auth_key']), 'view_map' => MiscHelpers :: buildCommand ($ mtg-> id, COMMAND_VIEW_MAP, 0, $ a ['user_id'], $ a ['auth_key'])]; // trimiteți mesajul $ message = Yii :: $ app-> mailer-> compose (['html' => 'reminder-html', 'text' => $ mtg-> id, 'sender_id' => $ user_id, 'user_id' => $ a ['user_id'], 'auth_key' => $ a ['auth_key'], 'display_time' => '=> $ select_place,' links '=> $ link-uri,' setSettings '=> $ mtg-> meetingSettings,]); dacă ! empty ($ a ['email'])) $ message-> setFrom (['[email protected]' => 'Planificator întâlniri']]; $ message-> setTo ($ a ['email']) -> setSubject (Yii :: t ('frontend', 'Memento întâlnire:') $ mtg-> subject) -> send ();  $ mr-> status = MeetingReminder :: STATUS_COMPLETE; $ MR-> actualizare ();  

Utilizator :: checkEmailDelivery () funcția verifică faptul că utilizatorul nu a blocat e-mailurile din sistem (sau de la anumite persoane). Se asigură că este bine să trimiteți memento-ul:

// verificați dacă e-mailul este bine și bine din acest sender_id dacă (User :: checkEmailDelivery ($ user_id, 0)) // Construiți linkurile absolute către întâlnire și comenzile $ links = ['home' => MiscHelpers :: buildCommand ($ mtg-> id, întâlnire :: COMMAND_HOME, 0, $ a ['user_id'], $ a ['auth_key']), 'view' => MiscHelpers :: buildCommand ($ mtg-> id, ($ Mtg-> id, Întâlnire :: COMMAND_FOOTER_EMAIL, 0, $ a ['user_id'], $ a ['auth_key'], 'footer_email' ], $ a ['auth_key']), 'footer_block' => MiscHelpers :: buildCommand ($ mtg-> id, întâlnire :: COMMAND_FOOTER_BLOCK, 0, $ a ['user_id'], $ a [' , 'footer_block_all' => MiscHelpers :: buildCommand ($ mtg-> id, întâlnire :: COMMAND_FOOTER_BLOCK_ALL, 0, $ a ['user_id'], $ a ['auth_key']), 'running_late' => MiscHelpers :: buildCommand ($ mtg-> id, întâlnire :: COMMAND_RUNNING_LATE, 0, $ a ['user_id'], $ a ['auth_key']), 'view_map' => MiscHelpers :: buildCommand ($ mtg-> id, COMMAND_VIEW_MAP, 0, $ a ['user_id'], $ a ['auth_key'])]; 

Iată-l Utilizator :: checkEmailDelivery metodă. În primul rând, verifică dacă utilizatorul a blocat complet e-mailurile (sperăm că nu) sau dacă mesajul este trimis de la un utilizator blocat:

 ($ user_id, $ sender_id) // verificați dacă acest user_id primește e-mail și dacă sender_id nu este blocat // verificați dacă toate e-mailurile sunt dezactivate $ us = UserSetting :: safeGet ($ user_id); dacă ($ us-> no_email! = UserSetting :: EMAIL_OK) return false;  // verificați dacă niciun expeditor, de ex. notificare de sistem dacă ($ sender_id == 0) return true;  // verificați dacă expeditorul este blocat $ ub = UserBlock :: find () -> unde (['user_id' => $ user_id, 'blocked_user_id' => $ sender_id]) -> one (); dacă (! is_null ($ ub)) return false;  return true;  

Șablonul de e-mail nou pentru mementouri

În episodul Delivering Your Invitation Meeting, am scris despre trimiterea mesajelor de e-mail în cadrul Yii Framework. În șabloanele de e-mail de rafinare, am descris actualizarea șabloanelor pentru noile șabloane receptive bazate pe Oxygen.

Iată noul șablon de email reminder_html.php:

   
Memento de întâlnire
Doar un memento despre întâlnirea viitoare la ń> nume; ?> (ń> vecinătate; ?>, ) prin telefon sau prin videoconferință.
Faceți clic mai jos pentru a vedea mai multe detalii pentru a vedea pagina de întâlnire.
"> Vizitați pagina de întâlniri
Opțiuni utile:

vizualizare-> renderFile ('@ common / mail / section-footer-dynamic.php', ['links' => $ links]

Acesta include data, ora și locația aleasă (cu o adresă și un link de hartă). De asemenea, am adăugat începutul unei zone de opțiuni utile, cu o comandă inițială "Informați-i că rulez târziu":

Când faceți clic pe, vom trimite un e-mail sau un SMS celorlalți participanți, cu întârziere de cinci până la zece minute. Nu aveți altceva de făcut sau de scris în timp ce vă grăbiți.

Poate că o eventuală versiune mobilă a Planificatorului de întâlniri va cunoaște locația dvs. GPS și vă va informa cât de departe vă aflați. Am început să urmăresc astfel de idei în Asana pentru planificarea produselor - voi cere zeițele editoriale Envato Tuts + (prezentate mai jos) dacă pot să scriu despre implementarea funcției și a urmăririi problemelor într-un viitor tutorial.

Îmbunătățirile aduse mementourilor

E-mailul de reamintire poate folosi de fapt câteva funcții îmbunătățite:

  • Finalizarea implementării implementării e-mailului târziu.
  • Afișarea informațiilor de contact ale altor participanți, cum ar fi numerele de telefon și adresele de e-mail. Mesajul de întârziere care rulează poate arăta doar informațiile de contact ale persoanei care rulează târziu.
  • Afișați o hartă Google statică care să arate locația întâlnirii.
  • Conectați-vă la o caracteristică pentru a solicita sau a solicita o reeșalonare a întâlnirii.
  • Conectați nu numai harta, ci și direcțiile spre locație.
  • Link pentru a ajusta mementourile.

Se pare că majoritatea acestor caracteristici necesită mai multă muncă decât există spațiu în acest tutorial. 

De exemplu, ideea trimiterii unui e-mail târziu se pare ca o caracteristică simplă, nu? Este un bun exemplu al provocării pe care cadrele MVC le impun uneori dezvoltatorilor. Implementarea unei funcții de e-mail târziu a fost necesară pentru un număr de fișiere, inclusiv un nou șablon de e-mail.

Implementarea funcției de alergare târzie

Mai degrabă decât să împărtășim toate modificările de cod necesare pentru această caracteristică, voi rezuma doar locurile în care schimbarea era necesară în jurul cadrului:

  • E-mailul de reamintire necesita o legatura cu o noua comanda
  • COMMAND_RUNNING_LATE a trebuit să fie definită în modelul de întâlnire și în controler și a trebuit să afișeze un mesaj de confirmare.

Iată un exemplu despre ceea ce vedeți după ce ați cerut o notificare târzie pentru a fi trimisă:

  • sendLateNotice () metoda a trebuit construită în Meeting.php
  • Șablonul de e-mail de la sfîrșitul html.php a trebuit să fie construit. Aceasta include o opțiune pentru celălalt participant de a anunța că sunt "întârziate".
  • UserContact :: buildContactString () metoda a trebuit completă pentru a include informații de contact pentru persoana care a intrat târziu.
  •  ACTION_SENT_RUNNING_LATE a trebuit să fie creată pentru a înregistra trimiterea unei notificări târzii în numele acestei persoane în MeetingLog.
  • sendLateNotice () metoda a trebuit să verifice jurnalul și să afișeze o eroare dacă notificarea târzie fusese deja trimisă o singură dată.

Iată ce afișează mesajul întârziat deja afișat: 

A fost o mulțime de cod pentru a pune în aplicare ceea ce părea o simplă adăugare. 

Am așteptat să testez caracteristica până când s-au făcut toate schimbările de mai sus și am fost plăcut surprins de faptul că toate au lucrat exact așa cum a fost intenționat. Trebuia doar să fac câteva modificări cosmetice ale textului.

Implementarea afișării informațiilor de contact ale participanților

Deși această funcție exista deja pentru fișierele iCal, trebuia să finalizez această funcție pentru invitațiile la întâlniri bazate pe e-mail. Așa că am extins UserContact :: buildContactString ($ user_id, modul de $) pentru Mod de $ = 'html'.

Iată codul actualizat:

funcția publică statică buildContactString ($ user_id, $ mode = 'ical') // de făcut - creați o vizualizare pentru aceasta care poate fi redată $ contacts = UserContact :: getUserContactList ($ user_id); dacă ($ conta == 'ical') $ str = ";  altfel dacă ($ mode == 'html') $ str = '

„; $ str = \ common \ components \ MiscHelpers :: getDisplayName ($ user_id). ':'; dacă ($ mode == 'ical') $ str. = '\\ n'; altfel dacă ($ mode == 'html') $ str. = '
„; foreach ($ contacte ca $ c) if ($ mode == 'ical') $ str. = $ c-> friendly_type. ':'. $ c-> info. (“$ C-> detalii.. ') \\ n'; altfel dacă ($ mode == 'html') $ str. = $ c-> friendly_type. ':'. $ c-> info. '
'$ C-> detalii.'
„; dacă ($ mode == 'ical') $ str. = '\\ n'; altfel dacă ($ mode == 'html') $ str. = '

„; return $ str;

Sunt sigur că va fi nevoie de o lustruire pe măsură ce trecem la testele alfa și beta, dar funcționalitatea este acum acolo.

Puteți vedea detaliile de contact afișate în notificarea completă de mai sus, dar aici este segmentul pe care îl generează:

Polizoare de lustruire

Lucrurile au mers atât de bine în ansamblu cu aceste mini-caracteristici târzii pe care le-am adăugat link-ul pentru a ajusta memento-urile la e-mailul memento original și.

Cu tot acest nou cod, sunt sigur că voi lustrui caracteristica memento-urilor și le voi îmbunătăți în mod regulat în următoarele câteva săptămâni. Cu toate acestea, în calitate de Planificator de Întâlniri s-au adunat, mai multe funcționalități sunt adesea posibile - adesea cu puțină muncă deoarece există un cadru și o fundație. Modelul curat de date și cadrul MVC fac în mod regulat îmbunătățiri incrementale relativ simple.

Toate acestea fac ca construirea unui startup să fie atât distractivă, cât și provocatoare. Și lucrul cu dragonii (câteva zile nu-mi vine să cred că mă plătesc să fac asta).

Ce urmeaza?

Întâlnirea Planificatorului a făcut progrese extraordinare în ultimele luni. Încep să experimentez cu WeFunder pe baza punerii în aplicare a noilor reguli de finanțare a SEC. Vă rugăm să luați în considerare profilul nostru. Sper să scriu despre asta mai mult într-un tutorial viitor.

Și, cu siguranță, aplicația are încă multe deficiențe - asigurați-vă că trimiteți feedbackul dvs. în comentarii sau deschideți un bilet de asistență.

Sper că ți-a plăcut acest episod. Urmăriți tutorialele viitoare în Building Your Startup With PHP series - încă mai există o activitate poloneză, dar și mai multe caracteristici mari.

Vă rugăm să nu adăugați întrebările și comentariile de mai jos; În general, particip la discuții. Puteți să mă contactați și pe Twitter @reifman direct.

Link-uri conexe

  • Planificatorul întâlnirilor
  • Profilul de finanțare a planificării întâlnirilor
  • Programarea cu Yii2: Noțiuni de bază
  • Schimbul de dezvoltatori Yii2
Cod