展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > 使用 PHP 构建您的初创公司:安排会议

使用 PHP 构建您的初创公司:安排会议

本教程是Tuts+上“使用PHP构建您的初创公司”系列的一部分。在本系列中,我将使用我的MeetingPlanner应用程序作为现实生活中的示例,指导您启动从概念到现实的初创公司。在此过程中的每一步,我们都会将MeetingPlanner代码作为开源示例发布,您可以从中学习。我们还将解决出现的与初创企业相关的业务问题。MeetingPlanner的所有代码都是用PHP的Yii2框架编写的。如果您想了解有关Yii2的更多信息,请查看Tuts+上的并行系列“使用Yii2编程”。您可能还想查看我的知识库网站,了

使用 PHP 构建您的初创公司:安排会议

本教程是 Tuts+ 上“使用 PHP 构建您的初创公司”系列的一部分。在本系列中,我将使用我的 Meeting Planner 应用程序作为现实生活中的示例,指导您启动从概念到现实的初创公司。在此过程中的每一步,我们都会将 Meeting Planner 代码作为开源示例发布,您可以从中学习。我们还将解决出现的与初创企业相关的业务问题。

Meeting Planner 的所有代码都是用 PHP 的 Yii2 框架编写的。如果您想了解有关 Yii2 的更多信息,请查看 Tuts+ 上的并行系列“使用 Yii2 编程”。您可能还想查看我的知识库网站,了解 Yii2 问题,Yii2 开发者交流中心。

在过去的六个教程中,我们通过多种方式奠定了应用程序支持的基础:用户、地点、联系人、设置和本地化。我打赌您会和我一样兴奋,因为我们终于准备好开始构建安排会议功能了。感谢您的耐心等待,我已经为这个应用程序的有趣且不可或缺的部分构建了基础架构。

但是,支持安排会议功能的编码教程将至少持续四集。接下来的两集将主要关注为基本用户体验建立支持,选择会议的参与者、地点、日期和时间,并将其存储在数据库中。之后,我们将介绍如何通过电子邮件发送会议请求。我们将在本系列稍后返回来优化和完善用户界面,因为它对于该产品的成功至关重要;后续更新的主要任务是消除会议安排过程中的页面刷新。

构建本教程的功能需要大量代码 - 一些由 Yii 的 Gii 自动生成,还有很多是手动生成的。由于交付此功能的初始部分非常复杂,因此我专注于相当基本的用户界面,我将对其进行迭代完善。

构建此功能涉及 Yii2 框架中编程的许多方面:Active Record 迁移、关系和验证、Gii 代码生成、Bootstrap、Yii2 JQuery UI 扩展和小部件、AJAX、渲染部分视图、DRY 编码实践等。很难选择这里要涵盖的内容。您会注意到早期教程中的存储库发生了很多更改。

如果您有任何疑问或意见,请在下面发布。我确实参与了讨论。

会议页面

引导选项卡

我需要做的第一件事就是为未来、过去和取消的会议构建不同的选项卡。

使用 PHP 构建您的初创公司:安排会议

实现这一点只是 Bootstrap 的伟大之处以及 Yii2 与 Bootstrap 3.x 集成的牢固性的另一个例子。 Bootstrap 有预构建的选项卡。

在 MeetingController 中,我们预加载每种会议类型的查询并呈现索引视图:

public function actionIndex()
{
  // add filter for upcoming or past
    $upcomingProvider = new ActiveDataProvider([
        'query' => Meeting::find()->joinWith('participants')->where(['owner_id'=>Yii::$app->user->getId()])->orWhere(['participant_id'=>Yii::$app->user->getId()])->andWhere(['Meeting.status'=>[Meeting::STATUS_PLANNING,Meeting::STATUS_CONFIRMED]]),
    ]);
    $pastProvider = new ActiveDataProvider([
        'query' => Meeting::find()->joinWith('participants')->where(['owner_id'=>Yii::$app->user->getId()])->orWhere(['participant_id'=>Yii::$app->user->getId()])->andWhere(['Meeting.status'=>Meeting::STATUS_COMPLETED]),
    ]);
    $canceledProvider = new ActiveDataProvider([
        'query' => Meeting::find()->joinWith('participants')->where(['owner_id'=>Yii::$app->user->getId()])->orWhere(['participant_id'=>Yii::$app->user->getId()])->andWhere(['Meeting.status'=>Meeting::STATUS_CANCELED]),
    ]);

    return $this->render('index', [
        'upcomingProvider' => $upcomingProvider,
        'pastProvider' => $pastProvider,
        'canceledProvider' => $canceledProvider,
    ]);
}

