Статьи

Создание с помощью API Twitter: Tweet Storms

Конечный продукт
Что вы будете создавать

В апреле инвестор и основатель Netscape Марк Андреессен начал расширять естественный лимит Твиттера в 140 символов, публикуя свои мысли в виде последовательностей твитов, которые некоторые окрестили штормами твитов (предприниматель Иво Шаап собрал их на своем веб-сайте ).

Прошло совсем немного времени, прежде чем BuzzFeed (выскочка списка, который должен быть остановлен) восстал против этой практики: почему новейший тренд Twitter Tweetstorm ™ должен быть остановлен . Лично я, наверное, за что-то против BuzzFeed.

Возникло несколько сервисов, чтобы простым смертным, таким как мы, было легче публиковать твиты, но они казались немного ненадежными и непоследовательными. Я решил создать эту функцию сам, и я думаю, что делать это с вашим собственным приложением имеет смысл.

В этом уроке я расскажу, как создать собственную функцию штормового твита с помощью API Twitter. Это продолжение моей серии руководств по API Twitter на Tuts +; Вы можете найти ссылку на все из них на моей странице автора .

Во-первых, давайте решим, для чего нам нужна наша функция TweetStorm.

  • Создайте группу твитов.
  • Пронумеруйте их по порядку.
  • Публикуйте их в последовательном порядке в Twitter.
  • Предоставить общедоступную веб-страницу, позволяющую людям читать их вместе.
  • Опубликуйте ссылку на эту страницу в последнем твите.

Результаты должны выглядеть примерно так:

Пятиступенчатый твит-шторм с финальной публичной ссылкой

Я предполагаю, что вы знакомы с моим предыдущим руководством по Birdcage и уже имеете код, который аутентифицирует вашу учетную запись через OAuth с помощью API Twitter.

Птичья клетка использует таблицу статуса для твитов. Сначала мы расширим эту таблицу миграцией Yii ActiveRecord, включив в нее поля для опубликованного идентификатора tweet_id и числовой последовательности шторма твитов.

Расширение существующей модели базы данных довольно просто с помощью миграции Yii ActiveRecord:

1
./app/protected/yiic migrate create extend_status_table

Вот код миграции:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
 
class m141020_182509_extend_status_table_for_groups extends CDbMigration
{
  protected $MySqlOptions = ‘ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_unicode_ci’;
  public $tablePrefix;
  public $tableName;
 
  public function before() {
    $this->tablePrefix = Yii::app()->getDb()->tablePrefix;
    if ($this->tablePrefix <> »)
      $this->tableName = $this->tablePrefix.’status’;
  }
 
    public function safeUp()
    {
      $this->before();
    $this->addColumn($this->tableName,’tweet_id’,’BIGINT(20) DEFAULT 0′);
    $this->addColumn($this->tableName,’sequence’,’TINYINT DEFAULT 0′);
   $this->addColumn($this->tableName,’error_code’,’INTEGER DEFAULT 0′);
    }
 
    public function safeDown()
    {
        $this->before();
     $this->dropColumn($this->tableName,’tweet_id’);
     $this->dropColumn($this->tableName,’sequence’);
     $this->dropColumn($this->tableName,’error_code’);
    }
 
}

Мы будем использовать tweet_ids для публичного отображения всего шторма твитов на веб-странице после публикации. Числовая последовательность будет определять порядок твитов статуса в нашем шторме.

Далее нам нужно создать таблицу для контейнера твитов статуса, по сути, контейнера для шторма твитов. Я собираюсь использовать термин «Группа», потому что мы будем использовать его для другой функции группировки в следующем уроке, повторяя твиты из группы. Посетите мою страницу автора, чтобы узнать, когда она выйдет, или подпишитесь на меня в Twitter @reifman .

Давайте создадим новую миграцию для создания таблицы группы:

1
./app/protected/yiic migrate create create_group_table

