get_id(); return [ 'blog_id' => 'required|integer', 'domain' => "required|domain|unique:\WP_Ultimo\Models\Domain,domain,{$id}", 'stage' => 'required|in:checking-dns,checking-ssl-cert,done-without-ssl,done,failed|default:checking-dns', 'active' => 'default:1', 'secure' => 'default:0', 'primary_domain' => 'default:0', ]; } /** * Returns the domain address mapped. * * @since 2.0.0 * @return string */ public function get_domain() { return $this->domain; } /** * Sets the domain of this model object; * * @since 2.0.0 * * @param string $domain Your Domain name. You don't need to put http or https in front of your domain in this field. e.g: example.com. * @return void */ public function set_domain($domain): void { $this->domain = strtolower($domain); } /** * Gets the URL with schema and all. * * @since 2.0.0 * * @param string $path The path to add to the end of the url. */ public function get_url($path = ''): string { $schema = $this->is_secure() ? 'https://' : 'http://'; return sprintf('%s%s/%s', $schema, $this->get_domain(), $path); } /** * Get the ID of the corresponding site. * * @access public * @since 2.0 * @return int */ public function get_blog_id() { return (int) $this->blog_id; } /** * Sets the blog_id of this model object; * * @since 2.0.0 * * @param int $blog_id The blog ID attached to this domain. * @return void */ public function set_blog_id($blog_id): void { $this->blog_id = $blog_id; } /** * Get the ID of the corresponding site. * * @since 2.0.0 * @return int */ public function get_site_id() { return $this->get_blog_id(); } /** * Get the site object for this particular mapping. * * @since 2.0.0 * @return \WP_Site|\WP_Ultimo\Models\Site|false */ public function get_site() { /** * In a domain mapping environment, the user is not yet logged in. * This means that we can't use BerlinDB, unfortunately, as it uses the user caps * to decide which fields to make available. * * To bypass this limitation, we use the default WordPress function on those cases. */ if ( ! function_exists('current_user_can')) { return \WP_Site::get_instance($this->get_blog_id()); } return wu_get_site($this->get_blog_id()); } /** * Check if this particular mapping is active. * * @since 2.0.0 * @return boolean */ public function is_active() { if ($this->has_inactive_stage()) { return false; } return (bool) $this->active; } /** * Sets the active state of this model object; * * @since 2.0.0 * * @param boolean $active Set this domain as active (true), which means available to be used, or inactive (false). * @return void */ public function set_active($active): void { $this->active = $active; } /** * Check if this is a primary domain. * * @since 2.0.0 * @return boolean */ public function is_primary_domain() { return (bool) $this->primary_domain; } /** * Sets the primary_domain state of this model object; * * @since 2.0.0 * * @param boolean $primary_domain Define true to set this as primary domain of a site, meaning it's the main url, or set false. * @return void */ public function set_primary_domain($primary_domain): void { $this->primary_domain = $primary_domain; } /** * Check if we should use this domain securely (via HTTPS). * * @since 2.0.0 * @return boolean */ public function is_secure() { return (bool) $this->secure; } /** * Sets the secure state of this model object; * * @since 2.0.0 * * @param boolean $secure If this domain has some SSL security or not. * @return void */ public function set_secure($secure): void { $this->secure = $secure; } /** * Get the stage in which this domain is in at the moment. * * This is used to check the stage of the domain lifecycle. * * @since 2.0.0 * @return string */ public function get_stage() { return $this->stage; } /** * Sets the stage of this model object; * * @since 2.0.0 * * @param string $stage The state of the domain model object. Can be one of this options: checking-dns, checking-ssl-cert, done-without-ssl, done and failed. * @return void */ public function set_stage($stage): void { $this->stage = $stage; } /** * Check if this domain is on a inactive stage. * * @since 2.0.0 */ public function has_inactive_stage(): bool { return in_array($this->get_stage(), self::INACTIVE_STAGES, true); } /** * Returns the Label for a given stage level. * * @since 2.0.0 * @return string */ public function get_stage_label() { $type = new Domain_Stage($this->get_stage()); return $type->get_label(); } /** * Gets the classes for a given stage level. * * @since 2.0.0 * @return string */ public function get_stage_class() { $type = new Domain_Stage($this->get_stage()); return $type->get_classes(); } /** * Get date when this was created. * * @since 2.0.0 * @return string */ public function get_date_created() { return $this->date_created; } /** * Set date when this was created. * * @since 2.0.0 * @param string $date_created Date when the domain was created. If no date is set, the current date and time will be used. * @return void */ public function set_date_created($date_created): void { $this->date_created = $date_created; } /** * Check if the domain is correctly set-up in terms of DNS resolution. * * @since 2.0.0 * @return boolean */ public function has_correct_dns() { global $current_site; $domain_url = $this->get_domain(); $network_ip_address = Helper::get_network_public_ip(); $results = \WP_Ultimo\Managers\Domain_Manager::dns_get_record($domain_url); $domains_and_ips = array_column($results, 'data'); if (in_array($current_site->domain, $domains_and_ips, true)) { return true; } if (in_array($network_ip_address, $domains_and_ips, true)) { return true; } $result = false; /** * Allow plugin developers to add new checks in order to define the results. * * @since 2.0.4 * @param bool $result the current result. * @param self $this The current domain instance. * @param array $domains_and_ips The list of domains and IPs found on the DNS lookup. * @return bool If the DNS is correctly setup or not. */ $result = apply_filters('wu_domain_has_correct_dns', $result, $this, $domains_and_ips); return $result; } /** * Checks if the current domain has a valid SSL certificate that covers it. * * @since 2.0.0 * @return boolean */ public function has_valid_ssl_certificate() { return Helper::has_valid_ssl_certificate($this->get_domain()); } /** * Save (create or update) the model on the database. * * Needs to override the parent implementation * to clear the cache. * * @since 2.0.0 * * @return bool */ public function save() { $new_domain = $this->exists(); $before_changes = clone $this; $results = parent::save(); if (is_wp_error($results) === false) { if ($new_domain) { if (has_action('mercator.mapping.created')) { $deprecated_args = [ $this, ]; /** * Deprecated: Mercator created domain. * * @since 2.0.0 * @param self The domain object after saving. * @param self The domain object before the changes. * @return void. */ do_action_deprecated('mercator.mapping.created', $deprecated_args, '2.0.0', 'wu_domain_post_save'); } } elseif (has_action('mercator.mapping.updated')) { $deprecated_args = [ $this, $before_changes, ]; /** * Deprecated: Mercator updated domain. * * @since 2.0.0 * @param self The domain object after saving. * @param self The domain object before the changes. * @return void. */ do_action_deprecated('mercator.mapping.updated', $deprecated_args, '2.0.0', 'wu_domain_post_save'); } /* * Resets cache. * * This will make sure the list of domains gets rebuild * after a change is made. */ wp_cache_flush(); } return $results; } /** * Delete the model from the database. * * @since 2.0.0 * @return \WP_Error|bool */ public function delete() { $results = parent::delete(); if (is_wp_error($results) === false && has_action('mercator.mapping.deleted')) { $deprecated_args = [ $this, ]; /** * Deprecated: Mercator Deleted domain. * * @since 2.0.0 * @param self The domain object just deleted. * @return void. */ do_action_deprecated('mercator.mapping.deleted', $deprecated_args, '2.0.0', 'wu_domain_post_delete'); } /* * Delete log file. */ wu_log_clear("domain-{$this->get_domain()}"); wu_log_add("domain-{$this->get_domain()}", __('Domain deleted and logs cleared...', 'wp-ultimo')); return $results; } /** * Get mapping by site ID * * @since 2.0.0 * * @param int|stdClass $site Site ID, or site object from {@see get_blog_details}. * @return Domain|Domain[]|\WP_Error|false Mapping on success, WP_Error if error occurred, or false if no mapping found. */ public static function get_by_site($site) { global $wpdb; // Allow passing a site object in if (is_object($site) && isset($site->blog_id)) { $site = $site->blog_id; } if ( ! is_numeric($site)) { return new \WP_Error('wu_domain_mapping_invalid_id'); } $site = absint($site); // Check cache first $mappings = wp_cache_get('id:' . $site, 'domain_mapping'); if ('none' === $mappings) { return false; } if ( ! empty($mappings)) { return static::to_instances($mappings); } // Cache missed, fetch from DB // Suppress errors in case the table doesn't exist $suppress = $wpdb->suppress_errors(); $domain_table = "{$wpdb->base_prefix}wu_domain_mappings"; $mappings = $wpdb->get_results($wpdb->prepare('SELECT * FROM ' . $domain_table . ' WHERE blog_id = %d ORDER BY primary_domain DESC, active DESC, secure DESC', $site)); //phpcs:ignore $wpdb->suppress_errors($suppress); if ( ! $mappings) { wp_cache_set('id:' . $site, 'none', 'domain_mapping'); return false; } wp_cache_set('id:' . $site, $mappings, 'domain_mapping'); return static::to_instances($mappings); } /** * Gets mappings by domain names * * Note: This is used in sunrise, so unfortunately, we can't use the Query model. * * @since 2.0.0 * * @param array|string $domains Domain names to search for. * @return object */ public static function get_by_domain($domains) { global $wpdb; $domains = (array) $domains; // Check cache first $not_exists = 0; foreach ($domains as $domain) { $data = wp_cache_get('domain:' . $domain, 'domain_mappings'); if ( ! empty($data) && 'notexists' !== $data) { return new static($data); } elseif ('notexists' === $data) { ++$not_exists; } } if (count($domains) === $not_exists) { // Every domain we checked was found in the cache, but doesn't exist // so skip the query return null; } $placeholders = array_fill(0, count($domains), '%s'); $placeholders_in = implode(',', $placeholders); // Prepare the query $query = "SELECT * FROM {$wpdb->wu_dmtable} WHERE domain IN ($placeholders_in) AND active = 1 ORDER BY primary_domain DESC, active DESC, secure DESC LIMIT 1"; $query = $wpdb->prepare($query, $domains); // phpcs:ignore // Suppress errors in case the table doesn't exist $suppress = $wpdb->suppress_errors(); $mapping = $wpdb->get_row($query); // phpcs:ignore $wpdb->suppress_errors($suppress); if (empty($mapping)) { // Cache that it doesn't exist foreach ($domains as $domain) { wp_cache_set('domain:' . $domain, 'notexists', 'domain_mappings'); } return null; } wp_cache_set('domain:' . $mapping->domain, $mapping, 'domain_mappings'); return new static($mapping); } }