然后,在索引视图中,我们使用选项卡窗格实现引导代码:

title ?>

render('_grid', [ 'dataProvider' => $upcomingProvider, ]) ?>
render('_grid', [ 'dataProvider' => $pastProvider, ]) ?>
render('_grid', [ 'dataProvider' => $canceledProvider, ]) ?>

随着我们深入了解本系列,我将留下许多占位符工作要做。其中之一是通过 AJAX 实现这些选项卡窗格,这样我们就不会预先加载三个查询。

工单追踪

我还将开始在问题跟踪应用 Lighthouse 中为我未来的工作创建票证,以使其更易于跟踪。我将在以后的教程中讨论 Lighthouse。

使用 PHP 构建您的初创公司:安排会议

安排会议的背后是什么?

创建一个安排会议的框架这个简单的任务在幕后却是相当复杂和详细的。我将在整个系列中分阶段完善这一点。

我的第一个目标是构建基本框架,以便我可以开始测试会议安排的功能。

会议由一些 ActiveRecord 数据模型组成,例如Participant、MeetingTime、MeetingPlace、MeetingNote 等。最初,我只是想使用 Yii 代码生成为每个模型构建 CRUD,然后将其集成到单个调度页面中。

这个想法是使用 MVC 来构建所有这些操作,并尽可能坚持 DRY 方法。最初,该界面将通过页面刷新来工作,但稍后我们将返回并使用相同的 MVC 代码通过 AJAX 集成所有这些模型。

创建会议表单

对于许多模型,我首先经历了早期教程中概述的使用 Yii 代码生成器 Gii 构建 CRUD 的过程。然后我根据需要定制它们。目前,我坚持使用非常基本的创建会议表单 - 它甚至还不包括参与者的电子邮件地址。这使我能够快速创建基本的会议记录并在安排页面上工作。

使用 PHP 构建您的初创公司:安排会议

表单提交后,您可以查看会议页面。显然,我会及时修改这个表格和最初的流程。

会议页面

记住我的本系列第一篇教程的模型:

使用 PHP 构建您的初创公司:安排会议

这是我正在处理的表单的早期版本:

使用 PHP 构建您的初创公司:安排会议

实现这一目标涉及大量基础设施、代码(自动生成、手动生成)和第三方小部件。我将逐步引导您完成它。

引导面板和表格

虽然不太可能是最终设计,但我选择使用 Bootstrap 面板来组织属性、地点、日期、时间和注释之间的页面。页面本身由会议控制器的 View 操作呈现,并调用每个视图的特定模型的部分视图。

我不必以这种方式构建它,但我有目的地想要利用 Yii 的所有内置 MVC 框架并尽可能多地集成事物。我的希望是,将来能够更轻松地对整个页面进行 AJAX 化,减少页面刷新并提高源代码的简单性和可维护性。

以下是会议控制器 View 操作的工作原理。它为每个模型加载 ActiveDataProviders,然后呈现会议视图文件:

/**
     * Displays a single Meeting model.
     * @param integer $id
     * @return mixed
     */
    public function actionView($id)
    {
      $timeProvider = new ActiveDataProvider([
          'query' => MeetingTime::find()->where(['meeting_id'=>$id]),
      ]);

      $noteProvider = new ActiveDataProvider([
          'query' => MeetingNote::find()->where(['meeting_id'=>$id]),
      ]);

      $placeProvider = new ActiveDataProvider([
          'query' => MeetingPlace::find()->where(['meeting_id'=>$id]),
      ]);

      $participantProvider = new ActiveDataProvider([
          'query' => Participant::find()->where(['meeting_id'=>$id]),
      ]);
      $model = $this->findModel($id);
      $model->prepareView();
        return $this->render('view', [
            'model' => $model,
            'participantProvider' => $participantProvider,
            'timeProvider' => $timeProvider,
            'noteProvider' => $noteProvider,
            'placeProvider' => $placeProvider,
        ]);
    }

部分视图

通过使用每个关联模型中的所有视图,可以非常轻松地使用 MVC 部分视图显示整个计划页面。会议视图呈现其他模型的所有 _panel 视图。您可以在此处查看 Yii2 渲染方法的文档。

        render('../participant/_panel', [
            'model'=>$model,
            'participantProvider' => $participantProvider,
        ]) ?>

        render('../meeting-place/_panel', [
            'model'=>$model,
            'placeProvider' => $placeProvider,
        ]) ?>       
                
        render('../meeting-time/_panel', [
            'model'=>$model,
            'timeProvider' => $timeProvider,
        ]) ?>

        render('../meeting-note/_panel', [
            'model'=>$model,
            'noteProvider' => $noteProvider,
        ]) ?>

