diff --git a/cloudflare.services.yml b/cloudflare.services.yml
index 7e16b4c..4e419db 100644
--- a/cloudflare.services.yml
+++ b/cloudflare.services.yml
@@ -11,3 +11,8 @@ services:
arguments: ['%cloudflare.cache_tag_header_limit%']
tags:
- { name: event_subscriber }
+ cloudflare:
+ class: Drupal\cloudflare\CloudFlareService
+ arguments: ['@config.factory']
+ tags:
+ - { name: cloudflare}
diff --git a/src/CloudFlareService.php b/src/CloudFlareService.php
new file mode 100644
index 0000000..6d67cec
--- /dev/null
+++ b/src/CloudFlareService.php
@@ -0,0 +1,191 @@
+config = $config->get('cloudflare.settings');
+ $this->api_key = $config->get('apikey');
+ $this->email = $config->get('email');
+
+ if ($this->hasValidApiCredentials()) {
+ $this->zone = $this->getCurrentZoneId();
+ }
+ }
+
+ /**
+ * Invalidates tags at CloudFlare edge.
+ *
+ * @param array $tags
+ * String array of tag names to invalidate.
+ */
+ public function invalidateByTags(array $tags) {
+ if (!$this->hasValidApiCredentials()) {
+ return;
+ }
+
+ try {
+ $this->zoneApi = new ZoneApi($this->apiKey, $this->email);
+ $this->zoneApi->purgeTags($this->zone, $tags);
+ }
+
+ catch (CloudFlareHttpException $e) {
+ drupal_set_message("Unable to clear zone cache. " . $e->getMessage(), 'error');
+ \Drupal::logger('cloudflare')->error($e->getMessage());
+ return;
+ }
+
+ catch (CloudFlareApiException $e) {
+ drupal_set_message("Unable to clear zone cache. " . $e->getMessage(), 'error');
+ \Drupal::logger('cloudflare')->error($e->getMessage());
+ return;
+ }
+
+ // If no exceptions have been thrown then the request has been successful.
+ }
+
+ /**
+ * Invalidates paths at CloudFlare edge.
+ *
+ * @param array $paths
+ * String array of paths to invalidate.
+ */
+ public function invalidateByPath(array $paths) {
+ if (!$this->hasValidApiCredentials()) {
+ return;
+ }
+
+ try {
+ $this->zoneApi = new ZoneApi($this->apiKey, $this->email);
+ $this->zoneApi->purgeIndividualFiles($this->zone, $paths);
+ }
+
+ catch (CloudFlareHttpException $e) {
+ drupal_set_message("Unable to clear zone cache. " . $e->getMessage(), 'error');
+ \Drupal::logger('cloudflare')->error($e->getMessage());
+ return;
+ }
+
+ catch (CloudFlareApiException $e) {
+ drupal_set_message("Unable to clear zone cache. " . $e->getMessage(), 'error');
+ \Drupal::logger('cloudflare')->error($e->getMessage());
+ return;
+ }
+ }
+
+ /**
+ * Invalidates entire zone at CloudFlare edge. Use cautiously.
+ */
+ public function invalidateZone() {
+ if (!$this->hasValidApiCredentials()) {
+ return;
+ }
+
+ try {
+ $this->zoneApi = new ZoneApi($this->apiKey, $this->email);
+ $this->zoneApi->purgeAllFiles($this->zone);
+ }
+
+ catch (CloudFlareHttpException $e) {
+ drupal_set_message("Unable to clear zone cache. " . $e->getMessage(), 'error');
+ \Drupal::logger('cloudflare')->error($e->getMessage());
+ return;
+ }
+
+ catch (CloudFlareApiException $e) {
+ drupal_set_message("Unable to clear zone cache. " . $e->getMessage(), 'error');
+ \Drupal::logger('cloudflare')->error($e->getMessage());
+ return;
+ }
+ }
+
+ /**
+ * Determine the current Cloudflare ZoneId for the site.
+ *
+ * Most CloudFlare accounts have a single zone. It can be assumed as the
+ * default. If there is more than one the user needs to specify the zone.
+ * on the cloudflare config page.
+ *
+ * @return string
+ * The id of the current zone.
+ */
+ public function getCurrentZoneId() {
+ $has_zone_in_cmi = !is_null($this->config->get('zone'));
+
+ // If this is a multi-zone cloudflare account and a zone has been set.
+ if ($has_zone_in_cmi) {
+ return $this->config->get('zone');
+ }
+
+ // If there is no zone set and the account only has a single zone.
+ $zones_from_api = $this->zoneApi->listZones();
+ $num_zones_from_api = count($zones_from_api);
+ $is_single_zone_cloudflare_account = $num_zones_from_api == 1;
+ if ($is_single_zone_cloudflare_account) {
+ return $zones_from_api[0]->getZoneId();
+ }
+
+ // If the zone has multiple accounts and none is specified in CMI we cannot
+ // move forward.
+ if (!$is_single_zone_cloudflare_account) {
+ $link_to_settings = '/admin/config/services/cloudflare/zone';
+ $message = t('No default zone has been entered for CloudFlare. Please go here to set.', ['@link_to_settings' => $link_to_settings]);
+
+ drupal_set_message($message, 'error');
+ \Drupal::logger('cloudflare')->error($message);
+ }
+ }
+
+ /**
+ * Checks if the site has valid CloudFlare Api credentials.
+ */
+ private function hasValidApiCredentials() {
+ if (!isset($this->apiKey)) {
+ $link_to_settings = '/admin/config/services/cloudflare';
+ $message = t('No valid credentials have been entered for CloudFlare. Please go here to set them.', ['@link_to_settings' => $link_to_settings]);
+
+ drupal_set_message($message, 'error');
+ \Drupal::logger('cloudflare')->error($message);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+}