/**
  * Conditional check for drip access.
  *
  * @since 140514 Enhancing `[s2Drip]` shortcode.
  *
  * @param string       $access Required; conditional expression with access_s2member_ capabilities
  *    (i.e., leveln, ccap_name), e.g., `level2` or `level3 and (ccap_music or ccap_videos)`.
  *    Note that `and`, `or` MUST be used in place of `&&`, `||` due to sanitation routines.
  *    The `$access` string may contain only `[A-Za-z0-9 _()]`.
  *
  * @param integer      $from_day Optional. Defaults to `0`. Any value greater than or equal to `0`.
  * @param integer      $to_day Optional. Defaults to `0`. Any value greater than or equal to `0`.
  *
  * @param null|integer $user_id Optional. A `NULL` value indicates the current user.
  *
  * @return boolean `TRUE` if user can `$access`; and dripping should occur; based on `$from_day` & `$to_day`.
  *
  * @triggers `E_USER_ERROR` if an invalid `$access` syntax is detected; with invalid chars.
  * @triggers `E_USER_ERROR` if an invalid `$access` syntax is detected; without any word chars.
  */
 public static function user_can_access_drip($access, $from_day = 0, $to_day = 0, $user_id = NULL)
 {
     $drip = FALSE;
     $access = trim((string) $access);
     $from_day = self::$from_day = (int) $from_day;
     $to_day = self::$to_day = (int) $to_day;
     if (!isset($user_id)) {
         $user_id = get_current_user_id();
     }
     $user_id = self::$user_id = (int) $user_id;
     if (user_can($user_id, 'administrator')) {
         $drip = TRUE;
     } else {
         if ($access && $user_id) {
             if (!is_array($all_access_cap_times = self::$all_access_cap_times = c_ws_plugin__s2member_access_cap_times::get_access_cap_times($user_id))) {
                 $all_access_cap_times = self::$all_access_cap_times = array();
             }
             $access_expression = strtolower($access);
             // e.g., 'level1 and ccap_music'
             $access_expression = trim(preg_replace('/[^a-z0-9 _()]/', '', $access_expression, -1, $invalid_chars));
             $access_expression = str_replace(array(' and ', ' or '), array(' && ', ' || '), $access_expression);
             if ($invalid_chars) {
                 trigger_error('Syntax error: invalid chars. Please use only `A-Za-z0-9 _()` in the `access` parameter of s2Drip.', E_USER_ERROR);
             }
             if (!$access_expression || !preg_match('/\\w+/', $access_expression)) {
                 trigger_error('Syntax error: no word chars in `access` parameter of s2Drip. Valid example: `level1 and ccap_music`.', E_USER_ERROR);
             }
             $access_expression = preg_replace_callback('/\\w+/', 'c_ws_plugin__s2member_pro_user_drip_access::_user_can_access_drip_cb', $access_expression);
             $drip = eval('return (' . $access_expression . ');');
         }
     }
     return apply_filters('ws_plugin__s2member_pro_user_can_access_drip', $drip, get_defined_vars());
 }