缺少模型

在构建此功能时,我意识到我忽略了几个必要的模型:MeetingPlaceChoice 和 MeetingTimeChoice。需要这些来存储特定 MeetingPlaces 和 MeetingTimes 的组织者和参与者的可用性。

以下是 MeetingPlaceChoice 的迁移:

$this->createTable('{{%meeting_place_choice}}', [
          'id' => Schema::TYPE_PK,
          'meeting_place_id' => Schema::TYPE_INTEGER.' NOT NULL',
          'user_id' => 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_mpc_meeting_place', '{{%meeting_place_choice}}', 'meeting_place_id', '{{%meeting_place}}', 'id', 'CASCADE', 'CASCADE');
      $this->addForeignKey('fk_mpc_user_id', '{{%meeting_place_choice}}', 'user_id', '{{%user}}', 'id', 'CASCADE', 'CASCADE');   

以下是 MeetingTimeChoice 的迁移:

$this->createTable('{{%meeting_time_choice}}', [
          'id' => Schema::TYPE_PK,
          'meeting_time_id' => Schema::TYPE_INTEGER.' NOT NULL',
          'user_id' => 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_mtc_meeting_time', '{{%meeting_time_choice}}', 'meeting_time_id', '{{%meeting_time}}', 'id', 'CASCADE', 'CASCADE');
      $this->addForeignKey('fk_mtc_user_id', '{{%meeting_time_choice}}', 'user_id', '{{%user}}', 'id', 'CASCADE', 'CASCADE');  

随着产品的进步,Yii 的 ActiveRecord 迁移可以轻松地以编程方式扩展数据库架构。

这些模型确定您在上面的每个地点和日期时间的行中看到的开关小部件的状态(反映用户可用性)。在下面的教程中,我将引导您了解如何初始化这些小部件并在 Yii 中使用 AJAX 来更新它们的状态而无需刷新页面。

安排提醒

PrepareView 确定会议的状态,并在必要时警告用户邀请尚未发送:

public function prepareView() {
        $this->setViewer();
        $this->canSend();
        $this->canFinalize();
        // has invitation been sent
         if ($this->canSend()) {
           Yii::$app->session->setFlash('warning', Yii::t('frontend','This invitation has not yet been sent.'));
      }
        // to do - if sent, has invitation been opened
        // to do - if not finalized, is it within 72 hrs, 48 hrs        
      }

Yii 具有显示 Bootstrap Alerts 的内置支持,称为 flashes:

使用 PHP 构建您的初创公司:安排会议

命令按钮

以下是示例会议视图容器的代码,其中包含上面所示的命令按钮:

title) ?>

message ?>

每个按钮都是使用 Yii 的 HTML 帮助器和 Bootstrap 按钮样式创建的:

 $model->id], ['class' => 'btn btn-primary '.(!$model->isReadyToSend?'disabled':'')]) ?>

对于取消和编辑属性按钮,我使用了 Glyphicons。 Glyphicons 非常漂亮,并且免费包含在 Bootstrap 中并与 Yii2 集成。

这些命令有什么作用?

用户添加一名参与者以及至少一个地点、日期和时间后,他或她就可以发送邀请。此功能将通过电子邮件向用户发送会议邀请,我将在即将发布的教程中对此进行描述。

最终确定按钮允许组织者(或参与者)将会议状态从计划更改为即将举行。这个想法是,一旦选择了地点和日期时间,会议就可以“最终确定”。在此之前,参与者将有机会选择建议其他地点和日期时间,组织者(或双方)将可以选择最终地点和日期时间。

取消按钮将取消会议并将其移至会议页面上已取消的选项卡。

参与者

接下来,用户将添加人员。

使用 PHP 构建您的初创公司:安排会议

注意:在我的最小可行产品中,只允许一名参与者,但我们稍后可能会添加更多参与者。

em>

如果您还记得我们在之前的教程中创建的“好友”表,我将允许用户输入新的电子邮件地址,或者通过从现有好友和过去的会议中加载自动完成功能来加快输入速度。

使用 PHP 构建您的初创公司:安排会议

将来,我们将在此处提供更多用户界面选项,包括频繁参与者。

在 Participant 控制器的顶部,我们将朋友加载到一个数组中,以供 JQuery 自动完成小部件使用 - Yii2 中再次内置了对此的支持:

/**
     * Creates a new Participant model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     * @return mixed
     */
    public function actionCreate($meeting_id)
    {
      $mtg = new Meeting();
      $title = $mtg->getMeetingTitle($meeting_id);
        $model = new Participant();
        $model->meeting_id= $meeting_id;
        $model->invited_by= Yii::$app->user->getId();
        // load friends for auto complete field
        $friends = Friend::getFriendList(Yii::$app->user->getId());

这是_form.php,位于\frontend\views\participant:

errorSummary($model); ?>

Email address:

$model, 'attribute' => 'email', 'clientOptions' => [ 'source' => $friends, ], ]); ?>

