diff --git a/core/modules/poll/lib/Drupal/poll/Plugin/block/block/PollRecentBlock.php b/core/modules/poll/lib/Drupal/poll/Plugin/block/block/PollRecentBlock.php
new file mode 100644
index 0000000..81ec76f
--- /dev/null
+++ b/core/modules/poll/lib/Drupal/poll/Plugin/block/block/PollRecentBlock.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Drupal\poll\Plugin\block\block;
+
+use Drupal\block\BlockBase;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+
+/**
+ * @Plugin(
+ *   id = "poll_recent_block",
+ *   subject = @Translation("Most recent poll"),
+ *   module = "poll"
+ * )
+ */
+class PollRecentBlock extends BlockBase {
+  protected $record;
+
+  /**
+   * Implements BlockInterface::settings().
+   */
+  public function settings() {
+    return array(
+      'properties' => array(
+        'administrative' => TRUE,
+      ),
+    );
+  }
+
+  /**
+   * Implements BlockInterface::access().
+   */
+  public function access() {
+    if (user_access('access content')) {
+      // Retrieve the latest poll.
+      $select = db_select('node', 'n');
+      $select->join('poll', 'p', 'p.nid = n.nid');
+      $select->fields('n', array('nid'))
+        ->condition('n.status', 1)
+        ->condition('p.active', 1)
+        ->orderBy('n.created', 'DESC')
+        ->range(0, 1)
+        ->addTag('node_access');
+
+      $record = $select->execute()->fetchObject();
+      if ($record) {
+        $this->record = $record;
+        return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
+  /**
+   * Implements BlockInterface::build().
+   */
+  public function build() {
+    $poll = node_load($this->record->nid);
+    if ($poll->nid) {
+      $poll = poll_block_latest_poll_view($poll);
+      return array(
+        $poll->content
+      );
+    }
+    return array();
+  }
+}
\ No newline at end of file
diff --git a/core/modules/poll/poll.module b/core/modules/poll/poll.module
index c85f121..c7f5e56 100644
--- a/core/modules/poll/poll.module
+++ b/core/modules/poll/poll.module
@@ -119,47 +119,6 @@ function _poll_menu_access($node, $perm, $inspect_allowvotes) {
 }
 
 /**
- * Implements hook_block_info().
- */
-function poll_block_info() {
-  $blocks['recent']['info'] = t('Most recent poll');
-  $blocks['recent']['properties']['administrative'] = TRUE;
-  return $blocks;
-}
-
-/**
- * Implements hook_block_view().
- *
- * Generates a block containing the latest poll.
- *
- * @see poll_block_latest_poll_view()
- */
-function poll_block_view($delta = '') {
-  if (user_access('access content')) {
-    // Retrieve the latest poll.
-    $select = db_select('node', 'n');
-    $select->join('poll', 'p', 'p.nid = n.nid');
-    $select->fields('n', array('nid'))
-      ->condition('n.status', 1)
-      ->condition('p.active', 1)
-      ->orderBy('n.created', 'DESC')
-      ->range(0, 1)
-      ->addTag('node_access');
-
-    $record = $select->execute()->fetchObject();
-    if ($record) {
-      $poll = node_load($record->nid);
-      if ($poll->nid) {
-        $poll = poll_block_latest_poll_view($poll);
-        $block['subject'] = t('Poll');
-        $block['content'] = $poll->content;
-        return $block;
-      }
-    }
-  }
-}
-
-/**
  * Implements hook_cron().
  *
  * Closes polls that have exceeded their allowed runtime.