Код ниже строит схему. Обратите внимание на отношение внешнего ключа, чтобы связать шторм твита с определенной учетной записью Twitter:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
 
class m141018_004954_create_group_table extends CDbMigration
{
   protected $MySqlOptions = ‘ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_unicode_ci’;
   public $tablePrefix;
   public $tableName;
 
   public function before() {
     $this->tablePrefix = Yii::app()->getDb()->tablePrefix;
     if ($this->tablePrefix <> »)
       $this->tableName = $this->tablePrefix.’group’;
   }
 
     public function safeUp()
    {
      $this->before();
    $this->createTable($this->tableName, array(
             ‘id’ => ‘pk’,
             ‘account_id’=>’integer default 0’,
             ‘name’=>’string default NULL’,
             ‘slug’=>’string default NULL’,
             ‘group_type’=>’tinyint default 0’,
             ‘stage’=>’integer default 0’,
             ‘created_at’ => ‘DATETIME NOT NULL DEFAULT 0’,
             ‘modified_at’ => ‘TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP’,
               ), $this->MySqlOptions);
               $this->addForeignKey(‘fk_group_account’, $this->tableName, ‘account_id’, $this->tablePrefix.’account’, ‘id’, ‘CASCADE’, ‘CASCADE’);
    }
 
    public function safeDown()
    {
        $this->before();
        $this->dropForeignKey(‘fk_group_account’, $this->tableName);
        $this->dropTable($this->tableName);
    }
}

Мы также GroupStatus реляционную таблицу с именем GroupStatus которая отслеживает твиты статуса в каждой группе:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
 
class m141018_020428_create_group_status_table extends CDbMigration
{
   protected $MySqlOptions = ‘ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_unicode_ci’;
   public $tablePrefix;
   public $tableName;
 
   public function before() {
     $this->tablePrefix = Yii::app()->getDb()->tablePrefix;
     if ($this->tablePrefix <> »)
       $this->tableName = $this->tablePrefix.’group_status’;
   }
 
     public function safeUp()
    {
      $this->before();
    $this->createTable($this->tableName, array(
             ‘id’ => ‘pk’,
             ‘group_id’ => ‘INTEGER NOT NULL’,
             ‘status_id’ => ‘INTEGER default 0’,
               ), $this->MySqlOptions);
               $this->addForeignKey(‘fk_group_status_group’, $this->tableName, ‘group_id’, $this->tablePrefix.’group’, ‘id’, ‘CASCADE’, ‘CASCADE’);
               $this->addForeignKey(‘fk_group_status_status’, $this->tableName, ‘status_id’, $this->tablePrefix.’status’, ‘id’, ‘CASCADE’, ‘CASCADE’);
    }
 
    public function safeDown()
    {
        $this->before();
        $this->dropForeignKey(‘fk_group_status_group’, $this->tableName);
        $this->dropForeignKey(‘fk_group_status_status’, $this->tableName);
        $this->dropTable($this->tableName);
    }
}

Чтобы публично отобразить шторм твитов на веб-странице, нам на самом деле нужна еще одна таблица для кэширования HTML-кода с помощью twitter_id из метода Oembed API Twitter :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
 
class m141021_203519_create_embed_table extends CDbMigration
{
   protected $MySqlOptions = ‘ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_unicode_ci’;
   public $tablePrefix;
   public $tableName;
 
   public function before() {
     $this->tablePrefix = Yii::app()->getDb()->tablePrefix;
     if ($this->tablePrefix <> »)
       $this->tableName = $this->tablePrefix.’embed’;
   }
 
     public function safeUp()
    {
      $this->before();
    $this->createTable($this->tableName, array(
             ‘id’ => ‘pk’,
             ‘tweet_id’ => ‘bigint(20) unsigned NOT NULL’,
             ‘html’ => ‘text default null’,
             ‘created_at’ => ‘DATETIME NOT NULL DEFAULT 0’,
             ‘modified_at’ => ‘TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP’,
               ), $this->MySqlOptions);
               $this->createIndex(‘tweet_id’, $this->tableName , ‘tweet_id’, false);
    }
 