我做出了将所有参与者存储在用户表中的设计决策。我可能会后悔——还不确定。但它极大地简化了流程,让人们能够快速开始使用网站,并简化了整体数据模型。

当用户邀请系统未知的人(新电子邮件地址)时,我们会在用户表中被动注册他们。

if ($model->load(Yii::$app->request->post())) {
          if (!User::find()->where( [ 'email' => $model->email ] )->exists()) {
            // if email not already registered
            //  create new user with temporary username & password
            $temp_email_arr[] = $model->email;
            $model->username = Inflector::slug(implode('-', $temp_email_arr));
            $model->password = Yii::$app->security->generateRandomString(12);
            $model->participant_id = $model->addUser();
          } else {
            // add participant from user record
            $usr = User::find()->where( [ 'email' => $model->email ] )->one();
            $model->participant_id = $usr->id;
          }
          // validate the form against model rules
          if ($model->validate()) {
              // all inputs are valid
              $model->save();              
              return $this->redirect(['/meeting/view', 'id' => $meeting_id]);
          } 

我们根据他们的电子邮件地址创建用户名。我在 Inflector 助手中使用 Yii 的 slug 生成器。我们现在使用 Yii 的安全助手创建一个随机密码。如果我使用普通 PHP,我可能必须集成其他函数才能实现这些功能。相反,它是内置的。

让我们继续添加地点。

地点

对每个控制器和模型使用 Yii 的 MVC 比将所有这些功能编码到会议控制器中具有很大的优势。它使理解和管理代码变得更加简单和更有条理。

但是,我很快注意到,我必须自定义默认面包屑以链接回当前会议页面,而不是特定模型的索引或视图。

使用 PHP 构建您的初创公司:安排会议

我们实际上使用 MeetingPlace 模型来添加会议地点。在 \frontend\views\meeting-place\create.php 中,我只需自定义 breadcrumbs 区域中的链接:

title = Yii::t('frontend', 'Add a {modelClass}', [
    'modelClass' => 'Meeting Place',
]);
$this->params['breadcrumbs'][] = ['label' => Yii::t('frontend', 'Meetings'), 'url' => ['/meeting/index']];

$this->params['breadcrumbs'][] = ['label'=>$title,'url' => ['/meeting/view', 'id' => $model->meeting_id]];
$this->params['breadcrumbs'][] = $this->title;

?>

添加对直接添加 Google 地点的支持

使用 PHP 构建您的初创公司:安排会议

我不仅想自定义地点创建表单,以便用户添加以前使用过的地点,还希望他们添加新的 Google 地方信息正在运行。

我基本上必须在 MeetingPlace 创建中复制我们在 Google 地方信息教程中构建的支持:



errorSummary($model); ?>

Choose one of your places

all(), 'place.id', 'place.name'),['prompt'=>Yii::t('frontend','-- select one of your places below --')] ) ?>

- or -

Choose from Google Places

Type in a place or business known to Google Places:

