Commit d01b644b authored by James Yao's avatar James Yao Committed by Joseph Olstad
Browse files

Issue #3273351 by joseph.olstad, jamesyao: bulk archive and bulk publish verify

parent 2bc5a077
Loading
Loading
Loading
Loading
+123 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ use Drupal\menu_link_content\Entity\MenuLinkContent;
use Drupal\media\Entity\Media;
use Drupal\file\Entity\File;
use Drupal\Core\Link;
use Drupal\Core\Render\Markup;


/**
@@ -611,3 +612,125 @@ function safedelete_cron() {
  $database = \Drupal::database();
  AdminHelper::listOrphanedNodes($reporteddate, $orphanedpages_results,$filedirectory, $database);
}

/**
 * Implements hook_moderated_content_bulk_publish_verify_archived().
 *
 * @param \Drupal\moderated_content_bulk_publish\HookObject.
 *   An object with properties by reference.
 */
function safedelete_moderated_content_bulk_publish_verify_archived($hookObject) {
  $state = 'archived';
  $limit = 20;
  $nid = $hookObject->nid;
  $bundle = $hookObject->bundle;
  $show_button = $hookObject->show_button;
  $markup = $hookObject->markup;
  $error_message = $hookObject->error_message;
  AdminHelper::checkNodeReferencesMessage($nid, $bundle, $show_button, $markup, $state, $limit);
  // Pass references back.
  $hookObject->show_button = $show_button;
  $hookObject->markup = $markup;
  //echo print_r($hookObject, TRUE);
  if (!$hookObject->show_button) {
    $hookObject->error_message = t('Unable to archive due to other content linking to this content.  See warning message(s)');
  }
}


/**
 * Implements hook_moderated_content_bulk_publish_verify_publish().
 *
 * @param \Drupal\moderated_content_bulk_publish\HookObject.
 *   An object with properties by reference.
 */
function safedelete_moderated_content_bulk_publish_verify_publish($hookObject) {
  $state = 'publish';
  $body_field_val = $hookObject->body_field_val;
  $nid = $hookObject->nid;
  AdminHelper::checkUrlToken($body_field_val, $found_token_href, $msgdetail_isToken);
  AdminHelper::checkPagePublished($body_field_val, $found_unpublished_node, $msgdetail_isPublished);
  AdminHelper::checkAbsoluteUrl($body_field_val, $found_absolute_url, $msgdetail_isAbsoluteURL);
  if ($found_token_href || $found_unpublished_node || $found_absolute_url) {
    $msgtitle = t('Unable to publish node %nid. See warning message(s).',['%nid' =>$nid]);
    $hookObject->error_message = $msgtitle;
    $hookObject->msgdetail_isToken = $msgdetail_isToken;
    $hookObject->msgdetail_isPublished = $msgdetail_isPublished;
    $hookObject->msgdetail_isAbsoluteURL = $msgdetail_isAbsoluteURL;
    $hookObject->validate_failure = TRUE;
  }
}

/**
 * Implements hook_preprocess_status_messages().
 *
 * Updates or removes the status message (type = status),
 * and displays the warning message (type = warning) if bulk action process fails.
 */