    public function safeDown()
    {
        $this->before();
        $this->dropIndex(‘tweet_id’, $this->tableName);
        $this->dropTable($this->tableName);
    }
}

Далее мы будем использовать генератор кода Yii, Gii, для построения модели, контроллеров и CRUD. В моей локальной среде я захожу на http: // localhost: 8888 / twitter / app / gii, чтобы получить доступ к Gii . Сначала я создаю модель:

Yii Model Generator

Затем я использую генератор Bootstrap CRUD:

Bootstrap Generator

Мы также будем использовать Gii для создания моделей по умолчанию для таблиц GroupStatus и Embed. Им не нужны контроллеры и представления.

В представлении панели навигации ( /app/protected/views/layouts/main.php ) я добавлю параметр в моем меню «Создать» в группу твитов:

1
2
3
4
5
6
array(‘label’=>’Compose’, ‘items’=> array(
         array(‘url’=>array(‘/status/compose’), ‘label’=>’Schedule a tweet’),
         array(‘url’=>array(‘/group’), ‘label’=>’Group tweets’),
         array(‘url’=>array(‘/status/admin’), ‘label’=>’Manage schedule’),
         array(‘url’=>array(‘/statuslog/admin’), ‘label’=>’Review log’),
       )),

Страница управления групповыми твитами выглядит следующим образом:

Управление группами твитов штормов

Щелчок на крайнем левом значке в каждой строке открывает группу для добавления твитов и их упорядочивания.

Нажав на ссылку меню «Добавить группу», вы увидите форму, которая позволяет вам назвать шторм твита и выбрать для него учетную запись Twitter:

Создать группу для Tweet Storm