field($model, 'searchbox')->textInput(['maxlength' => 255])->label('Place') ?>
isNewRecord ? Yii::t('frontend', 'Add Place') : Yii::t('frontend', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>

我还需要更多地利用 Yii2 复杂的验证支持。在下面的 MeetingPlace 模型中,如果有人尝试前往已建议的会议地点,我们会使用 Yii2 的独特验证来报告错误:

    public function rules()
    {
        return [
            [['meeting_id', 'place_id', 'suggested_by'], 'required'],
            [['meeting_id', 'place_id', 'suggested_by', 'status', 'created_at', 'updated_at'], 'integer'],
            [['place_id'], 'unique', 'targetAttribute' => ['place_id','meeting_id'], 'message'=>Yii::t('frontend','This place has already been suggested.')],

我还在 MeetingPlaceController 创建操作中添加了一个自定义错误条件(如果用户从其列表以及 Google Place 中选择地点),尽管这可能是一个需要保留的可选功能(有意见吗?请在下面的评论中发表):

     public function actionCreate($meeting_id)
     {
       $mtg = new Meeting();
       $title = $mtg->getMeetingTitle($meeting_id);
         $model = new MeetingPlace();
         $model->meeting_id= $meeting_id;
         $model->suggested_by= Yii::$app->user->getId();
         $model->status = MeetingPlace::STATUS_SUGGESTED;
         $posted_form = Yii::$app->request->post(); 
         if ($model->load($posted_form)) {
          // check if both are chosen and return an error
           if ($model->place_id<>'' and $posted_form['MeetingPlace']['google_place_id']<>'') {    
             $model->addErrors(['place_id'=>Yii::t('frontend','Please choose one or the other')]);
             return $this->render('create', [
                  'model' => $model,
                   'title' => $title,
              ]);             
           }

我使用了 Yii2 的 addErrors 方法。

我还修复了第三集中的一个错误,即每当有人更改 Google 地点选择时就会创建多个地图框。检查 article 选择器中现有的子级数量修复了此问题:

function loadMap(gps,name) {
  if (document.querySelector('article').children.length==0) {
    var mapcanvas = document.createElement('div');
    mapcanvas.id = 'mapcanvas';
    mapcanvas.style.height = '300px';
    mapcanvas.style.width = '300px';
    mapcanvas.style.border = '1px solid black';    
    document.querySelector('article').appendChild(mapcanvas);  
  }

未来,这种创作形式将包含一些重要的功能:

  • 允许用户添加他们当前的地理位置。
  • 推荐用户推荐的常去地点。
  • 提供对用户最喜爱的地点的快速访问。
  • 建议用户和参与者附近(等距离)的地点。
  • 建议付费广告商赞助的地点。
  • 允许组织者删除地点和日期时间 - 可能是在参与者未看到或回复的情况下。

允许用户记录特定地点和日期时间也可能很有用。例如,我可能会指定“这个地方适合我周四早上但周五下午不适合”或“如果您选择这个时间,我们可以在国会山的 Caffe Vita 进行吗”。如果您对此功能有意见(这会增加复杂性),请在下面发表评论。

显示面板

对于每个模型,我们使用类似的视图层次结构和 Yii2 组件。会议控制器在 \frontend\views\meeting-place 中呈现 _panel.php 的视图:


$model->id], ['class' => 'btn btn-primary glyphicon glyphicon-plus']) ?>
count>0): ?> $placeProvider, 'itemOptions' => ['class' => 'item'], 'layout' => '{items}', 'itemView' => '_list', 'viewParams' => ['placeCount'=>$placeProvider->count], ]) ?>
count>1) echo Yii::t('frontend','Choose'); ?>

Bootstrap 兼容表的概要位于 _panel.php 中。然后我们使用 Yii2 Listview 小部件以表格形式显示每一行数据。 itemView 部分位于 _list.php 中。

请注意,我们通过 viewParams 传递了一个名为 placeCount 的自定义变量。这对于配置表格中的按钮非常方便。

这是 _list.php 视图,我将在下一个教程中更详细地介绍该视图,包括切换输入小部件和 AJAX 实现。



 
  
        place->name,BaseUrl::home().'/place/'.$model->place->slug) ?>
  
  
      meetingPlaceChoices as $mpc) {
        if ($mpc->user_id == $model->meeting->owner_id) {
            if ($mpc->status == $mpc::STATUS_YES)
              $value = 1;
            else
              $value =0;
              echo SwitchInput::widget([
              'type'=>SwitchInput::CHECKBOX,
              'name' => 'meeting-place-choice',
              'id'=>'mpc-'.$mpc->id,          
              'value' => $value,
              'pluginOptions' => ['size' => 'mini','onText' => '','offText'=>'','onColor' => 'success','offColor' => 'danger',],
              ]);          
        }
      }      
      ?>
  
  
    meetingPlaceChoices as $mpc) {
    if (count($model->meeting->participants)==0) break;    
    if ($mpc->user_id == $model->meeting->participants[0]->participant_id) {
        if ($mpc->status == $mpc::STATUS_YES)
          $value = 1;
        else if ($mpc->status == $mpc::STATUS_NO)
          $value =0;
        else if ($mpc->status == $mpc::STATUS_UNKNOWN)
          $value =-1;
            echo SwitchInput::widget([
          'type'=>SwitchInput::CHECKBOX,         
          'name' => 'meeting-place-choice',
          'id'=>'mpc-'.$mpc->id,          
          'tristate'=>true,
          'indeterminateValue'=>-1,
          'indeterminateToggle'=>false,
          'disabled'=>true,
          'value' => $value,
          'pluginOptions' => ['size' => 'mini','onText' => '','offText'=>'','onColor' => 'success','offColor' => 'danger'],
      ]);          
    }
  }
    ?>
  
  
      
      1) {
        if ($model->status == $model::STATUS_SELECTED) {
            $value = $model->id;
        }    else {
          $value = 0;        
        } 
        echo SwitchInput::widget([
          'type' => SwitchInput::RADIO,
          'name' => 'place-chooser',
            'items' => [
                [ 'value' => $model->id],
            ],
            'value' => $value,
            'pluginOptions' => [  'size' => 'mini','handleWidth'=>60,'onText' => '','offText'=>''],
            'labelOptions' => ['style' => 'font-size: 12px'],
        ]);              
      }
      ?>
  