function safedelete_preprocess_status_messages(&$variables) {
  $msg = '';
  $msgCount = 0;
  $action = 'Archive current revision';
  if (isset($variables['message_list']['status'])){
    $msgCount = count($variables['message_list']['status']);
    if ($msgCount > 0) {
      // Get the last item of Status Message for the archive bulk action.
      $msg =  $variables['message_list']['status'][($msgCount-1)];
    };
  }
  // Only handles Archive current revision action
  if (isset($variables['message_list']['warning']) && (stripos($msg, $action) !== false)) {
    $warning_messages = $variables['message_list']['warning'];
    $warningCount = count($variables['message_list']['warning']);
    $totalCount = 0;
    if ($warningCount > 0) {
      $int_str = preg_replace('/[^0-9]/', '', $msg);
      $totalCount = intval($int_str);
      $diffCount = $totalCount - ($warningCount - 1);
      $diff_str = strval($diffCount);
      if ($diffCount == 0 ) {
        unset($variables['message_list']['status']);
      }
      else if ($diffCount == 1) {
        $new_msg = t(str_replace($int_str . ' items', $diff_str . ' item', $msg));
        $variables['message_list']['status'][($msgCount-1)] = Markup::create($new_msg);
      }
      else {
        $diff_str = strval($diffCount);
        $new_msg = t(str_replace($int_str ,$diff_str, $msg));
        $variables['message_list']['status'][($msgCount-1)] = Markup::create($new_msg);
      }
    }
  }

  $bulk_publish_action = 'Publish latest revision';
  // Only handles Publish latest revision action
  if (isset($variables['message_list']['warning']) && (stripos($msg, $bulk_publish_action) !== false)) {
    $warningCount = 0;
    $warning_messages = $variables['message_list']['warning'];
    foreach($warning_messages as $delta => $message) {
      $pattern = '/Unable to publish node \<em class=\"placeholder\"\>\d*\<\/em\>./';
      if(preg_match_all($pattern, $message, $matches)) {
        $warningCount = $warningCount + 1;
      }
    }
    if ($warningCount > 0) {
      $int_str = preg_replace('/[^0-9]/', '', $msg);
      $totalCount = intval($int_str);
      $diffCount = $totalCount - $warningCount;
      $diff_str = strval($diffCount);
      if ($diffCount == 0 ) {
        unset($variables['message_list']['status']);
      }
      else if ($diffCount == 1) {
        $new_msg = t(str_replace($int_str . ' items', $diff_str . ' item', $msg));
        $variables['message_list']['status'][0] = Markup::create($new_msg);
      }
      else {
        $diff_str = strval($diffCount);
        $new_msg = t(str_replace($int_str ,$diff_str, $msg));
        $variables['message_list']['status'][0] = Markup::create($new_msg);
      }
    }
  }
}
+140 −4
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ use Drupal\file\Entity\File;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\Core\Database\Connection;
use Drupal\Component\Utility\UrlHelper;


