You are here

PcpService.php in Profile Complete Percent 8

Namespace

Drupal\pcp

File

src/PcpService.php
View source
<?php

namespace Drupal\pcp;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\field\FieldConfigInterface;
use Drupal\user\UserInterface;

/**
 * Class PcpService.
 *
 * @package Drupal\pcp
 */
class PcpService implements PcpServiceInterface {

  /**
   * The entity field manager.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected $entityFieldManager;

  /**
   * The pcp settings configuration.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected $config;

  /**
   * PcpService constructor.
   *
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager
   *   The entity field manager.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   The configuration factory.
   */
  public function __construct(EntityFieldManagerInterface $entityFieldManager, ConfigFactoryInterface $configFactory) {
    $this->entityFieldManager = $entityFieldManager;
    $this->config = $configFactory
      ->get('pcp.settings');
  }

  /**
   * {@inheritdoc}
   */
  public function getCompletePercentageData(UserInterface $user) {
    $userFields = $this
      ->getUserFields();

    /** @var array $profileFields */
    $profileFields = array_filter($this->config
      ->get('profile_fields'));

    // Filter out the fields that are deleted. Outdated configuration may still
    // contain non-existing fields.
    $profileFields = array_intersect_key($profileFields, $userFields);
    if (empty($profileFields)) {
      return [
        'current_percent' => 100,
        'next_percent' => 0,
      ];
    }

    // Collect data of empty fields.
    $emptyFields = [];
    foreach ($profileFields as $fieldName) {
      if ($user
        ->get($fieldName)
        ->isEmpty()) {
        $emptyFields[$fieldName] = $userFields[$fieldName]
          ->label();
      }
    }
    $fieldCount = count($profileFields);
    $emptyFieldCount = count($emptyFields);
    $completedFieldCount = $fieldCount - $emptyFieldCount;
    $nextField = $this
      ->getNextField($emptyFields);
    $nextFieldTitle = isset($emptyFields[$nextField]) ? $emptyFields[$nextField] : '';
    return [
      'uid' => $user
        ->id(),
      'total' => $fieldCount,
      'open_link' => $this->config
        ->get('open_link') == 0 ? '_self' : '_target',
      'completed' => $completedFieldCount,
      'incomplete' => $emptyFieldCount,
      'hide_pcp_block' => (bool) $this->config
        ->get('hide_block_on_complete'),
      'nextfield_title' => $nextFieldTitle,
      'current_percent' => $this
        ->calcCurrentPercentage($completedFieldCount, $fieldCount),
      'next_percent' => $this
        ->calcNextPercentage($completedFieldCount, $fieldCount),
      'nextfield_name' => str_replace('_', '-', $nextField),
    ];
  }

  /**
   * Returns the user profile fields.
   *
   * @return \Drupal\Core\Field\FieldDefinitionInterface[]
   *   Array of field configurations.
   */
  protected function getUserFields() {
    $fields = array_filter($this->entityFieldManager
      ->getFieldDefinitions('user', 'user'), function ($field_definition) {
      return $field_definition instanceof FieldConfigInterface;
    });
    return $fields;
  }

  /**
   * Returns the next field.
   *
   * Depending on configuration, a random field or the first available field is
   * picked. When random is configured, every time the user reloads the page a
   * different field will be shown.
   *
   * @param array $fields
   *   The fields to choose from.
   *
   * @return string
   *   The field name of the next field. Empty string if not available.
   */
  protected function getNextField(array $fields) {
    if (empty($fields)) {
      return '';
    }

    // Return random value if configured to do so.
    if ($this->config
      ->get('field_order') == 0) {
      return array_rand($fields);
    }
    return key($fields);
  }

  /**
   * Calculates the percentage of fields currently completed.
   *
   * @param int $completed
   *   The number of fields completed.
   * @param int $total
   *   The total number of fields.
   *
   * @return int
   *   The calculated percentage.
   */
  protected function calcCurrentPercentage($completed, $total) {
    if ($total === 0) {
      return 0;
    }
    return round($completed * 100 / $total);
  }

  /**
   * Calculates the percentage of fields completed when one more is completed.
   *
   * @param int $completed
   *   The number of fields completed.
   * @param int $total
   *   The total number of fields.
   *
   * @return int
   *   The calculated percentage.
   */
  protected function calcNextPercentage($completed, $total) {
    if ($total === 0) {
      return 0;
    }
    return round(($completed + 1) * 100 / $total);
  }

}

Classes

Namesort descending Description
PcpService Class PcpService.