日期和时间

为了添加日期和时间,我们通过 2Amigos Yii2 日期时间扩展集成了 Bootstrap JQuery 日期时间选择器

使用 PHP 构建您的初创公司:安排会议



$model, 'attribute' => 'start', 'language' => 'en', 'size' => 'ms', 'clientOptions' => [ 'autoclose' => true, 'format' => 'MM dd, yyyy HH:ii P', 'todayBtn' => true, 'minuteStep'=> 15, 'pickerPosition' => 'bottom-left', ] ]);?>

isNewRecord ? Yii::t('frontend', 'Add') : Yii::t('frontend', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>

我希望将来对这个小部件进行一些增强。我想让它在加载时自动打开,但目前似乎没有相应的设置。

我们再次使用唯一的验证器来确保特定日期和时间尚未添加到会议中:

public function rules()
    {
        return [
            [['meeting_id', 'start', 'suggested_by'], 'required'],
            [['meeting_id', 'start', 'suggested_by', 'status', 'created_at', 'updated_at'], 'integer'],
            [['start'], 'unique', 'targetAttribute' => ['start','meeting_id'], 'message'=>Yii::t('frontend','This date and time has already been suggested.')],
            
        ];
    }

在会议视图页面上,“日期和时间”面板的构建方式与“地点”类似:


$model->id], ['class' => 'btn btn-primary glyphicon glyphicon-plus']) ?>
count>0): ?> $timeProvider, 'itemOptions' => ['class' => 'item'], 'layout' => '{items}', 'itemView' => '_list', 'viewParams' => ['timeCount'=>$timeProvider->count], ]) ?>
count>1) echo Yii::t('frontend','Choose'); ?>

这是_list.php 视图:



 
  
        start) ?>
  
  
      meetingTimeChoices as $mtc) {
        if ($mtc->user_id == $model->meeting->owner_id) {
            if ($mtc->status == $mtc::STATUS_YES)
              $value = 1;
            else
              $value =0;
              echo SwitchInput::widget([
              'type' => SwitchInput::CHECKBOX,              
              'name' => 'meeting-time-choice',
              'id'=>'mtc-'.$mtc->id,
              'value' => $value,
              'pluginOptions' => ['size' => 'mini','onText' => '','offText'=>'','onColor' => 'success','offColor' => 'danger',],
              ]);          
        }
      }
      ?>
  
  
    meetingTimeChoices as $mtc) {
      if (count($model->meeting->participants)==0) break;
      if ($mtc->user_id == $model->meeting->participants[0]->participant_id) {
          if ($mtc->status == $mtc::STATUS_YES)
            $value = 1;
          else if ($mtc->status == $mtc::STATUS_NO)
            $value =0;
          else if ($mtc->status == $mtc::STATUS_UNKNOWN)
            $value =-1;
          echo SwitchInput::widget([
            'type' => SwitchInput::CHECKBOX,          
            'name' => 'meeting-time-choice',
            'id'=>'mtc-'.$mtc->id,
            'tristate'=>true,
            'indeterminateValue'=>-1,
            'indeterminateToggle'=>false,
            'disabled'=>true,
            'value' => $value,
            'pluginOptions' => ['size' => 'mini','onText' => '','offText'=>'','onColor' => 'success','offColor' => 'danger',],
        ]);          
      }
    }
    ?>
  
  
      1) {
        if ($model->status == $model::STATUS_SELECTED) {
            $value = $model->id;
        }    else {
          $value = 0;        
        } 
        echo SwitchInput::widget([
            'type' => SwitchInput::RADIO,
            'name' => 'time-chooser',
            'items' => [
                [ 'value' => $model->id],
            ],
            'value' => $value,
            'pluginOptions' => [  'size' => 'mini','handleWidth'=>60,'onText' => '','offText'=>''],
            'labelOptions' => ['style' => 'font-size: 12px'],
        ]);            
      }
      ?>
  


注释

会议笔记允许用户根据他们的建议来回沟通并选择地点和日期时间,而无需实际分别向彼此发送电子邮件。

使用 PHP 构建您的初创公司:安排会议

会议页面上的注释如下所示:

使用 PHP 构建您的初创公司:安排会议