class AdminHelper {
@@ -375,6 +376,7 @@ EOT;
   * Safe delete validation and message prep.
   */
  static public function checkNodeReferencesMessage($nid = null, &$bundle = 'page', &$show_button = TRUE, &$markup = '', $type = 'delete', $limit = 20) {
    $root_nid = $nid;
    $action_result = 'deleted';
    if ($type == 'archived') {
      $action_result = $type;
@@ -434,8 +436,11 @@ EOT;
    if (count($result) > 0) {
      $show_button = FALSE;
      $msg_type = t('Safe Delete verification check status');
      $temp = 'This node is being used in entities and cannot be %action. Please edit the following content first and remove the link:';
      $markup = t($temp, ['%action' => $action_result]) . '<ul>';
      $temp = 'This node %nid is being used in entities and cannot be %action. Please edit the following content first and remove the link:';
      $markup = t($temp, [
        '%nid' => $root_nid,
        '%action' => $action_result,
      ]) . '<ul>';
      $list_count = 0;
      foreach ($result as $entity_type => $results) {

@@ -697,6 +702,19 @@ EOT;
  public static function getUrlForNode($nid, $lang = 'en') {
    $host_path = \Drupal::request()->getSchemeAndHttpHost();
    $base_path = \Drupal::request()->getBasePath();
    $is_multilingual = (int) \Drupal::languageManager()->isMultilingual();
    $has_langprefix = FALSE;

    if ($is_multilingual) {
      static::addToLog($is_multilingual . ' = multilingual', FALSE);
      $config = \Drupal::configFactory()->get('language.negotiation');
      $prefix_config = $config->get('url.prefixes');
      if (isset($prefix_config[$lang])) {
        if ($prefix_config[$lang] == $lang) {
          $has_langprefix = TRUE;
        }
      }
    }
    if (strlen($base_path) > 0) {
      if (stripos(strval($base_path), '/') < 0) {
        $host_path = $host_path . '/' . $base_path;
@@ -707,12 +725,130 @@ EOT;
    }
    $relative = \Drupal::service('path_alias.manager')->getAliasByPath('/node/' . $nid, $lang);

    if (isset($relative['alias'])) {
    if ($has_langprefix && isset($relative['alias'])) {
      $url = $host_path . '/' . $lang . $relative['alias'];
    }
    else {
    else if ($has_langprefix) {
      $url = $host_path . '/' . $lang . '/node/' . $nid;
    }
    else {
      $url = $host_path . '/node/' . $nid;
    }
    return $url;
  }


    /**
   * Verify if the current access unpublished hashtoken is found.
   */
  public static function checkUrlToken($bodyval, &$foundtokenhref = FALSE, &$markup = '') {
    $regex_token = '/\?auHash=/';
    preg_match_all($regex_token, $bodyval, $matches, PREG_SET_ORDER);
    foreach ($matches as $match_token) {
      $tokenhref = reset($match_token);
      if (isset($tokenhref) && strlen($tokenhref) == 8) {
        if (!$foundtokenhref) {
          $foundtokenhref = TRUE;
          $msg = t('Please remove any links to Preview/Draft pages (pages whose URL contains "auHash").');
          $markup = '<p style="color:#e0ac00; font-size:16px;"><strong>' . $msg .'</strong></p>';
          break;
        }
      }
    }
  }

  /**
   * Verify if the page is published or not.
   */
  public static function checkPagePublished($formbody, &$foundunpublishingnode = FALSE, &$markup ='') {
    $temparry = [];
    $regex_mediaobj = "/data-entity-type=\"node\" data-entity-uuid=\"([a-z]|[0-9]){8}-(([0-9]|[a-z]){4}-){3}([0-9]|[a-z]){12}\"/";
    $regex_uuid = "/([a-z]|[0-9]){8}-(([0-9]|[a-z]){4}-){3}([0-9]|[a-z]){12}/";
    preg_match_all($regex_mediaobj, $formbody, $matches, PREG_SET_ORDER);
    foreach ($matches as $match) {
      $tmpmsg = '';
      $node = reset($match);
      preg_match_all($regex_uuid, $node, $id_match, PREG_SET_ORDER);
      $nodeuuid = $id_match[0][0];
      $nentity = \Drupal::service('entity.repository')->loadEntityByUuid('node', $nodeuuid);
      if (is_null($nentity)) {
        continue;
      }
      $nodeid = $nentity->id();
      $nmstate = $nentity->get('moderation_state')->getValue();
      $nmstatetmp = array_pop($nmstate);
      $nmstateStr = array_pop($nmstatetmp);
      if ($nmstateStr != 'published') {
        if (!$foundunpublishingnode) {
          $foundunpublishingnode = TRUE;
          $msg = t('Please publish the identified pages first and then publish the current one.');
          $markup = '<p style="color:#e0ac00; font-size:16px;"><strong>' . $msg .'</strong></p>';
          $markup =  $markup  . '<ul>';
        }
        $tmpmsg = '<li>' . $node . " /node/" . $nodeid . '</li>';
        if (!in_array($tmpmsg, $temparry, true)) {
          $markup = $markup . $tmpmsg;
          array_push($temparry, $tmpmsg);
        }
      }
    }
    if ($foundunpublishingnode) {
      $markup =$markup . '</ul>';
    }
  }

  /**
   * Verify if the url in the form body is absolute or not.
   *
   * Returns (bool)
   *   True or false.
   */
  public static function checkAbsoluteUrl($formbody, &$found_absolute_url = FALSE, &$markup ='') {
    $regex_tokenabspath = '/href=\".*\"/m';
    preg_match_all($regex_tokenabspath, $formbody, $pathmatches, PREG_SET_ORDER);
    $temparry = [];
    foreach ($pathmatches as $match) {
      $tmpmsg = '';
      $hrefpath = reset($match);
      // Ignore the token case.
      $tokenhead = "?auHash=";
      if (strpos($hrefpath, $tokenhead) == FALSE) {
        $path = str_replace("href=\"", "", $hrefpath);
        $path = str_replace("\"", "", $path);
        if (UrlHelper::isExternal($path) && UrlHelper::isValid($path, TRUE)) {
          if (UrlHelper::externalIsLocal($path, \Drupal::request()->getSchemeAndHttpHost())) {
            $absolutepathstring = $path;
            $base_path = \Drupal::request()->getBasePath();
            $host = parse_url($path, PHP_URL_HOST);
            $host_end = strpos($path, $host) + strlen($host) + strlen($base_path);
            $path = substr($path, $host_end);
            $path = urldecode(trim($path, '/'));
            $path_args = explode('/', $path);
            $prefix = array_shift($path_args);
            $path = '/' . implode('/', $path_args);
            $nodpath = \Drupal::service('path_alias.manager')->getPathByAlias($path, $prefix);
            if (preg_match('/node\/(\d+)/', $nodpath, $matches)) {
              $hrefnode = Node::load($matches[1]);
              if (isset($hrefnode)) {
                if (!$found_absolute_url) {
                  $found_absolute_url = TRUE;
                  $msg = t('Please use Linkit to complete the reference.');
                  $markup = '<p style="color:#e0ac00; font-size:16px;"><strong>' . $msg .'</strong></p>';
                  $markup =  $markup  . '<ul>';
                }
                $tmpmsg =  '<li>' . $absolutepathstring . '</li>';
                if (!in_array($tmpmsg, $temparry, true)) {
                  $markup = $markup . $tmpmsg;
                  array_push($temparry, $tmpmsg);
                }
              }
            }
          }
        }
      }
    }
    if ($found_absolute_url) {
      $markup = $markup . '</ul>';
    }
  }
}