Нам нужно расширить поведение создания по умолчанию, чтобы завершить модель. Я повторно использую свой метод Slugify из Geogram, чтобы создать URL-подобный слаг из имени. Добавьте это в Group.php :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
    * Modifies a string to remove all non ASCII characters and spaces.
    */
 public function slugify($text)
 {
   //sourcecookbook.com/en/recipes/8/function-to-slugify-strings-in-php
     // replace non letter or digits by —
     $text = preg_replace(‘~[^\\pL\d]+~u’, ‘-‘, $text);
     // trim
     $text = trim($text, ‘-‘);
     // transliterate
     if (function_exists(‘iconv’))
     {
         $text = iconv(‘utf-8’, ‘us-ascii//TRANSLIT’, $text);
     }
     // lowercase
     $text = strtolower($text);
     // remove unwanted characters
     $text = preg_replace(‘~[^-\w]+~’, », $text);
     if (empty($text))
     {
         return ‘error-generating-slug’;
     }
     return $text;
 }

Вот модифицированный actionCreate в GroupController.php :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
public function actionCreate()
   {
       $model=new Group;
       // Uncomment the following line if AJAX validation is needed
       // $this->performAjaxValidation($model);
       if(isset($_POST[‘Group’]))
       {
           $model->attributes=$_POST[‘Group’];
           $model->slug=Group::model()->slugify($model->name);
     $model->created_at = new CDbExpression(‘NOW()’);
     $model->modified_at =new CDbExpression(‘NOW()’);
           if($model->save())
               $this->redirect(array(‘view’,’id’=>$model->id));
       }
       $this->render(‘create’,array(
           ‘model’=>$model,
       ));
   }

Затем вы добавляете твиты статуса для своего шторма и выбираете числовую последовательность, с которой они должны появляться:

Составьте твит статуса для шторма твитов

Мы используем производную форму статуса составить форму из Birdcage:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<?php
$this->breadcrumbs=array(
    ‘Statuses’=>array(‘index’),
    ‘Create’,
);
 
/*
$this->menu=array(
    array(‘label’=>’Manage schedule’,’url’=>array(‘admin’)),
    array(‘label’=>’Review log’,’url’=>array(‘statuslog/admin’)),
);
*/
?>
 
<h1>Compose a Tweet for your Group</h1>
<?php
 echo $this->renderPartial(‘_groupform’, array(‘model’=>$model,’maxCount’=>$maxCount));

Вот _groupform.php представления _groupform.php :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?php
 
$baseUrl = Yii::app()->baseUrl;
$cs = Yii::app()->getClientScript();
$cs->registerScriptFile($baseUrl.’/js/jquery.simplyCountable.js’);
$cs->registerScriptFile($baseUrl.’/js/twitter-text.js’);
$cs->registerScriptFile($baseUrl.’/js/twitter_count.js’);
 
?>
<?php $form=$this->beginWidget(‘bootstrap.widgets.TbActiveForm’,array(
    ‘id’=>’status-form’,
    ‘enableAjaxValidation’=>false,
));
 
<?php
  if(Yii::app()->user->hasFlash(‘no_account’)
    ) {
  $this->widget(‘bootstrap.widgets.TbAlert’, array(
      ‘alerts’=>array( // configurations per alert type
        ‘no_account’=>array(‘block’=>true, ‘fade’=>true, ‘closeText’=>’×’),
      ),
  ));
}
?>
 
    <p class=»help-block»>Fields with <span class=»required»>*
 
    <?php echo $form->errorSummary($model);
 
<?php echo $form->hiddenField($model,’account_id’,array(‘value’=>$model->account_id));
  <br />
    <?php
    echo $form->textAreaRow($model,’tweet_text’,array(‘id’=>’tweet_text’,’rows’=>6, ‘cols’=>50, ‘class’=>’span8’));
   ?>
   <p class=»right»>Remaining: <span id=»counter2″>0
 
    <?php
     echo CHtml::activeLabel($model,’sequence’,array(‘label’=>’Sequence:’));
   ?>
 
   <?php echo $form->dropDownList($model,’sequence’, $model->getSequence());
 
 
</div> <!— end section method —>
    <div class=»form-actions»>
        <?php $this->widget(‘bootstrap.widgets.TbButton’, array(
            ‘buttonType’=>’submit’,
            ‘type’=>’primary’,
            ‘label’=>$model->isNewRecord ?
        ));
    </div>
 
<?php $this->endWidget();
<script type=»text/javascript» charset=»utf-8″>
    $(document).ready(function()
    {
      $(‘#section_schedule’).hide();
      $(‘#section_method’).hide();
      $(‘#tweet_text’).simplyCountable({
        counter: ‘#counter2’,
      maxCount: <?php echo $maxCount ?>,
      countDirection: ‘down’
      });
    });
   
</script>

Вот метод getSequence который использует форма из Status.php :

1
2
3
4
5
6
7
8
9
public function getSequence() {
       $i=1;
       $seq = array(‘default’=>’select sequence below’);
       while ($i<=99) {
         $seq[$i]=$i;
         $i++;
       }
       return $seq;
     }

Статусные твиты в группах — это четыре символа короче 140, чтобы можно было вставить порядковую нумерацию.

Когда вы добавляете твиты статуса в свою группу, страница управления группой будет выглядеть примерно так:

Групповое представление для твитов штормовых статусов

Будущие улучшения могут включать элементы управления перемещением вверх / вниз для элементов статуса, а также автоматическую нумерацию при добавлении новых твитов.

Хотя вы можете просто публиковать твиты по порядку, полезно управлять ими в фоновом режиме для обеспечения надежности на случай, если на полпути возникнут сбои.

Поскольку многие функции Twitter API требуют использования курсора или подкачки страниц, я уже встроил модель фонового процесса в свою продвинутую среду Birdhouse . Я покажу вам основы добавления публикации твитов в ваше приложение.

Когда вы нажимаете «Опубликовать шторм», мы создаем действие для управления этим процессом в фоновом режиме:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
public function publish($group_id) {
     // create an action to publish the storm in the background
     $gp = Group::model()->findByPK($group_id);
   $check_dup = Action::model()->findByAttributes(array(‘action’=>Action::ACTION_STORM,’item_id’=>$group_id,’status’=>Action::STATUS_ACTIVE));
    if (empty($check_dup)) {
     $a = new Action;
     $a->account_id = $gp->account_id;
     $a->action = Action::ACTION_STORM;
     $a->status = Action::STATUS_ACTIVE;
     $a->item_id = $group_id;
      $a->created_at = new CDbExpression(‘NOW()’);
      $a->modified_at =new CDbExpression(‘NOW()’);
     $a->save();
   }
   }

Затем обычные фоновые задачи cron управляют таблицей Action и вызывают Action::model()->publishStorm :

01
02
03
04
05
06
07
08
09
10
public function publishStorm($action) {
     // publish group twitter storm
     $results = Group::model()->publishStormItems($action->account_id,$action->item_id);
     if ($results) {
       // if true, action is complete
     $a = Action::model()->findByPk($action->id);
     $a->status=self::STATUS_COMPLETE;
     $a->save();
     }
   }

Это, в свою очередь, вызывает publishStormItems модели publishStormItems :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// publish the group as a twitter storm
   public function publishStormItems($account_id,$group_id) {
     $error = false;
     $account = Account::model()->findByPK($account_id);
   // make the connection to Twitter
     $twitter = Yii::app()->twitter->getTwitterTokened($account[‘oauth_token’], $account[‘oauth_token_secret’]);
     // get unpublished statuses in specific group
      $statuses = Status::model()->in_account($account_id)->stage_zero()->in_specific_group($group_id)->findAll(array(‘order’=>’sequence ASC’));
      $tweet_id = 0;
    foreach ($statuses as $status) {
      $prefix = $status->sequence.’.
      // add sequence count as prefix
      echo $prefix.$status->tweet_text;lb();
      $tweet_id = Status::model()->postTweet($twitter,$status,$prefix);
      if ($tweet_id!=0) {
         // update stage to published = 1
         $ns = Yii::app()->db->createCommand()->update(Yii::app()->getDb()->tablePrefix.’status’,array(‘stage’=>1,’tweet_id’=>$tweet_id),’id=:id’, array(‘:id’=>$status->id));
      } else {
        $error = true;
      }
    }
    // if finishing up
    if (count($statuses)>0 and !$error) {
      // publish final tweet with link to the storm
      $group = Group::model()->findByPk($group_id);
      $status = ‘Read or share my tweet storm on ‘.$group->name.’
      if (strlen($status)>120) {
        $status = ‘Read or share all of my tweet storm: ‘.$_SERVER[«SERVER_NAME»].’/storm/’.$group->slug;
      }
      $tweet= $twitter->post(«statuses/update»,array(‘status’=>$status));
    }
     // if done, return true
     return !$error;
   }

Запрос ActiveRecord, который мы используем, чтобы найти статусные твиты в неопубликованной группе, выглядит следующим образом:

1
$statuses = Status::model()->in_account($account_id)->stage_zero()->in_specific_group($group_id)->findAll(array(‘order’=>’sequence ASC’));

Этот запрос использует области, которые определены следующим образом в модели состояния:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public function scopes()
     {
         return array(
             // part of a group of tweets
             ‘in_group’=>array(
               ‘condition’=>’status_type=’.self::STATUS_TYPE_IN_GROUP,
             ),
             ‘stage_zero’=>array(
               ‘condition’=>’stage=0’,
             ),
             ‘has_tweet_id’=>array(
               ‘condition’=>’tweet_id<>0’,
             ),
         );
     }
 
     public function in_specific_group($group_id)
     {
             $crit = $this->getDbCriteria();
             $crit->addCondition(«
                       id IN (
                         SELECT status_id FROM tw_group_status
                         WHERE
                             group_id = :group_id
                     )
             «);
             $crit->params[‘:group_id’] = $group_id;
             return $this;
     }
      
     // custom scopes
     public function in_account($account_id=0)
     {
       $this->getDbCriteria()->mergeWith( array(
         ‘condition’=>’account_id=’.$account_id,
       ));
         return $this;
     }

Поскольку мы перебираем все статусы, которые нужно твитнуть, мы добавляем префикс для порядкового номера, например, «1. Мой первый твит это …»:

01
02
03
04
05
06
07
08
09
10
11
12
foreach ($statuses as $status) {
      $prefix = $status->sequence.’.
      // add sequence count as prefix
      echo $prefix.$status->tweet_text;lb();
      $tweet_id = Status::model()->postTweet($twitter,$status,$prefix);
      if ($tweet_id!=0) {
         // update stage to published = 1
         $ns = Yii::app()->db->createCommand()->update(Yii::app()->getDb()->tablePrefix.’status’,array(‘stage’=>1,’tweet_id’=>$tweet_id),’id=:id’, array(‘:id’=>$status->id));
      } else {
        $error = true;
      }
    }

Когда статус публикуется, этап увеличивается. Будущие улучшения могут включать возможность повторного размещения штормов твитов несколько раз. В настоящее время мы разрешаем одну публикацию (пожалуйста, Buzzfeed).

Если все твиты были успешно опубликованы, мы публикуем финальный твит со ссылкой на шторм твитов:

01
02
03
04
05
06
07
08
09
10
// if finishing up
    if (count($statuses)>0 and !$error) {
      // publish final tweet with link to the storm
      $group = Group::model()->findByPk($group_id);
      $status = ‘Read or share my tweet storm on ‘.$group->name.’
      if (strlen($status)>130) {
        $status = ‘Read or share all of my tweet storm: ‘.$_SERVER[«SERVER_NAME»].’/storm/’.$group->slug;
      }
      $tweet= $twitter->post(«statuses/update»,array(‘status’=>$status));
    }

Вот как выглядит Tweet Storm при публикации :

Еще один пример твитовой бури в моем потоке

Поэтому, хотя мы могли бы публично отображать твиты в Интернете в текстовой форме, такой как Yvo Schaap , я подумал, что было бы лучше использовать встраивания Twitter, с которыми пользователь может взаимодействовать, например, follow, reply, retweet et al.

Tweet Storm опубликован в Интернете с помощью HTML-кода OEmbed

Сначала я думал, что смогу использовать статический HTML-код и просто заменить twitter_id в представлении, но Twitter предпочитает, чтобы вы делали вызов OEmbed и кэшировали HTML для каждого твита. Я создал таблицу Embed выше, чтобы сделать это.

Итак, во-первых, давайте создадим маршрут в UriiManager в Yii, чтобы путь нашего приложения мог перенаправляться для просмотра твитов с помощью URL-дружественного слага. В /app/protected/config/main.php добавьте перенаправление штормовой слаг ниже. Это перенаправит запросы на http: // yourdomain / storm / my-ideas-on-twitters-api к действию поиска контроллера группы с my-ideas-on-twitters-api в качестве параметра:

01
02
03
04
05
06
07
08
09
10
11
12
13
‘urlManager’=>array(
               ‘urlFormat’=>’path’,
               ‘showScriptName’=>false,
               ‘caseSensitive’=>false,
               ‘rules’=>array(
                   ‘<controller:\w+>/<id:\d+>’=>'<controller>/view’,
                   ‘<controller:\w+>/<action:\w+>/<id:\d+>’=>'<controller>/<action>’,
                   ‘<controller:\w+>/<action:\w+>’=>'<controller>/<action>’,
                   ‘/hybridauth’ => ‘/hybridauth’,
                   ‘/storm/<slug>’ => ‘/group/lookup/’,
                   » => ‘site/index’
               ),
           ),

Используя фильтры доступа к контроллеру Yii, давайте сделаем так, чтобы любой публичный посетитель мог просматривать штормы, но действия CRUD видны только аутентифицированным пользователям. Измените accessRules в GroupController.php следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
public function accessRules()
   {
       return array(
           array(‘allow’, // allow all users to perform ‘storm’
               ‘actions’=>array(‘lookup’),
               ‘users’=>array(‘*’),
           ),
           array(‘allow’, // allow authenticated user to perform these actions
               ‘actions’=>array(‘index’,’view’,’create’,’update’,’delete’),
               ‘users’=>array(‘@’),
           ),
           array(‘allow’, // allow admin user to perform ‘admin’ actions
               ‘actions’=>array(»),
               ‘users’=>array(‘admin’),
           ),
           array(‘deny’, // deny all users
               ‘users’=>array(‘*’),
           ),
       );
   }

Когда приходит запрос для http://yourdomain.com/storm/your-storm-name , он направляется к действию поиска контроллера группы:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
public function actionLookup($slug) {
     $success = false;
     $this->layout = ‘storm’;
   // try look up by slug
   $group = Group::model()->findByAttributes(array(‘slug’=>$slug));
   $embeds = Group::model()->fetchEmbeds($group->id);
   if ($group !== null) {
     $success = true;
           $this->render(‘lookup’,array(
            ’embeds’=>$embeds,
            ‘name’=>$group->name,
           ));
     }
   }

Метод fetchEmbeds сначала ищет в нашей базе данных кэшированную копию, а затем внешне в API Twitter для извлечения HTML-кода. Метод fetchEmbeds создает массив твитов HTML:

01
02
03
04
05
06
07
08
09
10
public function fetchEmbeds($group_id) {
     $e = new Embed();
     $group = Group::model()->findByPk($group_id);
     $embed =array();
      $statuses = Status::model()->in_account($group->account_id)->has_tweet_id()->in_specific_group($group_id)->findAll(array(‘order’=>’sequence ASC’));
     foreach ($statuses as $status) {
       $embed[]=$e->fetch($group->account_id, $status->tweet_id);
     }
     return $embed;
   }

Он использует метод извлечения модели Embed:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public function fetch($account_id,$tweet_id) {
   // is it in embed table
   $data = Embed::model()->findByAttributes(array(‘tweet_id’=>$tweet_id));
   if (empty($data)) {
     // is there a connection
     if (is_null($this->twitter)) {
       $account = Account::model()->findByPK($account_id);
       // make the connection to Twitter
       $this->twitter = Yii::app()->twitter->getTwitterTokened($account[‘oauth_token’], $account[‘oauth_token_secret’]);
     }
     $result= $this->twitter->get(«statuses/oembed»,array(‘id’=>$tweet_id));
     $html = $result->html;
     $this->add($tweet_id,$html);
   } else {
     $html = $data->html;
   }
     return $html;
 }
 
public function add($tweet_id,$html) {
  $e = new Embed();
  $e->html = $html;
  $e->tweet_id=$tweet_id;
  $e->modified_at = new CDbExpression(‘NOW()’);
  $e->created_at = new CDbExpression(‘NOW()’);
  $e->save();
}

Он только инициирует OAuth-соединение с Twitter, если есть хотя бы один tweet_id, который нужно извлечь, и делает это только один раз по соображениям производительности.

Я надеюсь, что вы нашли этот учебник шторм твит полезным. Это была определенно забавная функция для создания. Пожалуйста, не стесняйтесь размещать исправления, вопросы или комментарии ниже. Я стараюсь не отставать от комментариев Tuts +. Вы также можете связаться со мной в Twitter @reifman или написать мне напрямую.

Вы можете найти начальное руководство по API Twitter для Birdcage здесь и ссылку на все мои руководства по API Twitter на моей странице автора Tuts + по мере их публикации. Birdcage предлагает бесплатный репозиторий Github с открытым исходным кодом для начала работы с основными функциями API Twitter.