注释的实现与上述地点和日期时间的实现几乎相同。您可以查看 MeetingNote 控制器和 \frontend\views\meeting-note 视图文件以获取更多信息。

下一步是什么?

我希望您通过本教程学到了一些新东西。请观看我的“使用 PHP 构建您的初创公司”系列中即将推出的教程 - 即将推出许多有趣的功能。

在下一个教程中,我将深入探讨如何使用 AJAX 实现地点和日期时间选择。之后,我们将开始构建电子邮件以发送消息邀请、在日程安排页面上收集参与者的回复,并最终确定现实世界的会议。

请随时在下面添加您的问题和评论;我一般都会参与讨论。您还可以通过 Twitter @reifman 联系我或直接给我发送电子邮件。

相关链接

  • 使用 Yii2 编程:入门
  • Yii 开发者交流中心

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
作者最新文章
编程开发
相关文章 更多
精品专题 更多
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

PDF教程

正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

macOS软件

正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

IOS软件

正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

AI

正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

Mac软件 更多
WPS Office macOS版
WPS Office macOS版

WPS Office是一款面向macOS用户的综合办公套件,将文字处理、电子表格、演示文稿、PDF工具、模板与云协作整合在同一应用中。它兼容常见Microsoft Office格式,支持Intel及Apple芯片Mac,基础功能可免费使用,

Shapr3D macOS版
Shapr3D macOS版

Shapr3D是一款面向工业设计、机械工程、建筑概念和三维打印工作流的CAD软件。Mac版采用Parasolid建模内核,支持草图约束、实体建模、工程图、可视化渲染及常见CAD格式交换,并可通过账户在多台设备之间同步项目。

REAPER macOS版
REAPER macOS版

REAPER是Cockos开发的数字音频工作站,提供多轨音频与MIDI录制、剪辑、处理、混音和母带制作工具。Mac版兼容Intel与Apple芯片,支持AU、VST、VST3、CLAP等插件格式,并提供高度可定制的工作流程。

Ableton Live macOS版
Ableton Live macOS版

Ableton Live 是面向音乐制作人与现场表演者的数字音频工作站,提供编曲视图、独具特色的现场视图、音频录制、MIDI创作、实时变速、乐器及效果器。Mac版原生支持Apple芯片,并可连接音频接口、MIDI控制器和第三方插件。

Adobe After Effects macOS版
Adobe After Effects macOS版

Adobe After Effects 是面向动态图形、影视特效与视频合成的专业创作软件。它提供关键帧动画、遮罩抠像、运动跟踪、三维空间、文字动画和表达式等工具,并可与 Premiere Pro、Photoshop、Illustrator

Adobe Audition macOS版
Adobe Audition macOS版

Adobe Audition 是面向播客、影视后期、音乐制作及内容创作者的专业音频工作站,提供波形精修、多轨录制与混音、频谱编辑、降噪修复、响度匹配和效果处理工具,并可与 Adobe Premiere 协同完成视频声音制作。

Adobe Bridge macOS版
Adobe Bridge macOS版

Adobe Bridge 是面向摄影师、设计师及内容团队的免费数字资产管理工具,可集中预览照片、视频和 Adobe 项目文件,并利用评级、标签、关键词、元数据、筛选与收藏集完成分类检索。它还支持批量重命名、格式导出、相机导入及 Camera

Adobe Illustrator macOS版
Adobe Illustrator macOS版

Adobe Illustrator 是 Adobe 推出的专业矢量图形设计软件,适合在 Mac 上制作标志、图标、插画、包装、信息图及印刷版面。它以路径和锚点构建可无损缩放的图形,并提供钢笔、形状、文字、图像描摹、渐变、画板及生成式功能。

Adobe InDesign macOS版
Adobe InDesign macOS版

Adobe InDesign 是面向印刷品与数字出版物的专业版面设计软件,可在 Mac 上制作书籍、杂志、宣传册、海报、报告及交互式文档。它提供精细的文字样式、网格、母版、长文档管理和印前输出能力。

Adobe Lightroom Classic macOS版
Adobe Lightroom Classic macOS版

Adobe Lightroom Classic 是面向桌面摄影工作流的照片管理与后期处理软件,可将原始照片保存在本地硬盘,通过目录、关键词、评分和收藏夹高效整理图库,并提供 RAW 冲印、蒙版、镜头校正、批量同步及多格式导出等功能。

Adobe Media Encoder macOS版
Adobe Media Encoder macOS版

Adobe Media Encoder 是 Adobe 推出的专业音视频编码与转码工具,可通过队列、预设和监视文件夹批量完成格式转换、代理文件创建及多平台成片输出,并与 Premiere Pro、After Effects 等软件紧密协作。

