Kristof Coomans
function twitter_fetch_user_timeline($id) { $account = twitter_account_load($id); $since = db_query("...", array(':screen_name' => $account->screen_name)) ->fetchField(); $twitter = twitter_connect($account); $params = $since ? array('since_id' => $since) : array(); $statuses = $twitter->user_timeline($id, $params); foreach ($statuses as $status) { twitter_status_save($status); } if (count($statuses) > 0) { twitter_account_save($statuses[0]->user); } }
function twitter_connect($account) { $auth = $account->get_auth(); return new Twitter( variable_get('twitter_consumer_key'), variable_get('twitter_consumer_secret'), $auth['oauth_token'], $auth['oauth_token_secret'] ); }
Is this code easily testable and maintainable?
SOLID: 5 basic principles of object oriented programming and design
(Robert C. Martin)
Definition in YAML inside your module named example:
example.services.yml
Simplest form:
services: asset.css.optimizer: class: Drupal\Core\Asset\CssOptimizer
Equivalent to:
new \Drupal\Core\Asset\CssOptimizer();
services: database: ... config.storage.active: class: Drupal\Core\Config\DatabaseStorage arguments: ['@database', config] config.storage.snapshot: class: Drupal\Core\Config\DatabaseStorage arguments: ['@database', config_snapshot]
Equivalent to:
$database = ... $activeConfigStorage = new \Drupal\Core\Config\DatabaseStorage( $database, 'config' ); $snapshotConfigStorage = new \Drupal\Core\Config\DatabaseStorage( $database, 'config_snapshot' );
theme.manager: class: Drupal\Core\Theme\ThemeManager arguments: ... calls: - [setThemeRegistry, ['@theme.registry']] theme.registry: class: Drupal\Core\Theme\Registry arguments: ... calls: - [setThemeManager, ['@theme.manager']]
Equivalent to:
$themeManager = new \Drupal\Core\Theme\ThemeManager(...); $themeRegistry = new \Drupal\Core\Theme\Registry(...); $themeRegistry->setThemeManager($themeManager); $themeManager->setThemeRegistry($themeRegistry);
Code smell!
Creation by a static factory method
services: database: class: Drupal\Core\Database\Connection factory_class: Drupal\Core\Database\Database factory_method: getConnection arguments: [default]
Equivalent to:
$database = \Drupal\Core\Database\Database::getConnection('default');
OR by a factory service
services: cache_factory: ... cache.menu: class: Drupal\Core\Cache\CacheBackendInterface factory_method: get factory_service: cache_factory arguments: [menu]
Equivalent to:
$cacheFactory = ...; $menuCache = $cacheFactory::get('menu');
$container = \Drupal::getContainer(); $languageManager = $container->get('language_manager');
However, avoid using \Drupal::getContainer(), use dependency injection instead!
Implement a factory method interface!
/** * Provides a 'Language switcher' block. * ... */ class LanguageBlock extends BlockBase implements ContainerFactoryPluginInterface { public function __construct( array $configuration, $plugin_id, $plugin_definition, LanguageManagerInterface $language_manager, PathMatcherInterface $path_matcher ) { ... }
public static function create( ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition ) { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('language_manager'), $container->get('path.matcher') ); } }
class UserController extends ControllerBase { public function __construct( DateFormatter $date_formatter, UserStorageInterface $user_storage, UserDataInterface $user_data ) { $this->dateFormatter = $date_formatter; $this->userStorage = $user_storage; $this->userData = $user_data; }
public static function create( ContainerInterface $container ) { return new static( $container->get('date.formatter'), $container->get('entity.manager')->getStorage('user'), $container->get('user.data') ); } }
Faster to write it like in the old days?
$database = \Drupal\Core\Database\Database::getConnection('default');
services: database: class: Drupal\Core\Database\Connection factory_class: Drupal\Core\Database\Database factory_method: getConnection arguments: [default]
Remember:
Technique to improve your code, by applying far stricter coding standards, among which:
How to check? PHP CodeSniffer ruleset
List all upcoming events of the Drupal User Group Belgium announced at their Meetup page in a Block on a Drupal 8 website, by using their API.
Bonus: add caching on the API requests.