Adobe Photoshop macOS版
Adobe Photoshop macOS版

Adobe Photoshop 是面向摄影师、设计师和内容创作者的专业图像处理软件,提供图层、蒙版、选区、修复、调色、文字排版、智能对象及生成式编辑等能力。Mac 版支持 Intel 与 Apple Silicon 处理器。

WINDOWS 更多
Adobe Photoshop Windows版
Adobe Photoshop Windows版

Adobe Photoshop 是面向摄影师、设计师和内容创作者的专业图像处理工具,可在 Windows 上完成照片修饰、选区抠图、图层合成、文字排版、绘画及生成式编辑。软件采用订阅授权,由 Creative Cloud 管理安装、更新与许

Adobe InDesign Windows版
Adobe InDesign Windows版

Adobe InDesign 是面向印刷与数字出版的专业页面排版工具,可制作书籍、杂志、宣传册、海报、交互式 PDF 和电子书。它提供精细的文字样式、多页面管理、印前检查及多格式输出能力,并能与 Photoshop、Illustrator

Adobe Illustrator Windows版
Adobe Illustrator Windows版

Adobe Illustrator 是用于绘制矢量图形、插画、图标、徽标和版式的专业设计工具。它以路径和锚点为核心,作品放大后仍能保持清晰,并提供画板、文字、渐变、图像描摹及精确变换等功能,适合品牌视觉、印刷物料、数字界面和商业插画创作。

Adobe Bridge Windows版
Adobe Bridge Windows版

Adobe Bridge 是 Adobe 推出的创意资产管理工具,可集中预览、分类和查找照片、视频、PDF及多种设计文件,并支持元数据、关键词、评级、批量重命名和格式导出。它可与 Photoshop、Illustrator 等应用衔接,

Affinity Photo Windows版
Affinity Photo Windows版

Affinity Photo 是一款面向摄影师、修图师和视觉设计人员的桌面图像编辑工具,提供 RAW 显影、多图层合成、蒙版、实时滤镜、批处理和色彩管理等功能。原独立产品已停止销售,其照片编辑能力已延续至免费的新 Affinity 应用;

Adobe Lightroom Classic Windows版
Adobe Lightroom Classic Windows版

Adobe Lightroom Classic 是面向 Windows 桌面摄影工作流的照片管理与无损编辑工具,可通过目录集中整理大型图库,并完成 RAW 显影、局部蒙版、批量调整、打印和多格式导出。它强调本地文件管理与精细控制,

Figma Windows版
Figma Windows版

Figma 是面向产品设计与开发团队的云端协作平台,可在 Windows 桌面客户端中完成界面绘制、组件管理、交互原型、评论评审和开发交付。文件保存在云端,多名成员能够同步编辑并共享设计系统;官方同时提供免费 Starter 方案及按席位计

Affinity Designer Windows版
Affinity Designer Windows版

Affinity Designer 是面向矢量图形、数字插画和界面设计的专业创作工具,可在矢量、像素与导出工作区之间快速切换。它提供曲线编辑、形状构建、画板、排版、图层和专业色彩管理,并支持常见设计文件的导入及多种印刷、网页格式输出。

Capture One Pro Windows版
Capture One Pro Windows版

Capture One Pro 是面向摄影师和影像团队的专业桌面照片处理工具,提供相机定制色彩配置、RAW转换、图层与蒙版、联机拍摄、目录及会话管理等功能。它适合棚拍、人像、商业产品、婚礼和风光摄影,

Adobe Acrobat Pro Windows版
Adobe Acrobat Pro Windows版

Adobe Acrobat Pro 是面向专业 PDF 工作的综合解决方案,可在 Windows 中创建、编辑、转换、比较、整理和保护文档,并支持表单、电子签名、扫描件文字识别及敏感信息永久遮盖。订阅还包含网页、移动服务和云端协作能力,

Adobe After Effects Windows版
Adobe After Effects Windows版

Adobe After Effects 是面向动态图形、动画与影视视觉特效制作的专业工具,可完成关键帧动画、图层合成、遮罩跟踪、抠像、文字动画和二维三维元素整合。Windows 版通过 Adobe Creative Cloud 安装及更新,

DaVinci Resolve Windows版
DaVinci Resolve Windows版

DaVinci Resolve是Blackmagic Design推出的一体化影视后期工具,将素材管理、非线性剪辑、专业调色、Fusion视觉特效、Fairlight音频处理和成片交付整合在统一工程中。免费版已覆盖多数个人创作需求,

网站备案号:苏ICP备2026018738号-1 联系邮箱:bd@zhengruan.com

Copyright ©2018-2026