dvadf
File manager - Edit - /home/centroca/public_html/classes.tar
Back
class-twentynineteen-svg-icons.php 0000644 00000167726 15252477157 0013410 0 ustar 00 <?php /** * SVG Icons class * * @package WordPress * @subpackage Twenty_Nineteen * @since Twenty Nineteen 1.0 */ /** * This class is in charge of displaying SVG icons across the site. * * Place each <svg> source on its own array key, without adding the * both `width` and `height` attributes, since these are added dynamically, * before rendering the SVG code. * * All icons are assumed to have equal width and height, hence the option * to only specify a `$size` parameter in the svg methods. * * @since Twenty Nineteen 1.0 */ class TwentyNineteen_SVG_Icons { /** * Gets the SVG code for a given icon. */ public static function get_svg( $group, $icon, $size ) { if ( 'ui' === $group ) { $arr = self::$ui_icons; } elseif ( 'social' === $group ) { $arr = self::$social_icons; } else { $arr = array(); } if ( array_key_exists( $icon, $arr ) ) { $repl = sprintf( '<svg class="svg-icon" width="%d" height="%d" aria-hidden="true" role="img" focusable="false" ', $size, $size ); $svg = preg_replace( '/^<svg /', $repl, trim( $arr[ $icon ] ) ); // Add extra attributes to SVG code. $svg = preg_replace( "/([\n\t]+)/", ' ', $svg ); // Remove newlines & tabs. $svg = preg_replace( '/>\s*</', '><', $svg ); // Remove whitespace between SVG tags. return $svg; } return null; } /** * Detects the social network from a URL and returns the SVG code for its icon. */ public static function get_social_link_svg( $uri, $size ) { static $regex_map; // Only compute regex map once, for performance. if ( ! isset( $regex_map ) ) { $regex_map = array(); $map = &self::$social_icons_map; // Use reference instead of copy, to save memory. foreach ( array_keys( self::$social_icons ) as $icon ) { $domains = array_key_exists( $icon, $map ) ? $map[ $icon ] : array( sprintf( '%s.com', $icon ) ); $domains = array_map( 'trim', $domains ); // Remove leading/trailing spaces, to prevent regex from failing to match. $domains = array_map( 'preg_quote', $domains ); $regex_map[ $icon ] = sprintf( '/(%s)/i', implode( '|', $domains ) ); } } foreach ( $regex_map as $icon => $regex ) { if ( preg_match( $regex, $uri ) ) { return self::get_svg( 'social', $icon, $size ); } } return null; } /** * User Interface icons – svg sources. * * @var array */ static $ui_icons = array( 'link' => /* material-design – link */ ' <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M0 0h24v24H0z" fill="none"></path> <path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path> </svg>', 'watch' => /* material-design – watch-later */ ' <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <defs> <path id="a" d="M0 0h24v24H0V0z"></path> </defs> <clipPath id="b"> <use xlink:href="#a" overflow="visible"></use> </clipPath> <path clip-path="url(#b)" d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm4.2 14.2L11 13V7h1.5v5.2l4.5 2.7-.8 1.3z"></path> </svg>', 'archive' => /* material-design – folder */ ' <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"></path> <path d="M0 0h24v24H0z" fill="none"></path> </svg>', 'tag' => /* material-design – local_offer */ ' <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"></path> <path d="M0 0h24v24H0z" fill="none"></path> </svg>', 'comment' => /* material-design – comment */ ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M21.99 4c0-1.1-.89-2-1.99-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4-.01-18z"></path> <path d="M0 0h24v24H0z" fill="none"></path> </svg>', 'person' => /* material-design – person */ ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"></path> <path d="M0 0h24v24H0z" fill="none"></path> </svg>', 'edit' => /* material-design – edit */ ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"></path> <path d="M0 0h24v24H0z" fill="none"></path> </svg>', 'chevron_left' => /* material-design – chevron_left */ ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path> <path d="M0 0h24v24H0z" fill="none"></path> </svg>', 'chevron_right' => /* material-design – chevron_right */ ' <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path> <path d="M0 0h24v24H0z" fill="none"></path> </svg>', 'check' => /* material-design – check */ ' <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M0 0h24v24H0z" fill="none"></path> <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"></path> </svg>', 'arrow_drop_down_circle' => /* material-design – arrow_drop_down_circle */ ' <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M0 0h24v24H0z" fill="none"></path> <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 12l-4-4h8l-4 4z"></path> </svg>', 'keyboard_arrow_down' => /* material-design – keyboard_arrow_down */ ' <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z"></path> <path fill="none" d="M0 0h24v24H0V0z"></path> </svg>', 'keyboard_arrow_right' => /* material-design – keyboard_arrow_right */ ' <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M10 17l5-5-5-5v10z"></path> <path fill="none" d="M0 24V0h24v24H0z"></path> </svg>', 'keyboard_arrow_left' => /* material-design – keyboard_arrow_left */ ' <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M14 7l-5 5 5 5V7z"></path> <path fill="none" d="M24 0v24H0V0h24z"></path> </svg>', 'arrow_drop_down_ellipsis' => /* custom – arrow_drop_down_ellipsis */ ' <svg xmlns="http://www.w3.org/2000/svg"> <g fill="none" fill-rule="evenodd"> <path d="M0 0h24v24H0z"/> <path fill="currentColor" fill-rule="nonzero" d="M12 2c5.52 0 10 4.48 10 10s-4.48 10-10 10S2 17.52 2 12 6.48 2 12 2zM6 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm6 0a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm6 0a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/> </g> </svg>', ); /** * Social Icons – domain mappings. * * By default, each Icon ID is matched against a .com TLD. To override this behavior, * specify all the domains it covers (including the .com TLD too, if applicable). * * @var array */ static $social_icons_map = array( 'amazon' => array( 'amazon.com', 'amazon.cn', 'amazon.in', 'amazon.fr', 'amazon.de', 'amazon.it', 'amazon.nl', 'amazon.es', 'amazon.co', 'amazon.ca', ), 'apple' => array( 'apple.com', 'itunes.com', ), 'behance' => array( 'behance.net', ), 'codepen' => array( 'codepen.io', ), 'facebook' => array( 'facebook.com', 'fb.me', ), 'feed' => array( 'feed', ), 'google-plus' => array( 'plus.google.com', ), 'lastfm' => array( 'last.fm', ), 'mail' => array( 'mailto:', ), 'slideshare' => array( 'slideshare.net', ), 'pocket' => array( 'getpocket.com', ), 'twitch' => array( 'twitch.tv', ), 'wordpress' => array( 'wordpress.com', 'wordpress.org', ), ); /** * Social Icons – svg sources. * * @var array */ static $social_icons = array( '500px' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M6.94026,15.1412c.00437.01213.108.29862.168.44064a6.55008,6.55008,0,1,0,6.03191-9.09557,6.68654,6.68654,0,0,0-2.58357.51467A8.53914,8.53914,0,0,0,8.21268,8.61344L8.209,8.61725V3.22948l9.0504-.00008c.32934-.0036.32934-.46353.32934-.61466s0-.61091-.33035-.61467L7.47248,2a.43.43,0,0,0-.43131.42692v7.58355c0,.24466.30476.42131.58793.4819.553.11812.68074-.05864.81617-.2457l.018-.02481A10.52673,10.52673,0,0,1,9.32258,9.258a5.35268,5.35268,0,1,1,7.58985,7.54976,5.417,5.417,0,0,1-3.80867,1.56365,5.17483,5.17483,0,0,1-2.69822-.74478l.00342-4.61111a2.79372,2.79372,0,0,1,.71372-1.78792,2.61611,2.61611,0,0,1,1.98282-.89477,2.75683,2.75683,0,0,1,1.95525.79477,2.66867,2.66867,0,0,1,.79656,1.909,2.724,2.724,0,0,1-2.75849,2.748,4.94651,4.94651,0,0,1-.86254-.13719c-.31234-.093-.44519.34058-.48892.48349-.16811.54966.08453.65862.13687.67489a3.75751,3.75751,0,0,0,1.25234.18375,3.94634,3.94634,0,1,0-2.82444-6.742,3.67478,3.67478,0,0,0-1.13028,2.584l-.00041.02323c-.0035.11667-.00579,2.881-.00644,3.78811l-.00407-.00451a6.18521,6.18521,0,0,1-1.0851-1.86092c-.10544-.27856-.34358-.22925-.66857-.12917-.14192.04372-.57386.17677-.47833.489Zm4.65165-1.08338a.51346.51346,0,0,0,.19513.31818l.02276.022a.52945.52945,0,0,0,.3517.18416.24242.24242,0,0,0,.16577-.0611c.05473-.05082.67382-.67812.73287-.738l.69041.68819a.28978.28978,0,0,0,.21437.11032.53239.53239,0,0,0,.35708-.19486c.29792-.30419.14885-.46821.07676-.54751l-.69954-.69975.72952-.73469c.16-.17311.01874-.35708-.12218-.498-.20461-.20461-.402-.25742-.52855-.14083l-.7254.72665-.73354-.73375a.20128.20128,0,0,0-.14179-.05695.54135.54135,0,0,0-.34379.19648c-.22561.22555-.274.38149-.15656.5059l.73374.7315-.72942.73072A.26589.26589,0,0,0,11.59191,14.05782Zm1.59866-9.915A8.86081,8.86081,0,0,0,9.854,4.776a.26169.26169,0,0,0-.16938.22759.92978.92978,0,0,0,.08619.42094c.05682.14524.20779.531.50006.41955a8.40969,8.40969,0,0,1,2.91968-.55484,7.87875,7.87875,0,0,1,3.086.62286,8.61817,8.61817,0,0,1,2.30562,1.49315.2781.2781,0,0,0,.18318.07586c.15529,0,.30425-.15253.43167-.29551.21268-.23861.35873-.4369.1492-.63538a8.50425,8.50425,0,0,0-2.62312-1.694A9.0177,9.0177,0,0,0,13.19058,4.14283ZM19.50945,18.6236h0a.93171.93171,0,0,0-.36642-.25406.26589.26589,0,0,0-.27613.06613l-.06943.06929A7.90606,7.90606,0,0,1,7.60639,18.505a7.57284,7.57284,0,0,1-1.696-2.51537,8.58715,8.58715,0,0,1-.5147-1.77754l-.00871-.04864c-.04939-.25873-.28755-.27684-.62981-.22448-.14234.02178-.5755.088-.53426.39969l.001.00712a9.08807,9.08807,0,0,0,15.406,4.99094c.00193-.00192.04753-.04718.0725-.07436C19.79425,19.16234,19.87422,18.98728,19.50945,18.6236Z"></path> </svg>', 'amazon' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M13.582,8.182C11.934,8.367,9.78,8.49,8.238,9.166c-1.781,0.769-3.03,2.337-3.03,4.644 c0,2.953,1.86,4.429,4.253,4.429c2.02,0,3.125-0.477,4.685-2.065c0.516,0.747,0.685,1.109,1.629,1.894 c0.212,0.114,0.483,0.103,0.672-0.066l0.006,0.006c0.567-0.505,1.599-1.401,2.18-1.888c0.231-0.188,0.19-0.496,0.009-0.754 c-0.52-0.718-1.072-1.303-1.072-2.634V8.305c0-1.876,0.133-3.599-1.249-4.891C15.23,2.369,13.422,2,12.04,2 C9.336,2,6.318,3.01,5.686,6.351C5.618,6.706,5.877,6.893,6.109,6.945l2.754,0.298C9.121,7.23,9.308,6.977,9.357,6.72 c0.236-1.151,1.2-1.706,2.284-1.706c0.584,0,1.249,0.215,1.595,0.738c0.398,0.584,0.346,1.384,0.346,2.061V8.182z M13.049,14.088 c-0.451,0.8-1.169,1.291-1.967,1.291c-1.09,0-1.728-0.83-1.728-2.061c0-2.42,2.171-2.86,4.227-2.86v0.615 C13.582,12.181,13.608,13.104,13.049,14.088z M20.683,19.339C18.329,21.076,14.917,22,11.979,22c-4.118,0-7.826-1.522-10.632-4.057 c-0.22-0.199-0.024-0.471,0.241-0.317c3.027,1.762,6.771,2.823,10.639,2.823c2.608,0,5.476-0.541,8.115-1.66 C20.739,18.62,21.072,19.051,20.683,19.339z M21.336,21.043c-0.194,0.163-0.379,0.076-0.293-0.139 c0.284-0.71,0.92-2.298,0.619-2.684c-0.301-0.386-1.99-0.183-2.749-0.092c-0.23,0.027-0.266-0.173-0.059-0.319 c1.348-0.946,3.555-0.673,3.811-0.356C22.925,17.773,22.599,19.986,21.336,21.043z"></path> </svg>', 'apple' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M20.07,17.586a10.874,10.874,0,0,1-1.075,1.933,9.822,9.822,0,0,1-1.385,1.674,2.687,2.687,0,0,1-1.78.784,4.462,4.462,0,0,1-1.644-.393,4.718,4.718,0,0,0-1.77-.391,4.878,4.878,0,0,0-1.82.391A4.9,4.9,0,0,1,9.021,22a2.53,2.53,0,0,1-1.82-.8A10.314,10.314,0,0,1,5.752,19.46,11.987,11.987,0,0,1,4.22,16.417a11.143,11.143,0,0,1-.643-3.627,6.623,6.623,0,0,1,.87-3.465A5.1,5.1,0,0,1,6.268,7.483a4.9,4.9,0,0,1,2.463-.695,5.8,5.8,0,0,1,1.9.443,6.123,6.123,0,0,0,1.511.444,9.04,9.04,0,0,0,1.675-.523,5.537,5.537,0,0,1,2.277-.4,4.835,4.835,0,0,1,3.788,1.994,4.213,4.213,0,0,0-2.235,3.827,4.222,4.222,0,0,0,1.386,3.181,4.556,4.556,0,0,0,1.385.909q-.167.483-.353.927ZM16.211,2.4a4.267,4.267,0,0,1-1.094,2.8,3.726,3.726,0,0,1-3.1,1.528A3.114,3.114,0,0,1,12,6.347a4.384,4.384,0,0,1,1.16-2.828,4.467,4.467,0,0,1,1.414-1.061A4.215,4.215,0,0,1,16.19,2a3.633,3.633,0,0,1,.021.4Z"></path> </svg>', 'bandcamp' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M15.27 17.289 3 17.289 8.73 6.711 21 6.711 15.27 17.289"></path> </svg>', 'behance' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M7.799,5.698c0.589,0,1.12,0.051,1.606,0.156c0.482,0.102,0.894,0.273,1.241,0.507c0.344,0.235,0.612,0.546,0.804,0.938 c0.188,0.387,0.281,0.871,0.281,1.443c0,0.619-0.141,1.137-0.421,1.551c-0.284,0.413-0.7,0.751-1.255,1.014 c0.756,0.218,1.317,0.601,1.689,1.146c0.374,0.549,0.557,1.205,0.557,1.975c0,0.623-0.12,1.161-0.359,1.612 c-0.241,0.457-0.569,0.828-0.973,1.114c-0.408,0.288-0.876,0.5-1.399,0.637C9.052,17.931,8.514,18,7.963,18H2V5.698H7.799 M7.449,10.668c0.481,0,0.878-0.114,1.192-0.345c0.311-0.228,0.463-0.603,0.463-1.119c0-0.286-0.051-0.523-0.152-0.707 C8.848,8.315,8.711,8.171,8.536,8.07C8.362,7.966,8.166,7.894,7.94,7.854c-0.224-0.044-0.457-0.06-0.697-0.06H4.709v2.874H7.449z M7.6,15.905c0.267,0,0.521-0.024,0.759-0.077c0.243-0.053,0.457-0.137,0.637-0.261c0.182-0.12,0.332-0.283,0.441-0.491 C9.547,14.87,9.6,14.602,9.6,14.278c0-0.633-0.18-1.084-0.533-1.357c-0.356-0.27-0.83-0.404-1.413-0.404H4.709v3.388L7.6,15.905z M16.162,15.864c0.367,0.358,0.897,0.538,1.583,0.538c0.493,0,0.92-0.125,1.277-0.374c0.354-0.248,0.571-0.514,0.654-0.79h2.155 c-0.347,1.072-0.872,1.838-1.589,2.299C19.534,18,18.67,18.23,17.662,18.23c-0.701,0-1.332-0.113-1.899-0.337 c-0.567-0.227-1.041-0.544-1.439-0.958c-0.389-0.415-0.689-0.907-0.904-1.484c-0.213-0.574-0.32-1.21-0.32-1.899 c0-0.666,0.11-1.288,0.329-1.863c0.222-0.577,0.529-1.075,0.933-1.492c0.406-0.42,0.885-0.751,1.444-0.994 c0.558-0.241,1.175-0.363,1.857-0.363c0.754,0,1.414,0.145,1.98,0.44c0.563,0.291,1.026,0.686,1.389,1.181 c0.363,0.493,0.622,1.057,0.783,1.69c0.16,0.632,0.217,1.292,0.171,1.983h-6.428C15.557,14.84,15.795,15.506,16.162,15.864 M18.973,11.184c-0.291-0.321-0.783-0.496-1.384-0.496c-0.39,0-0.714,0.066-0.973,0.2c-0.254,0.132-0.461,0.297-0.621,0.491 c-0.157,0.197-0.265,0.405-0.328,0.628c-0.063,0.217-0.101,0.413-0.111,0.587h3.98C19.478,11.969,19.265,11.509,18.973,11.184z M15.057,7.738h4.985V6.524h-4.985L15.057,7.738z"></path> </svg>', 'chain' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M19.647,16.706a1.134,1.134,0,0,0-.343-.833l-2.549-2.549a1.134,1.134,0,0,0-.833-.343,1.168,1.168,0,0,0-.883.392l.233.226q.2.189.264.264a2.922,2.922,0,0,1,.184.233.986.986,0,0,1,.159.312,1.242,1.242,0,0,1,.043.337,1.172,1.172,0,0,1-1.176,1.176,1.237,1.237,0,0,1-.337-.043,1,1,0,0,1-.312-.159,2.76,2.76,0,0,1-.233-.184q-.073-.068-.264-.264l-.226-.233a1.19,1.19,0,0,0-.4.895,1.134,1.134,0,0,0,.343.833L15.837,19.3a1.13,1.13,0,0,0,.833.331,1.18,1.18,0,0,0,.833-.318l1.8-1.789a1.12,1.12,0,0,0,.343-.821Zm-8.615-8.64a1.134,1.134,0,0,0-.343-.833L8.163,4.7a1.134,1.134,0,0,0-.833-.343,1.184,1.184,0,0,0-.833.331L4.7,6.473a1.12,1.12,0,0,0-.343.821,1.134,1.134,0,0,0,.343.833l2.549,2.549a1.13,1.13,0,0,0,.833.331,1.184,1.184,0,0,0,.883-.38L8.728,10.4q-.2-.189-.264-.264A2.922,2.922,0,0,1,8.28,9.9a.986.986,0,0,1-.159-.312,1.242,1.242,0,0,1-.043-.337A1.172,1.172,0,0,1,9.254,8.079a1.237,1.237,0,0,1,.337.043,1,1,0,0,1,.312.159,2.761,2.761,0,0,1,.233.184q.073.068.264.264l.226.233a1.19,1.19,0,0,0,.4-.895ZM22,16.706a3.343,3.343,0,0,1-1.042,2.488l-1.8,1.789a3.536,3.536,0,0,1-4.988-.025l-2.525-2.537a3.384,3.384,0,0,1-1.017-2.488,3.448,3.448,0,0,1,1.078-2.561l-1.078-1.078a3.434,3.434,0,0,1-2.549,1.078,3.4,3.4,0,0,1-2.5-1.029L3.029,9.794A3.4,3.4,0,0,1,2,7.294,3.343,3.343,0,0,1,3.042,4.806l1.8-1.789A3.384,3.384,0,0,1,7.331,2a3.357,3.357,0,0,1,2.5,1.042l2.525,2.537a3.384,3.384,0,0,1,1.017,2.488,3.448,3.448,0,0,1-1.078,2.561l1.078,1.078a3.551,3.551,0,0,1,5.049-.049l2.549,2.549A3.4,3.4,0,0,1,22,16.706Z"></path> </svg>', 'codepen' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M22.016,8.84c-0.002-0.013-0.005-0.025-0.007-0.037c-0.005-0.025-0.008-0.048-0.015-0.072 c-0.003-0.015-0.01-0.028-0.013-0.042c-0.008-0.02-0.015-0.04-0.023-0.062c-0.007-0.015-0.013-0.028-0.02-0.042 c-0.008-0.02-0.018-0.037-0.03-0.057c-0.007-0.013-0.017-0.027-0.025-0.038c-0.012-0.018-0.023-0.035-0.035-0.052 c-0.01-0.013-0.02-0.025-0.03-0.037c-0.015-0.017-0.028-0.032-0.043-0.045c-0.01-0.012-0.022-0.023-0.035-0.035 c-0.015-0.015-0.032-0.028-0.048-0.04c-0.012-0.01-0.025-0.02-0.037-0.03c-0.005-0.003-0.01-0.008-0.015-0.012l-9.161-6.096 c-0.289-0.192-0.666-0.192-0.955,0L2.359,8.237C2.354,8.24,2.349,8.245,2.344,8.249L2.306,8.277 c-0.017,0.013-0.033,0.027-0.048,0.04C2.246,8.331,2.234,8.342,2.222,8.352c-0.015,0.015-0.028,0.03-0.042,0.047 c-0.012,0.013-0.022,0.023-0.03,0.037C2.139,8.453,2.125,8.471,2.115,8.488C2.107,8.501,2.099,8.514,2.09,8.526 C2.079,8.548,2.069,8.565,2.06,8.585C2.054,8.6,2.047,8.613,2.04,8.626C2.032,8.648,2.025,8.67,2.019,8.69 c-0.005,0.013-0.01,0.027-0.013,0.042C1.999,8.755,1.995,8.778,1.99,8.803C1.989,8.817,1.985,8.828,1.984,8.84 C1.978,8.879,1.975,8.915,1.975,8.954v6.093c0,0.037,0.003,0.075,0.008,0.112c0.002,0.012,0.005,0.025,0.007,0.038 c0.005,0.023,0.008,0.047,0.015,0.072c0.003,0.015,0.008,0.028,0.013,0.04c0.007,0.022,0.013,0.042,0.022,0.063 c0.007,0.015,0.013,0.028,0.02,0.04c0.008,0.02,0.018,0.038,0.03,0.058c0.007,0.013,0.015,0.027,0.025,0.038 c0.012,0.018,0.023,0.035,0.035,0.052c0.01,0.013,0.02,0.025,0.03,0.037c0.013,0.015,0.028,0.032,0.042,0.045 c0.012,0.012,0.023,0.023,0.035,0.035c0.015,0.013,0.032,0.028,0.048,0.04l0.038,0.03c0.005,0.003,0.01,0.007,0.013,0.01 l9.163,6.095C11.668,21.953,11.833,22,12,22c0.167,0,0.332-0.047,0.478-0.144l9.163-6.095l0.015-0.01 c0.013-0.01,0.027-0.02,0.037-0.03c0.018-0.013,0.035-0.028,0.048-0.04c0.013-0.012,0.025-0.023,0.035-0.035 c0.017-0.015,0.03-0.032,0.043-0.045c0.01-0.013,0.02-0.025,0.03-0.037c0.013-0.018,0.025-0.035,0.035-0.052 c0.008-0.013,0.018-0.027,0.025-0.038c0.012-0.02,0.022-0.038,0.03-0.058c0.007-0.013,0.013-0.027,0.02-0.04 c0.008-0.022,0.015-0.042,0.023-0.063c0.003-0.013,0.01-0.027,0.013-0.04c0.007-0.025,0.01-0.048,0.015-0.072 c0.002-0.013,0.005-0.027,0.007-0.037c0.003-0.042,0.007-0.079,0.007-0.117V8.954C22.025,8.915,22.022,8.879,22.016,8.84z M12.862,4.464l6.751,4.49l-3.016,2.013l-3.735-2.492V4.464z M11.138,4.464v4.009l-3.735,2.494L4.389,8.954L11.138,4.464z M3.699,10.562L5.853,12l-2.155,1.438V10.562z M11.138,19.536l-6.749-4.491l3.015-2.011l3.735,2.492V19.536z M12,14.035L8.953,12 L12,9.966L15.047,12L12,14.035z M12.862,19.536v-4.009l3.735-2.492l3.016,2.011L12.862,19.536z M20.303,13.438L18.147,12 l2.156-1.438L20.303,13.438z"></path> </svg>', 'deviantart' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M 18.19 5.636 18.19 2 18.188 2 14.553 2 14.19 2.366 12.474 5.636 11.935 6 5.81 6 5.81 10.994 9.177 10.994 9.477 11.357 5.81 18.363 5.81 22 5.811 22 9.447 22 9.81 21.634 11.526 18.364 12.065 18 18.19 18 18.19 13.006 14.823 13.006 14.523 12.641 18.19 5.636z"></path> </svg>', 'digg' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M4.5,5.4h2.2V16H1V8.5h3.5V5.4L4.5,5.4z M4.5,14.2v-4H3.2v4H4.5z M7.6,8.5V16h2.2V8.5C9.8,8.5,7.6,8.5,7.6,8.5z M7.6,5.4 v2.2h2.2V5.4C9.8,5.4,7.6,5.4,7.6,5.4z M10.7,8.5h5.7v10.1h-5.7v-1.8h3.5V16h-3.5C10.7,16,10.7,8.5,10.7,8.5z M14.2,14.2v-4h-1.3v4 H14.2z M17.3,8.5H23v10.1h-5.7v-1.8h3.5V16h-3.5C17.3,16,17.3,8.5,17.3,8.5z M20.8,14.2v-4h-1.3v4H20.8z"></path> </svg>', 'dribbble' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M12,22C6.486,22,2,17.514,2,12S6.486,2,12,2c5.514,0,10,4.486,10,10S17.514,22,12,22z M20.434,13.369 c-0.292-0.092-2.644-0.794-5.32-0.365c1.117,3.07,1.572,5.57,1.659,6.09C18.689,17.798,20.053,15.745,20.434,13.369z M15.336,19.876c-0.127-0.749-0.623-3.361-1.822-6.477c-0.019,0.006-0.038,0.013-0.056,0.019c-4.818,1.679-6.547,5.02-6.701,5.334 c1.448,1.129,3.268,1.803,5.243,1.803C13.183,20.555,14.311,20.313,15.336,19.876z M5.654,17.724 c0.193-0.331,2.538-4.213,6.943-5.637c0.111-0.036,0.224-0.07,0.337-0.102c-0.214-0.485-0.448-0.971-0.692-1.45 c-4.266,1.277-8.405,1.223-8.778,1.216c-0.003,0.087-0.004,0.174-0.004,0.261C3.458,14.207,4.29,16.21,5.654,17.724z M3.639,10.264 c0.382,0.005,3.901,0.02,7.897-1.041c-1.415-2.516-2.942-4.631-3.167-4.94C5.979,5.41,4.193,7.613,3.639,10.264z M9.998,3.709 c0.236,0.316,1.787,2.429,3.187,5c3.037-1.138,4.323-2.867,4.477-3.085C16.154,4.286,14.17,3.471,12,3.471 C11.311,3.471,10.641,3.554,9.998,3.709z M18.612,6.612C18.432,6.855,17,8.69,13.842,9.979c0.199,0.407,0.389,0.821,0.567,1.237 c0.063,0.148,0.124,0.295,0.184,0.441c2.842-0.357,5.666,0.215,5.948,0.275C20.522,9.916,19.801,8.065,18.612,6.612z"></path> </svg>', 'dropbox' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M12,6.134L6.069,9.797L2,6.54l5.883-3.843L12,6.134z M2,13.054l5.883,3.843L12,13.459L6.069,9.797L2,13.054z M12,13.459 l4.116,3.439L22,13.054l-4.069-3.257L12,13.459z M22,6.54l-5.884-3.843L12,6.134l5.931,3.663L22,6.54z M12.011,14.2l-4.129,3.426 l-1.767-1.153v1.291l5.896,3.539l5.897-3.539v-1.291l-1.769,1.153L12.011,14.2z"></path> </svg>', 'etsy' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M9.16033,4.038c0-.27174.02717-.43478.48913-.43478h6.22283c1.087,0,1.68478.92391,2.11957,2.663l.35326,1.38587h1.05978C19.59511,3.712,19.75815,2,19.75815,2s-2.663.29891-4.23913.29891h-7.962L3.29076,2.163v1.1413L4.731,3.57609c1.00543.19022,1.25.40761,1.33152,1.33152,0,0,.08152,2.71739.08152,7.20109s-.08152,7.17391-.08152,7.17391c0,.81522-.32609,1.11413-1.33152,1.30435l-1.44022.27174V22l4.2663-.13587h7.11957c1.60326,0,5.32609.13587,5.32609.13587.08152-.97826.625-5.40761.70652-5.89674H19.7038L18.644,18.52174c-.84239,1.90217-2.06522,2.038-3.42391,2.038H11.1712c-1.3587,0-2.01087-.54348-2.01087-1.712V12.65217s3.0163,0,3.99457.08152c.76087.05435,1.22283.27174,1.46739,1.33152l.32609,1.413h1.16848l-.08152-3.55978.163-3.587H15.02989l-.38043,1.57609c-.24457,1.03261-.40761,1.22283-1.46739,1.33152-1.38587.13587-4.02174.1087-4.02174.1087Z"></path> </svg>', 'facebook' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M20.007,3H3.993C3.445,3,3,3.445,3,3.993v16.013C3,20.555,3.445,21,3.993,21h8.621v-6.971h-2.346v-2.717h2.346V9.31 c0-2.325,1.42-3.591,3.494-3.591c0.993,0,1.847,0.074,2.096,0.107v2.43l-1.438,0.001c-1.128,0-1.346,0.536-1.346,1.323v1.734h2.69 l-0.35,2.717h-2.34V21h4.587C20.555,21,21,20.555,21,20.007V3.993C21,3.445,20.555,3,20.007,3z"></path> </svg>', 'feed' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M2,8.667V12c5.515,0,10,4.485,10,10h3.333C15.333,14.637,9.363,8.667,2,8.667z M2,2v3.333 c9.19,0,16.667,7.477,16.667,16.667H22C22,10.955,13.045,2,2,2z M4.5,17C3.118,17,2,18.12,2,19.5S3.118,22,4.5,22S7,20.88,7,19.5 S5.882,17,4.5,17z"></path> </svg>', 'flickr' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M6.5,7c-2.75,0-5,2.25-5,5s2.25,5,5,5s5-2.25,5-5S9.25,7,6.5,7z M17.5,7c-2.75,0-5,2.25-5,5s2.25,5,5,5s5-2.25,5-5 S20.25,7,17.5,7z"></path> </svg>', 'foursquare' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M17.573,2c0,0-9.197,0-10.668,0S5,3.107,5,3.805s0,16.948,0,16.948c0,0.785,0.422,1.077,0.66,1.172 c0.238,0.097,0.892,0.177,1.285-0.275c0,0,5.035-5.843,5.122-5.93c0.132-0.132,0.132-0.132,0.262-0.132h3.26 c1.368,0,1.588-0.977,1.732-1.552c0.078-0.318,0.692-3.428,1.225-6.122l0.675-3.368C19.56,2.893,19.14,2,17.573,2z M16.495,7.22 c-0.053,0.252-0.372,0.518-0.665,0.518c-0.293,0-4.157,0-4.157,0c-0.467,0-0.802,0.318-0.802,0.787v0.508 c0,0.467,0.337,0.798,0.805,0.798c0,0,3.197,0,3.528,0s0.655,0.362,0.583,0.715c-0.072,0.353-0.407,2.102-0.448,2.295 c-0.04,0.193-0.262,0.523-0.655,0.523c-0.33,0-2.88,0-2.88,0c-0.523,0-0.683,0.068-1.033,0.503 c-0.35,0.437-3.505,4.223-3.505,4.223c-0.032,0.035-0.063,0.027-0.063-0.015V4.852c0-0.298,0.26-0.648,0.648-0.648 c0,0,8.228,0,8.562,0c0.315,0,0.61,0.297,0.528,0.683L16.495,7.22z"></path> </svg>', 'goodreads' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M17.3,17.5c-0.2,0.8-0.5,1.4-1,1.9c-0.4,0.5-1,0.9-1.7,1.2C13.9,20.9,13.1,21,12,21c-0.6,0-1.3-0.1-1.9-0.2 c-0.6-0.1-1.1-0.4-1.6-0.7c-0.5-0.3-0.9-0.7-1.2-1.2c-0.3-0.5-0.5-1.1-0.5-1.7h1.5c0.1,0.5,0.2,0.9,0.5,1.2 c0.2,0.3,0.5,0.6,0.9,0.8c0.3,0.2,0.7,0.3,1.1,0.4c0.4,0.1,0.8,0.1,1.2,0.1c1.4,0,2.5-0.4,3.1-1.2c0.6-0.8,1-2,1-3.5v-1.7h0 c-0.4,0.8-0.9,1.4-1.6,1.9c-0.7,0.5-1.5,0.7-2.4,0.7c-1,0-1.9-0.2-2.6-0.5C8.7,15,8.1,14.5,7.7,14c-0.5-0.6-0.8-1.3-1-2.1 c-0.2-0.8-0.3-1.6-0.3-2.5c0-0.9,0.1-1.7,0.4-2.5c0.3-0.8,0.6-1.5,1.1-2c0.5-0.6,1.1-1,1.8-1.4C10.3,3.2,11.1,3,12,3 c0.5,0,0.9,0.1,1.3,0.2c0.4,0.1,0.8,0.3,1.1,0.5c0.3,0.2,0.6,0.5,0.9,0.8c0.3,0.3,0.5,0.6,0.6,1h0V3.4h1.5V15 C17.6,15.9,17.5,16.7,17.3,17.5z M13.8,14.1c0.5-0.3,0.9-0.7,1.3-1.1c0.3-0.5,0.6-1,0.8-1.6c0.2-0.6,0.3-1.2,0.3-1.9 c0-0.6-0.1-1.2-0.2-1.9c-0.1-0.6-0.4-1.2-0.7-1.7c-0.3-0.5-0.7-0.9-1.3-1.2c-0.5-0.3-1.1-0.5-1.9-0.5s-1.4,0.2-1.9,0.5 c-0.5,0.3-1,0.7-1.3,1.2C8.5,6.4,8.3,7,8.1,7.6C8,8.2,7.9,8.9,7.9,9.5c0,0.6,0.1,1.3,0.2,1.9C8.3,12,8.6,12.5,8.9,13 c0.3,0.5,0.8,0.8,1.3,1.1c0.5,0.3,1.1,0.4,1.9,0.4C12.7,14.5,13.3,14.4,13.8,14.1z"></path> </svg>', 'google-plus' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M8,11h6.61c0.06,0.35,0.11,0.7,0.11,1.16c0,4-2.68,6.84-6.72,6.84c-3.87,0-7-3.13-7-7s3.13-7,7-7 c1.89,0,3.47,0.69,4.69,1.83l-1.9,1.83C10.27,8.16,9.36,7.58,8,7.58c-2.39,0-4.34,1.98-4.34,4.42S5.61,16.42,8,16.42 c2.77,0,3.81-1.99,3.97-3.02H8V11L8,11z M23,11h-2V9h-2v2h-2v2h2v2h2v-2h2"></path> </svg>', 'google' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M12.02,10.18v3.72v0.01h5.51c-0.26,1.57-1.67,4.22-5.5,4.22c-3.31,0-6.01-2.75-6.01-6.12s2.7-6.12,6.01-6.12 c1.87,0,3.13,0.8,3.85,1.48l2.84-2.76C16.99,2.99,14.73,2,12.03,2c-5.52,0-10,4.48-10,10s4.48,10,10,10c5.77,0,9.6-4.06,9.6-9.77 c0-0.83-0.11-1.42-0.25-2.05H12.02z"></path> </svg>', 'github' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path> </svg>', 'instagram' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M12,4.622c2.403,0,2.688,0.009,3.637,0.052c0.877,0.04,1.354,0.187,1.671,0.31c0.42,0.163,0.72,0.358,1.035,0.673 c0.315,0.315,0.51,0.615,0.673,1.035c0.123,0.317,0.27,0.794,0.31,1.671c0.043,0.949,0.052,1.234,0.052,3.637 s-0.009,2.688-0.052,3.637c-0.04,0.877-0.187,1.354-0.31,1.671c-0.163,0.42-0.358,0.72-0.673,1.035 c-0.315,0.315-0.615,0.51-1.035,0.673c-0.317,0.123-0.794,0.27-1.671,0.31c-0.949,0.043-1.233,0.052-3.637,0.052 s-2.688-0.009-3.637-0.052c-0.877-0.04-1.354-0.187-1.671-0.31c-0.42-0.163-0.72-0.358-1.035-0.673 c-0.315-0.315-0.51-0.615-0.673-1.035c-0.123-0.317-0.27-0.794-0.31-1.671C4.631,14.688,4.622,14.403,4.622,12 s0.009-2.688,0.052-3.637c0.04-0.877,0.187-1.354,0.31-1.671c0.163-0.42,0.358-0.72,0.673-1.035 c0.315-0.315,0.615-0.51,1.035-0.673c0.317-0.123,0.794-0.27,1.671-0.31C9.312,4.631,9.597,4.622,12,4.622 M12,3 C9.556,3,9.249,3.01,8.289,3.054C7.331,3.098,6.677,3.25,6.105,3.472C5.513,3.702,5.011,4.01,4.511,4.511 c-0.5,0.5-0.808,1.002-1.038,1.594C3.25,6.677,3.098,7.331,3.054,8.289C3.01,9.249,3,9.556,3,12c0,2.444,0.01,2.751,0.054,3.711 c0.044,0.958,0.196,1.612,0.418,2.185c0.23,0.592,0.538,1.094,1.038,1.594c0.5,0.5,1.002,0.808,1.594,1.038 c0.572,0.222,1.227,0.375,2.185,0.418C9.249,20.99,9.556,21,12,21s2.751-0.01,3.711-0.054c0.958-0.044,1.612-0.196,2.185-0.418 c0.592-0.23,1.094-0.538,1.594-1.038c0.5-0.5,0.808-1.002,1.038-1.594c0.222-0.572,0.375-1.227,0.418-2.185 C20.99,14.751,21,14.444,21,12s-0.01-2.751-0.054-3.711c-0.044-0.958-0.196-1.612-0.418-2.185c-0.23-0.592-0.538-1.094-1.038-1.594 c-0.5-0.5-1.002-0.808-1.594-1.038c-0.572-0.222-1.227-0.375-2.185-0.418C14.751,3.01,14.444,3,12,3L12,3z M12,7.378 c-2.552,0-4.622,2.069-4.622,4.622S9.448,16.622,12,16.622s4.622-2.069,4.622-4.622S14.552,7.378,12,7.378z M12,15 c-1.657,0-3-1.343-3-3s1.343-3,3-3s3,1.343,3,3S13.657,15,12,15z M16.804,6.116c-0.596,0-1.08,0.484-1.08,1.08 s0.484,1.08,1.08,1.08c0.596,0,1.08-0.484,1.08-1.08S17.401,6.116,16.804,6.116z"></path> </svg>', 'lastfm' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M10.5002,0 C4.7006,0 0,4.70109753 0,10.4998496 C0,16.2989526 4.7006,21 10.5002,21 C16.299,21 21,16.2989526 21,10.4998496 C21,4.70109753 16.299,0 10.5002,0 Z M14.69735,14.7204413 C13.3164,14.7151781 12.4346,14.0870017 11.83445,12.6859357 L11.6816001,12.3451305 L10.35405,9.31011397 C9.92709997,8.26875064 8.85260001,7.57120012 7.68010001,7.57120012 C6.06945001,7.57120012 4.75925001,8.88509738 4.75925001,10.5009524 C4.75925001,12.1164565 6.06945001,13.4303036 7.68010001,13.4303036 C8.77200001,13.4303036 9.76514999,12.827541 10.2719501,11.8567047 C10.2893,11.8235214 10.3239,11.8019673 10.36305,11.8038219 C10.4007,11.8053759 10.43535,11.8287847 10.4504,11.8631709 L10.98655,13.1045863 C11.0016,13.1389726 10.9956,13.17782 10.97225,13.2068931 C10.1605001,14.1995341 8.96020001,14.7683115 7.68010001,14.7683115 C5.33305,14.7683115 3.42340001,12.8535563 3.42340001,10.5009524 C3.42340001,8.14679459 5.33300001,6.23203946 7.68010001,6.23203946 C9.45720002,6.23203946 10.8909,7.19074535 11.6138,8.86359341 C11.6205501,8.88018505 12.3412,10.5707777 12.97445,12.0190621 C13.34865,12.8739575 13.64615,13.3959676 14.6288,13.4291508 C15.5663001,13.4612814 16.25375,12.9121534 16.25375,12.1484869 C16.25375,11.4691321 15.8320501,11.3003585 14.8803,10.98216 C13.2365,10.4397989 12.34495,9.88605929 12.34495,8.51817658 C12.34495,7.1809207 13.26665,6.31615054 14.692,6.31615054 C15.62875,6.31615054 16.3155,6.7286858 16.79215,7.5768142 C16.80495,7.60062396 16.8079001,7.62814302 16.8004001,7.65420843 C16.7929,7.68027384 16.7748,7.70212868 16.7507001,7.713808 L15.86145,8.16900031 C15.8178001,8.19200805 15.7643,8.17807308 15.73565,8.13847371 C15.43295,7.71345711 15.0956,7.52513451 14.6423,7.52513451 C14.05125,7.52513451 13.6220001,7.92899802 13.6220001,8.48649708 C13.6220001,9.17382194 14.1529001,9.34144259 15.0339,9.61923972 C15.14915,9.65578139 15.26955,9.69397731 15.39385,9.73432853 C16.7763,10.1865133 17.57675,10.7311301 17.57675,12.1836251 C17.57685,13.629654 16.3389,14.7204413 14.69735,14.7204413 Z"></path> </svg>', 'linkedin' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path> </svg>', 'mail' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M20,4H4C2.895,4,2,4.895,2,6v12c0,1.105,0.895,2,2,2h16c1.105,0,2-0.895,2-2V6C22,4.895,21.105,4,20,4z M20,8.236l-8,4.882 L4,8.236V6h16V8.236z"></path> </svg>', 'meetup' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M19.24775,14.722a3.57032,3.57032,0,0,1-2.94457,3.52073,3.61886,3.61886,0,0,1-.64652.05634c-.07314-.0008-.10187.02846-.12507.09547A2.38881,2.38881,0,0,1,13.49453,20.094a2.33092,2.33092,0,0,1-1.827-.50716.13635.13635,0,0,0-.19878-.00408,3.191,3.191,0,0,1-2.104.60248,3.26309,3.26309,0,0,1-3.00324-2.71993,2.19076,2.19076,0,0,1-.03512-.30865c-.00156-.08579-.03413-.1189-.11608-.13493a2.86421,2.86421,0,0,1-1.23189-.56111,2.945,2.945,0,0,1-1.166-2.05749,2.97484,2.97484,0,0,1,.87524-2.50774.112.112,0,0,0,.02091-.16107,2.7213,2.7213,0,0,1-.36648-1.48A2.81256,2.81256,0,0,1,6.57673,7.58838a.35764.35764,0,0,0,.28869-.22819,4.2208,4.2208,0,0,1,6.02892-1.90111.25161.25161,0,0,0,.22023.0243,3.65608,3.65608,0,0,1,3.76031.90678A3.57244,3.57244,0,0,1,17.95918,8.626a2.97339,2.97339,0,0,1,.01829.57356.10637.10637,0,0,0,.0853.12792,1.97669,1.97669,0,0,1,1.27939,1.33733,2.00266,2.00266,0,0,1-.57112,2.12652c-.05284.05166-.04168.08328-.01173.13489A3.51189,3.51189,0,0,1,19.24775,14.722Zm-6.35959-.27836a1.6984,1.6984,0,0,0,1.14556,1.61113,3.82039,3.82039,0,0,0,1.036.17935,1.46888,1.46888,0,0,0,.73509-.12255.44082.44082,0,0,0,.26057-.44274.45312.45312,0,0,0-.29211-.43375.97191.97191,0,0,0-.20678-.063c-.21326-.03806-.42754-.0701-.63973-.11215a.54787.54787,0,0,1-.50172-.60926,2.75864,2.75864,0,0,1,.1773-.901c.1763-.535.414-1.045.64183-1.55913A12.686,12.686,0,0,0,15.85,10.47863a1.58461,1.58461,0,0,0,.04861-.87208,1.04531,1.04531,0,0,0-.85432-.83981,1.60658,1.60658,0,0,0-1.23654.16594.27593.27593,0,0,1-.36286-.03413c-.085-.0747-.16594-.15379-.24918-.23055a.98682.98682,0,0,0-1.33577-.04933,6.1468,6.1468,0,0,1-.4989.41615.47762.47762,0,0,1-.51535.03566c-.17448-.09307-.35512-.175-.53531-.25665a1.74949,1.74949,0,0,0-.56476-.2016,1.69943,1.69943,0,0,0-1.61654.91787,8.05815,8.05815,0,0,0-.32952.80126c-.45471,1.2557-.82507,2.53825-1.20838,3.81639a1.24151,1.24151,0,0,0,.51532,1.44389,1.42659,1.42659,0,0,0,1.22008.17166,1.09728,1.09728,0,0,0,.66994-.69764c.44145-1.04111.839-2.09989,1.25981-3.14926.11581-.28876.22792-.57874.35078-.86438a.44548.44548,0,0,1,.69189-.19539.50521.50521,0,0,1,.15044.43836,1.75625,1.75625,0,0,1-.14731.50453c-.27379.69219-.55265,1.38236-.82766,2.074a2.0836,2.0836,0,0,0-.14038.42876.50719.50719,0,0,0,.27082.57722.87236.87236,0,0,0,.66145.02739.99137.99137,0,0,0,.53406-.532q.61571-1.20914,1.228-2.42031.28423-.55863.57585-1.1133a.87189.87189,0,0,1,.29055-.35253.34987.34987,0,0,1,.37634-.01265.30291.30291,0,0,1,.12434.31459.56716.56716,0,0,1-.04655.1915c-.05318.12739-.10286.25669-.16183.38156-.34118.71775-.68754,1.43273-1.02568,2.152A2.00213,2.00213,0,0,0,12.88816,14.44366Zm4.78568,5.28972a.88573.88573,0,0,0-1.77139.00465.8857.8857,0,0,0,1.77139-.00465Zm-14.83838-7.296a.84329.84329,0,1,0,.00827-1.68655.8433.8433,0,0,0-.00827,1.68655Zm10.366-9.43673a.83506.83506,0,1,0-.0091,1.67.83505.83505,0,0,0,.0091-1.67Zm6.85014,5.22a.71651.71651,0,0,0-1.433.0093.71656.71656,0,0,0,1.433-.0093ZM5.37528,6.17908A.63823.63823,0,1,0,6.015,5.54483.62292.62292,0,0,0,5.37528,6.17908Zm6.68214,14.80843a.54949.54949,0,1,0-.55052.541A.54556.54556,0,0,0,12.05742,20.98752Zm8.53235-8.49689a.54777.54777,0,0,0-.54027.54023.53327.53327,0,0,0,.532.52293.51548.51548,0,0,0,.53272-.5237A.53187.53187,0,0,0,20.58977,12.49063ZM7.82846,2.4715a.44927.44927,0,1,0,.44484.44766A.43821.43821,0,0,0,7.82846,2.4715Zm13.775,7.60492a.41186.41186,0,0,0-.40065.39623.40178.40178,0,0,0,.40168.40168A.38994.38994,0,0,0,22,10.48172.39946.39946,0,0,0,21.60349,10.07642ZM5.79193,17.96207a.40469.40469,0,0,0-.397-.39646.399.399,0,0,0-.396.405.39234.39234,0,0,0,.39939.389A.39857.39857,0,0,0,5.79193,17.96207Z"></path> </svg>', 'medium' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M20.962,7.257l-5.457,8.867l-3.923-6.375l3.126-5.08c0.112-0.182,0.319-0.286,0.527-0.286c0.05,0,0.1,0.008,0.149,0.02 c0.039,0.01,0.078,0.023,0.114,0.041l5.43,2.715l0.006,0.003c0.004,0.002,0.007,0.006,0.011,0.008 C20.971,7.191,20.98,7.227,20.962,7.257z M9.86,8.592v5.783l5.14,2.57L9.86,8.592z M15.772,17.331l4.231,2.115 C20.554,19.721,21,19.529,21,19.016V8.835L15.772,17.331z M8.968,7.178L3.665,4.527C3.569,4.479,3.478,4.456,3.395,4.456 C3.163,4.456,3,4.636,3,4.938v11.45c0,0.306,0.224,0.669,0.498,0.806l4.671,2.335c0.12,0.06,0.234,0.088,0.337,0.088 c0.29,0,0.494-0.225,0.494-0.602V7.231C9,7.208,8.988,7.188,8.968,7.178z"></path> </svg>', 'pinterest' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M12.289,2C6.617,2,3.606,5.648,3.606,9.622c0,1.846,1.025,4.146,2.666,4.878c0.25,0.111,0.381,0.063,0.439-0.169 c0.044-0.175,0.267-1.029,0.365-1.428c0.032-0.128,0.017-0.237-0.091-0.362C6.445,11.911,6.01,10.75,6.01,9.668 c0-2.777,2.194-5.464,5.933-5.464c3.23,0,5.49,2.108,5.49,5.122c0,3.407-1.794,5.768-4.13,5.768c-1.291,0-2.257-1.021-1.948-2.277 c0.372-1.495,1.089-3.112,1.089-4.191c0-0.967-0.542-1.775-1.663-1.775c-1.319,0-2.379,1.309-2.379,3.059 c0,1.115,0.394,1.869,0.394,1.869s-1.302,5.279-1.54,6.261c-0.405,1.666,0.053,4.368,0.094,4.604 c0.021,0.126,0.167,0.169,0.25,0.063c0.129-0.165,1.699-2.419,2.142-4.051c0.158-0.59,0.817-2.995,0.817-2.995 c0.43,0.784,1.681,1.446,3.013,1.446c3.963,0,6.822-3.494,6.822-7.833C20.394,5.112,16.849,2,12.289,2"></path> </svg>', 'pocket' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M21.927,4.194C21.667,3.48,20.982,3,20.222,3h-0.01h-1.721H3.839C3.092,3,2.411,3.47,2.145,4.17 C2.066,4.378,2.026,4.594,2.026,4.814v6.035l0.069,1.2c0.29,2.73,1.707,5.115,3.899,6.778c0.039,0.03,0.079,0.059,0.119,0.089 l0.025,0.018c1.175,0.859,2.491,1.441,3.91,1.727c0.655,0.132,1.325,0.2,1.991,0.2c0.615,0,1.232-0.057,1.839-0.17 c0.073-0.014,0.145-0.028,0.219-0.044c0.02-0.004,0.042-0.012,0.064-0.023c1.359-0.297,2.621-0.864,3.753-1.691l0.025-0.018 c0.04-0.029,0.08-0.058,0.119-0.089c2.192-1.664,3.609-4.049,3.898-6.778l0.069-1.2V4.814C22.026,4.605,22,4.398,21.927,4.194z M17.692,10.481l-4.704,4.512c-0.266,0.254-0.608,0.382-0.949,0.382c-0.342,0-0.684-0.128-0.949-0.382l-4.705-4.512 C5.838,9.957,5.82,9.089,6.344,8.542c0.524-0.547,1.392-0.565,1.939-0.04l3.756,3.601l3.755-3.601 c0.547-0.524,1.415-0.506,1.939,0.04C18.256,9.089,18.238,9.956,17.692,10.481z"></path> </svg>', 'reddit' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M22,11.816c0-1.256-1.021-2.277-2.277-2.277c-0.593,0-1.122,0.24-1.526,0.614c-1.481-0.965-3.455-1.594-5.647-1.69 l1.171-3.702l3.18,0.748c0.008,1.028,0.846,1.862,1.876,1.862c1.035,0,1.877-0.842,1.877-1.878c0-1.035-0.842-1.877-1.877-1.877 c-0.769,0-1.431,0.466-1.72,1.13l-3.508-0.826c-0.203-0.047-0.399,0.067-0.46,0.261l-1.35,4.268 c-2.316,0.038-4.411,0.67-5.97,1.671C5.368,9.765,4.853,9.539,4.277,9.539C3.021,9.539,2,10.56,2,11.816 c0,0.814,0.433,1.523,1.078,1.925c-0.037,0.221-0.061,0.444-0.061,0.672c0,3.292,4.011,5.97,8.941,5.97s8.941-2.678,8.941-5.97 c0-0.214-0.02-0.424-0.053-0.632C21.533,13.39,22,12.661,22,11.816z M18.776,4.394c0.606,0,1.1,0.493,1.1,1.1s-0.493,1.1-1.1,1.1 s-1.1-0.494-1.1-1.1S18.169,4.394,18.776,4.394z M2.777,11.816c0-0.827,0.672-1.5,1.499-1.5c0.313,0,0.598,0.103,0.838,0.269 c-0.851,0.676-1.477,1.479-1.812,2.36C2.983,12.672,2.777,12.27,2.777,11.816z M11.959,19.606c-4.501,0-8.164-2.329-8.164-5.193 S7.457,9.22,11.959,9.22s8.164,2.329,8.164,5.193S16.46,19.606,11.959,19.606z M20.636,13.001c-0.326-0.89-0.948-1.701-1.797-2.384 c0.248-0.186,0.55-0.301,0.883-0.301c0.827,0,1.5,0.673,1.5,1.5C21.223,12.299,20.992,12.727,20.636,13.001z M8.996,14.704 c-0.76,0-1.397-0.616-1.397-1.376c0-0.76,0.637-1.397,1.397-1.397c0.76,0,1.376,0.637,1.376,1.397 C10.372,14.088,9.756,14.704,8.996,14.704z M16.401,13.328c0,0.76-0.616,1.376-1.376,1.376c-0.76,0-1.399-0.616-1.399-1.376 c0-0.76,0.639-1.397,1.399-1.397C15.785,11.931,16.401,12.568,16.401,13.328z M15.229,16.708c0.152,0.152,0.152,0.398,0,0.55 c-0.674,0.674-1.727,1.002-3.219,1.002c-0.004,0-0.007-0.002-0.011-0.002c-0.004,0-0.007,0.002-0.011,0.002 c-1.492,0-2.544-0.328-3.218-1.002c-0.152-0.152-0.152-0.398,0-0.55c0.152-0.152,0.399-0.151,0.55,0 c0.521,0.521,1.394,0.775,2.669,0.775c0.004,0,0.007,0.002,0.011,0.002c0.004,0,0.007-0.002,0.011-0.002 c1.275,0,2.148-0.253,2.669-0.775C14.831,16.556,15.078,16.556,15.229,16.708z"></path> </svg>', 'skype' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M10.113,2.699c0.033-0.006,0.067-0.013,0.1-0.02c0.033,0.017,0.066,0.033,0.098,0.051L10.113,2.699z M2.72,10.223 c-0.006,0.034-0.011,0.069-0.017,0.103c0.018,0.032,0.033,0.064,0.051,0.095L2.72,10.223z M21.275,13.771 c0.007-0.035,0.011-0.071,0.018-0.106c-0.018-0.031-0.033-0.064-0.052-0.095L21.275,13.771z M13.563,21.199 c0.032,0.019,0.065,0.035,0.096,0.053c0.036-0.006,0.071-0.011,0.105-0.017L13.563,21.199z M22,16.386 c0,1.494-0.581,2.898-1.637,3.953c-1.056,1.057-2.459,1.637-3.953,1.637c-0.967,0-1.914-0.251-2.75-0.725 c0.036-0.006,0.071-0.011,0.105-0.017l-0.202-0.035c0.032,0.019,0.065,0.035,0.096,0.053c-0.543,0.096-1.099,0.147-1.654,0.147 c-1.275,0-2.512-0.25-3.676-0.743c-1.125-0.474-2.135-1.156-3.002-2.023c-0.867-0.867-1.548-1.877-2.023-3.002 c-0.493-1.164-0.743-2.401-0.743-3.676c0-0.546,0.049-1.093,0.142-1.628c0.018,0.032,0.033,0.064,0.051,0.095L2.72,10.223 c-0.006,0.034-0.011,0.069-0.017,0.103C2.244,9.5,2,8.566,2,7.615c0-1.493,0.582-2.898,1.637-3.953 c1.056-1.056,2.46-1.638,3.953-1.638c0.915,0,1.818,0.228,2.622,0.655c-0.033,0.007-0.067,0.013-0.1,0.02l0.199,0.031 c-0.032-0.018-0.066-0.034-0.098-0.051c0.002,0,0.003-0.001,0.004-0.001c0.586-0.112,1.187-0.169,1.788-0.169 c1.275,0,2.512,0.249,3.676,0.742c1.124,0.476,2.135,1.156,3.002,2.024c0.868,0.867,1.548,1.877,2.024,3.002 c0.493,1.164,0.743,2.401,0.743,3.676c0,0.575-0.054,1.15-0.157,1.712c-0.018-0.031-0.033-0.064-0.052-0.095l0.034,0.201 c0.007-0.035,0.011-0.071,0.018-0.106C21.754,14.494,22,15.432,22,16.386z M16.817,14.138c0-1.331-0.613-2.743-3.033-3.282 l-2.209-0.49c-0.84-0.192-1.807-0.444-1.807-1.237c0-0.794,0.679-1.348,1.903-1.348c2.468,0,2.243,1.696,3.468,1.696 c0.645,0,1.209-0.379,1.209-1.031c0-1.521-2.435-2.663-4.5-2.663c-2.242,0-4.63,0.952-4.63,3.488c0,1.221,0.436,2.521,2.839,3.123 l2.984,0.745c0.903,0.223,1.129,0.731,1.129,1.189c0,0.762-0.758,1.507-2.129,1.507c-2.679,0-2.307-2.062-3.743-2.062 c-0.645,0-1.113,0.444-1.113,1.078c0,1.236,1.501,2.886,4.856,2.886C15.236,17.737,16.817,16.199,16.817,14.138z"></path> </svg>', 'slideshare' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M11.738,10.232a2.142,2.142,0,0,1-.721,1.619,2.556,2.556,0,0,1-3.464,0,2.183,2.183,0,0,1,0-3.243,2.572,2.572,0,0,1,3.464,0A2.136,2.136,0,0,1,11.738,10.232Zm5.7,0a2.15,2.15,0,0,1-.715,1.619,2.563,2.563,0,0,1-3.469,0,2.183,2.183,0,0,1,0-3.243,2.58,2.58,0,0,1,3.469,0A2.144,2.144,0,0,1,17.439,10.232Zm2.555,2.045V4.7a2.128,2.128,0,0,0-.363-1.4,1.614,1.614,0,0,0-1.261-.415H5.742a1.656,1.656,0,0,0-1.278.386A2.246,2.246,0,0,0,4.129,4.7v7.643a8.212,8.212,0,0,0,1,.454q.516.193.92.318a6.847,6.847,0,0,0,.92.21q.516.085.806.125a6.615,6.615,0,0,0,.795.045l.665.006q.16,0,.642-.023t.506-.023a1.438,1.438,0,0,1,1.079.307,1.134,1.134,0,0,0,.114.1,7.215,7.215,0,0,0,.693.579q.079-1.033,1.34-.988.057,0,.415.017l.488.023q.13.006.517.011t.6-.011l.619-.051a5.419,5.419,0,0,0,.693-.1l.7-.153a5.353,5.353,0,0,0,.761-.221q.345-.131.766-.307a8.727,8.727,0,0,0,.818-.392Zm1.851-.057a10.4,10.4,0,0,1-4.225,2.862,6.5,6.5,0,0,1-.261,5.281,3.524,3.524,0,0,1-2.078,1.681,2.452,2.452,0,0,1-2.067-.17,1.915,1.915,0,0,1-.931-1.863l-.011-3.7V16.3l-.279-.068q-.188-.045-.267-.057l-.011,3.839a1.9,1.9,0,0,1-.943,1.863,2.481,2.481,0,0,1-2.078.17,3.519,3.519,0,0,1-2.067-1.7,6.546,6.546,0,0,1-.25-5.258A10.4,10.4,0,0,1,2.152,12.22a.56.56,0,0,1-.045-.715q.238-.3.681.011l.125.079a.767.767,0,0,1,.125.091V3.8a1.987,1.987,0,0,1,.534-1.4,1.7,1.7,0,0,1,1.295-.579H19.141a1.7,1.7,0,0,1,1.295.579,1.985,1.985,0,0,1,.534,1.4v7.882l.238-.17q.443-.307.681-.011a.56.56,0,0,1-.045.715Z"></path> </svg>', 'snapchat' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M12.065,2a5.526,5.526,0,0,1,3.132.892A5.854,5.854,0,0,1,17.326,5.4a5.821,5.821,0,0,1,.351,2.33q0,.612-.117,2.487a.809.809,0,0,0,.365.091,1.93,1.93,0,0,0,.664-.176,1.93,1.93,0,0,1,.664-.176,1.3,1.3,0,0,1,.729.234.7.7,0,0,1,.351.6.839.839,0,0,1-.41.7,2.732,2.732,0,0,1-.9.41,3.192,3.192,0,0,0-.9.378.728.728,0,0,0-.41.618,1.575,1.575,0,0,0,.156.56,6.9,6.9,0,0,0,1.334,1.953,5.6,5.6,0,0,0,1.881,1.315,5.875,5.875,0,0,0,1.042.3.42.42,0,0,1,.365.456q0,.911-2.852,1.341a1.379,1.379,0,0,0-.143.507,1.8,1.8,0,0,1-.182.605.451.451,0,0,1-.429.241,5.878,5.878,0,0,1-.807-.085,5.917,5.917,0,0,0-.833-.085,4.217,4.217,0,0,0-.807.065,2.42,2.42,0,0,0-.82.293,6.682,6.682,0,0,0-.755.5q-.351.267-.755.527a3.886,3.886,0,0,1-.989.436A4.471,4.471,0,0,1,11.831,22a4.307,4.307,0,0,1-1.256-.176,3.784,3.784,0,0,1-.976-.436q-.4-.26-.749-.527a6.682,6.682,0,0,0-.755-.5,2.422,2.422,0,0,0-.807-.293,4.432,4.432,0,0,0-.82-.065,5.089,5.089,0,0,0-.853.1,5,5,0,0,1-.762.1.474.474,0,0,1-.456-.241,1.819,1.819,0,0,1-.182-.618,1.411,1.411,0,0,0-.143-.521q-2.852-.429-2.852-1.341a.42.42,0,0,1,.365-.456,5.793,5.793,0,0,0,1.042-.3,5.524,5.524,0,0,0,1.881-1.315,6.789,6.789,0,0,0,1.334-1.953A1.575,1.575,0,0,0,6,12.9a.728.728,0,0,0-.41-.618,3.323,3.323,0,0,0-.9-.384,2.912,2.912,0,0,1-.9-.41.814.814,0,0,1-.41-.684.71.71,0,0,1,.338-.593,1.208,1.208,0,0,1,.716-.241,1.976,1.976,0,0,1,.625.169,2.008,2.008,0,0,0,.69.169.919.919,0,0,0,.416-.091q-.117-1.849-.117-2.474A5.861,5.861,0,0,1,6.385,5.4,5.516,5.516,0,0,1,8.625,2.819,7.075,7.075,0,0,1,12.062,2Z"></path> </svg>', 'soundcloud' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M8.9,16.1L9,14L8.9,9.5c0-0.1,0-0.1-0.1-0.1c0,0-0.1-0.1-0.1-0.1c-0.1,0-0.1,0-0.1,0.1c0,0-0.1,0.1-0.1,0.1L8.3,14l0.1,2.1 c0,0.1,0,0.1,0.1,0.1c0,0,0.1,0.1,0.1,0.1C8.8,16.3,8.9,16.3,8.9,16.1z M11.4,15.9l0.1-1.8L11.4,9c0-0.1,0-0.2-0.1-0.2 c0,0-0.1,0-0.1,0s-0.1,0-0.1,0c-0.1,0-0.1,0.1-0.1,0.2l0,0.1l-0.1,5c0,0,0,0.7,0.1,2v0c0,0.1,0,0.1,0.1,0.1c0.1,0.1,0.1,0.1,0.2,0.1 c0.1,0,0.1,0,0.2-0.1c0.1,0,0.1-0.1,0.1-0.2L11.4,15.9z M2.4,12.9L2.5,14l-0.2,1.1c0,0.1,0,0.1-0.1,0.1c0,0-0.1,0-0.1-0.1L2.1,14 l0.1-1.1C2.2,12.9,2.3,12.9,2.4,12.9C2.3,12.9,2.4,12.9,2.4,12.9z M3.1,12.2L3.3,14l-0.2,1.8c0,0.1,0,0.1-0.1,0.1 c-0.1,0-0.1,0-0.1-0.1L2.8,14L3,12.2C3,12.2,3,12.2,3.1,12.2C3.1,12.2,3.1,12.2,3.1,12.2z M3.9,11.9L4.1,14l-0.2,2.1 c0,0.1,0,0.1-0.1,0.1c-0.1,0-0.1,0-0.1-0.1L3.5,14l0.2-2.1c0-0.1,0-0.1,0.1-0.1C3.9,11.8,3.9,11.8,3.9,11.9z M4.7,11.9L4.9,14 l-0.2,2.1c0,0.1-0.1,0.1-0.1,0.1c-0.1,0-0.1,0-0.1-0.1L4.3,14l0.2-2.2c0-0.1,0-0.1,0.1-0.1C4.7,11.7,4.7,11.8,4.7,11.9z M5.6,12 l0.2,2l-0.2,2.1c0,0.1-0.1,0.1-0.1,0.1c0,0-0.1,0-0.1,0c0,0,0-0.1,0-0.1L5.1,14l0.2-2c0,0,0-0.1,0-0.1s0.1,0,0.1,0 C5.5,11.9,5.5,11.9,5.6,12L5.6,12z M6.4,10.7L6.6,14l-0.2,2.1c0,0,0,0.1,0,0.1c0,0-0.1,0-0.1,0c-0.1,0-0.1-0.1-0.2-0.2L5.9,14 l0.2-3.3c0-0.1,0.1-0.2,0.2-0.2c0,0,0.1,0,0.1,0C6.4,10.7,6.4,10.7,6.4,10.7z M7.2,10l0.2,4.1l-0.2,2.1c0,0,0,0.1,0,0.1 c0,0-0.1,0-0.1,0c-0.1,0-0.2-0.1-0.2-0.2l-0.1-2.1L6.8,10c0-0.1,0.1-0.2,0.2-0.2c0,0,0.1,0,0.1,0S7.2,9.9,7.2,10z M8,9.6L8.2,14 L8,16.1c0,0.1-0.1,0.2-0.2,0.2c-0.1,0-0.2-0.1-0.2-0.2L7.5,14l0.1-4.4c0-0.1,0-0.1,0.1-0.1c0,0,0.1-0.1,0.1-0.1c0.1,0,0.1,0,0.1,0.1 C8,9.6,8,9.6,8,9.6z M11.4,16.1L11.4,16.1L11.4,16.1z M9.7,9.6L9.8,14l-0.1,2.1c0,0.1,0,0.1-0.1,0.2s-0.1,0.1-0.2,0.1 c-0.1,0-0.1,0-0.1-0.1s-0.1-0.1-0.1-0.2L9.2,14l0.1-4.4c0-0.1,0-0.1,0.1-0.2s0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.2,0.1S9.7,9.5,9.7,9.6 L9.7,9.6z M10.6,9.8l0.1,4.3l-0.1,2c0,0.1,0,0.1-0.1,0.2c0,0-0.1,0.1-0.2,0.1c-0.1,0-0.1,0-0.2-0.1c0,0-0.1-0.1-0.1-0.2L10,14 l0.1-4.3c0-0.1,0-0.1,0.1-0.2c0,0,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.2,0.1S10.6,9.7,10.6,9.8z M12.4,14l-0.1,2c0,0.1,0,0.1-0.1,0.2 c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0-0.1,0-0.2-0.1c-0.1-0.1-0.1-0.1-0.1-0.2l-0.1-1l-0.1-1l0.1-5.5v0c0-0.1,0-0.2,0.1-0.2 c0.1,0,0.1-0.1,0.2-0.1c0,0,0.1,0,0.1,0c0.1,0,0.1,0.1,0.1,0.2L12.4,14z M22.1,13.9c0,0.7-0.2,1.3-0.7,1.7c-0.5,0.5-1.1,0.7-1.7,0.7 h-6.8c-0.1,0-0.1,0-0.2-0.1c-0.1-0.1-0.1-0.1-0.1-0.2V8.2c0-0.1,0.1-0.2,0.2-0.3c0.5-0.2,1-0.3,1.6-0.3c1.1,0,2.1,0.4,2.9,1.1 c0.8,0.8,1.3,1.7,1.4,2.8c0.3-0.1,0.6-0.2,1-0.2c0.7,0,1.3,0.2,1.7,0.7C21.8,12.6,22.1,13.2,22.1,13.9L22.1,13.9z"></path> </svg>', 'spotify' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M12,2C6.477,2,2,6.477,2,12c0,5.523,4.477,10,10,10c5.523,0,10-4.477,10-10C22,6.477,17.523,2,12,2 M16.586,16.424 c-0.18,0.295-0.563,0.387-0.857,0.207c-2.348-1.435-5.304-1.76-8.785-0.964c-0.335,0.077-0.67-0.133-0.746-0.469 c-0.077-0.335,0.132-0.67,0.469-0.746c3.809-0.871,7.077-0.496,9.713,1.115C16.673,15.746,16.766,16.13,16.586,16.424 M17.81,13.7 c-0.226,0.367-0.706,0.482-1.072,0.257c-2.687-1.652-6.785-2.131-9.965-1.166C6.36,12.917,5.925,12.684,5.8,12.273 C5.675,11.86,5.908,11.425,6.32,11.3c3.632-1.102,8.147-0.568,11.234,1.328C17.92,12.854,18.035,13.335,17.81,13.7 M17.915,10.865 c-3.223-1.914-8.54-2.09-11.618-1.156C5.804,9.859,5.281,9.58,5.131,9.086C4.982,8.591,5.26,8.069,5.755,7.919 c3.532-1.072,9.404-0.865,13.115,1.338c0.445,0.264,0.59,0.838,0.327,1.282C18.933,10.983,18.359,11.129,17.915,10.865"></path> </svg>', 'stumbleupon' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M12,4.294c-2.469,0-4.471,2.002-4.471,4.471v6.353c0,0.585-0.474,1.059-1.059,1.059c-0.585,0-1.059-0.474-1.059-1.059 v-2.824H2v2.941c0,2.469,2.002,4.471,4.471,4.471c2.469,0,4.471-2.002,4.471-4.471V8.765c0-0.585,0.474-1.059,1.059-1.059 s1.059,0.474,1.059,1.059v1.294l1.412,0.647l2-0.647V8.765C16.471,6.296,14.469,4.294,12,4.294z M13.059,12.353v2.882 c0,2.469,2.002,4.471,4.471,4.471S22,17.704,22,15.235v-2.824h-3.412v2.824c0,0.585-0.474,1.059-1.059,1.059 c-0.585,0-1.059-0.474-1.059-1.059v-2.882l-2,0.647L13.059,12.353z"></path> </svg>', 'tumblr' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M16.749,17.396c-0.357,0.17-1.041,0.319-1.551,0.332c-1.539,0.041-1.837-1.081-1.85-1.896V9.847h3.861V6.937h-3.847V2.039 c0,0-2.77,0-2.817,0c-0.046,0-0.127,0.041-0.138,0.144c-0.165,1.499-0.867,4.13-3.783,5.181v2.484h1.945v6.282 c0,2.151,1.587,5.206,5.775,5.135c1.413-0.024,2.982-0.616,3.329-1.126L16.749,17.396z"></path> </svg>', 'twitch' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M16.499,8.089h-1.636v4.91h1.636V8.089z M12,8.089h-1.637v4.91H12V8.089z M4.228,3.178L3,6.451v13.092h4.499V22h2.456 l2.454-2.456h3.681L21,14.636V3.178H4.228z M19.364,13.816l-2.864,2.865H12l-2.453,2.453V16.68H5.863V4.814h13.501V13.816z"></path> </svg>', 'twitter' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M22.23,5.924c-0.736,0.326-1.527,0.547-2.357,0.646c0.847-0.508,1.498-1.312,1.804-2.27 c-0.793,0.47-1.671,0.812-2.606,0.996C18.324,4.498,17.257,4,16.077,4c-2.266,0-4.103,1.837-4.103,4.103 c0,0.322,0.036,0.635,0.106,0.935C8.67,8.867,5.647,7.234,3.623,4.751C3.27,5.357,3.067,6.062,3.067,6.814 c0,1.424,0.724,2.679,1.825,3.415c-0.673-0.021-1.305-0.206-1.859-0.513c0,0.017,0,0.034,0,0.052c0,1.988,1.414,3.647,3.292,4.023 c-0.344,0.094-0.707,0.144-1.081,0.144c-0.264,0-0.521-0.026-0.772-0.074c0.522,1.63,2.038,2.816,3.833,2.85 c-1.404,1.1-3.174,1.756-5.096,1.756c-0.331,0-0.658-0.019-0.979-0.057c1.816,1.164,3.973,1.843,6.29,1.843 c7.547,0,11.675-6.252,11.675-11.675c0-0.178-0.004-0.355-0.012-0.531C20.985,7.47,21.68,6.747,22.23,5.924z"></path> </svg>', 'vimeo' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M22.396,7.164c-0.093,2.026-1.507,4.799-4.245,8.32C15.322,19.161,12.928,21,10.97,21c-1.214,0-2.24-1.119-3.079-3.359 c-0.56-2.053-1.119-4.106-1.68-6.159C5.588,9.243,4.921,8.122,4.206,8.122c-0.156,0-0.701,0.328-1.634,0.98L1.594,7.841 c1.027-0.902,2.04-1.805,3.037-2.708C6.001,3.95,7.03,3.327,7.715,3.264c1.619-0.156,2.616,0.951,2.99,3.321 c0.404,2.557,0.685,4.147,0.841,4.769c0.467,2.121,0.981,3.181,1.542,3.181c0.435,0,1.09-0.688,1.963-2.065 c0.871-1.376,1.338-2.422,1.401-3.142c0.125-1.187-0.343-1.782-1.401-1.782c-0.498,0-1.012,0.115-1.541,0.341 c1.023-3.35,2.977-4.977,5.862-4.884C21.511,3.066,22.52,4.453,22.396,7.164z"></path> </svg>', 'vk' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M22,7.1c0.2,0.4-0.4,1.5-1.6,3.1c-0.2,0.2-0.4,0.5-0.7,0.9c-0.5,0.7-0.9,1.1-0.9,1.4c-0.1,0.3-0.1,0.6,0.1,0.8 c0.1,0.1,0.4,0.4,0.8,0.9h0l0,0c1,0.9,1.6,1.7,2,2.3c0,0,0,0.1,0.1,0.1c0,0.1,0,0.1,0.1,0.3c0,0.1,0,0.2,0,0.4 c0,0.1-0.1,0.2-0.3,0.3c-0.1,0.1-0.4,0.1-0.6,0.1l-2.7,0c-0.2,0-0.4,0-0.6-0.1c-0.2-0.1-0.4-0.1-0.5-0.2l-0.2-0.1 c-0.2-0.1-0.5-0.4-0.7-0.7s-0.5-0.6-0.7-0.8c-0.2-0.2-0.4-0.4-0.6-0.6C14.8,15,14.6,15,14.4,15c0,0,0,0-0.1,0c0,0-0.1,0.1-0.2,0.2 c-0.1,0.1-0.2,0.2-0.2,0.3c-0.1,0.1-0.1,0.3-0.2,0.5c-0.1,0.2-0.1,0.5-0.1,0.8c0,0.1,0,0.2,0,0.3c0,0.1-0.1,0.2-0.1,0.2l0,0.1 c-0.1,0.1-0.3,0.2-0.6,0.2h-1.2c-0.5,0-1,0-1.5-0.2c-0.5-0.1-1-0.3-1.4-0.6s-0.7-0.5-1.1-0.7s-0.6-0.4-0.7-0.6l-0.3-0.3 c-0.1-0.1-0.2-0.2-0.3-0.3s-0.4-0.5-0.7-0.9s-0.7-1-1.1-1.6c-0.4-0.6-0.8-1.3-1.3-2.2C2.9,9.4,2.5,8.5,2.1,7.5C2,7.4,2,7.3,2,7.2 c0-0.1,0-0.1,0-0.2l0-0.1c0.1-0.1,0.3-0.2,0.6-0.2l2.9,0c0.1,0,0.2,0,0.2,0.1S5.9,6.9,5.9,7L6,7c0.1,0.1,0.2,0.2,0.3,0.3 C6.4,7.7,6.5,8,6.7,8.4C6.9,8.8,7,9,7.1,9.2l0.2,0.3c0.2,0.4,0.4,0.8,0.6,1.1c0.2,0.3,0.4,0.5,0.5,0.7s0.3,0.3,0.4,0.4 c0.1,0.1,0.3,0.1,0.4,0.1c0.1,0,0.2,0,0.3-0.1c0,0,0,0,0.1-0.1c0,0,0.1-0.1,0.1-0.2c0.1-0.1,0.1-0.3,0.1-0.5c0-0.2,0.1-0.5,0.1-0.8 c0-0.4,0-0.8,0-1.3c0-0.3,0-0.5-0.1-0.8c0-0.2-0.1-0.4-0.1-0.5L9.6,7.6C9.4,7.3,9.1,7.2,8.7,7.1C8.6,7.1,8.6,7,8.7,6.9 C8.9,6.7,9,6.6,9.1,6.5c0.4-0.2,1.2-0.3,2.5-0.3c0.6,0,1,0.1,1.4,0.1c0.1,0,0.3,0.1,0.3,0.1c0.1,0.1,0.2,0.1,0.2,0.3 c0,0.1,0.1,0.2,0.1,0.3s0,0.3,0,0.5c0,0.2,0,0.4,0,0.6c0,0.2,0,0.4,0,0.7c0,0.3,0,0.6,0,0.9c0,0.1,0,0.2,0,0.4c0,0.2,0,0.4,0,0.5 c0,0.1,0,0.3,0,0.4s0.1,0.3,0.1,0.4c0.1,0.1,0.1,0.2,0.2,0.3c0.1,0,0.1,0,0.2,0c0.1,0,0.2,0,0.3-0.1c0.1-0.1,0.2-0.2,0.4-0.4 s0.3-0.4,0.5-0.7c0.2-0.3,0.5-0.7,0.7-1.1c0.4-0.7,0.8-1.5,1.1-2.3c0-0.1,0.1-0.1,0.1-0.2c0-0.1,0.1-0.1,0.1-0.1l0,0l0.1,0 c0,0,0,0,0.1,0s0.2,0,0.2,0l3,0c0.3,0,0.5,0,0.7,0S21.9,7,21.9,7L22,7.1z"></path> </svg>', 'wordpress' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M12.158,12.786L9.46,20.625c0.806,0.237,1.657,0.366,2.54,0.366c1.047,0,2.051-0.181,2.986-0.51 c-0.024-0.038-0.046-0.079-0.065-0.124L12.158,12.786z M3.009,12c0,3.559,2.068,6.634,5.067,8.092L3.788,8.341 C3.289,9.459,3.009,10.696,3.009,12z M18.069,11.546c0-1.112-0.399-1.881-0.741-2.48c-0.456-0.741-0.883-1.368-0.883-2.109 c0-0.826,0.627-1.596,1.51-1.596c0.04,0,0.078,0.005,0.116,0.007C16.472,3.904,14.34,3.009,12,3.009 c-3.141,0-5.904,1.612-7.512,4.052c0.211,0.007,0.41,0.011,0.579,0.011c0.94,0,2.396-0.114,2.396-0.114 C7.947,6.93,8.004,7.642,7.52,7.699c0,0-0.487,0.057-1.029,0.085l3.274,9.739l1.968-5.901l-1.401-3.838 C9.848,7.756,9.389,7.699,9.389,7.699C8.904,7.67,8.961,6.93,9.446,6.958c0,0,1.484,0.114,2.368,0.114 c0.94,0,2.397-0.114,2.397-0.114c0.485-0.028,0.542,0.684,0.057,0.741c0,0-0.488,0.057-1.029,0.085l3.249,9.665l0.897-2.996 C17.841,13.284,18.069,12.316,18.069,11.546z M19.889,7.686c0.039,0.286,0.06,0.593,0.06,0.924c0,0.912-0.171,1.938-0.684,3.22 l-2.746,7.94c2.673-1.558,4.47-4.454,4.47-7.771C20.991,10.436,20.591,8.967,19.889,7.686z M12,22C6.486,22,2,17.514,2,12 C2,6.486,6.486,2,12,2c5.514,0,10,4.486,10,10C22,17.514,17.514,22,12,22z"></path> </svg>', 'yelp' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M12.271,16.718v1.417q-.011,3.257-.067,3.4a.707.707,0,0,1-.569.446,4.637,4.637,0,0,1-2.024-.424A4.609,4.609,0,0,1,7.8,20.565a.844.844,0,0,1-.19-.4.692.692,0,0,1,.044-.29,3.181,3.181,0,0,1,.379-.524q.335-.412,2.019-2.409.011,0,.669-.781a.757.757,0,0,1,.44-.274.965.965,0,0,1,.552.039.945.945,0,0,1,.418.324.732.732,0,0,1,.139.468Zm-1.662-2.8a.783.783,0,0,1-.58.781l-1.339.435q-3.067.981-3.257.981a.711.711,0,0,1-.6-.4,2.636,2.636,0,0,1-.19-.836,9.134,9.134,0,0,1,.011-1.857,3.559,3.559,0,0,1,.335-1.389.659.659,0,0,1,.625-.357,22.629,22.629,0,0,1,2.253.859q.781.324,1.283.524l.937.379a.771.771,0,0,1,.4.34A.982.982,0,0,1,10.609,13.917Zm9.213,3.313a4.467,4.467,0,0,1-1.021,1.8,4.559,4.559,0,0,1-1.512,1.417.671.671,0,0,1-.7-.078q-.156-.112-2.052-3.2l-.524-.859a.761.761,0,0,1-.128-.513.957.957,0,0,1,.217-.513.774.774,0,0,1,.926-.29q.011.011,1.327.446,2.264.736,2.7.887a2.082,2.082,0,0,1,.524.229.673.673,0,0,1,.245.68Zm-7.5-7.049q.056,1.137-.6,1.361-.647.19-1.272-.792L6.237,4.08a.7.7,0,0,1,.212-.691,5.788,5.788,0,0,1,2.314-1,5.928,5.928,0,0,1,2.5-.352.681.681,0,0,1,.547.5q.034.2.245,3.407T12.327,10.181Zm7.384,1.2a.679.679,0,0,1-.29.658q-.167.112-3.67.959-.747.167-1.015.257l.011-.022a.769.769,0,0,1-.513-.044.914.914,0,0,1-.413-.357.786.786,0,0,1,0-.971q.011-.011.836-1.137,1.394-1.908,1.673-2.275a2.423,2.423,0,0,1,.379-.435A.7.7,0,0,1,17.435,8a4.482,4.482,0,0,1,1.372,1.489,4.81,4.81,0,0,1,.9,1.868v.034Z"></path> </svg>', 'youtube' => ' <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path> </svg>', ); } class-twentynineteen-walker-comment.php 0000644 00000010017 15252477157 0014401 0 ustar 00 <?php /** * Custom comment walker for this theme * * @package WordPress * @subpackage Twenty_Nineteen * @since Twenty Nineteen 1.0 */ /** * This class outputs custom comment walker for HTML5 friendly WordPress comment and threaded replies. * * @since Twenty Nineteen 1.0 */ class TwentyNineteen_Walker_Comment extends Walker_Comment { /** * Outputs a comment in the HTML5 format. * * @see wp_list_comments() * * @param WP_Comment $comment Comment to display. * @param int $depth Depth of the current comment. * @param array $args An array of arguments. */ protected function html5_comment( $comment, $depth, $args ) { $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; ?> <<?php echo $tag; ?> id="comment-<?php comment_ID(); ?>" <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?>> <article id="div-comment-<?php comment_ID(); ?>" class="comment-body"> <footer class="comment-meta"> <div class="comment-author vcard"> <?php $comment_author_url = get_comment_author_url( $comment ); $comment_author = get_comment_author( $comment ); $avatar = get_avatar( $comment, $args['avatar_size'] ); if ( 0 != $args['avatar_size'] ) { if ( empty( $comment_author_url ) ) { echo $avatar; } else { printf( '<a href="%s" rel="external nofollow" class="url">', $comment_author_url ); echo $avatar; } } /* * Using the `check` icon instead of `check_circle`, since we can't add a * fill color to the inner check shape when in circle form. */ if ( twentynineteen_is_comment_by_post_author( $comment ) ) { printf( '<span class="post-author-badge" aria-hidden="true">%s</span>', twentynineteen_get_icon_svg( 'check', 24 ) ); } printf( wp_kses( /* translators: %s: Comment author link. */ __( '%s <span class="screen-reader-text says">says:</span>', 'twentynineteen' ), array( 'span' => array( 'class' => array(), ), ) ), '<b class="fn">' . $comment_author . '</b>' ); if ( ! empty( $comment_author_url ) ) { echo '</a>'; } ?> </div><!-- .comment-author --> <div class="comment-metadata"> <a href="<?php echo esc_url( get_comment_link( $comment, $args ) ); ?>"> <?php /* translators: 1: Comment date, 2: Comment time. */ $comment_timestamp = sprintf( __( '%1$s at %2$s', 'twentynineteen' ), get_comment_date( '', $comment ), get_comment_time() ); ?> <time datetime="<?php comment_time( 'c' ); ?>" title="<?php echo $comment_timestamp; ?>"> <?php echo $comment_timestamp; ?> </time> </a> <?php $edit_comment_icon = twentynineteen_get_icon_svg( 'edit', 16 ); edit_comment_link( __( 'Edit', 'twentynineteen' ), '<span class="edit-link-sep">—</span> <span class="edit-link">' . $edit_comment_icon, '</span>' ); ?> </div><!-- .comment-metadata --> <?php $commenter = wp_get_current_commenter(); if ( $commenter['comment_author_email'] ) { $moderation_note = __( 'Your comment is awaiting moderation.', 'twentynineteen' ); } else { $moderation_note = __( 'Your comment is awaiting moderation. This is a preview, your comment will be visible after it has been approved.', 'twentynineteen' ); } ?> <?php if ( '0' == $comment->comment_approved ) : ?> <p class="comment-awaiting-moderation"><?php echo $moderation_note; ?></p> <?php endif; ?> </footer><!-- .comment-meta --> <div class="comment-content"> <?php comment_text(); ?> </div><!-- .comment-content --> </article><!-- .comment-body --> <?php comment_reply_link( array_merge( $args, array( 'add_below' => 'div-comment', 'depth' => $depth, 'max_depth' => $args['max_depth'], 'before' => '<div class="comment-reply">', 'after' => '</div>', ) ) ); ?> <?php } } class-twentytwenty-non-latin-languages.php 0000644 00000014771 15252503212 0015035 0 ustar 00 <?php /** * Non-latin language handling. * * Handle non-latin language styles. * * @package WordPress * @subpackage Twenty_Twenty * @since Twenty Twenty 1.0 */ if ( ! class_exists( 'TwentyTwenty_Non_Latin_Languages' ) ) { /** * Language handling. */ class TwentyTwenty_Non_Latin_Languages { /** * Get custom CSS. * * Return CSS for non-latin language, if available, or null * * @param string $type Whether to return CSS for the "front-end", "block-editor" or "classic-editor". * @return void */ public static function get_non_latin_css( $type = 'front-end' ) { // Fetch site locale. $locale = get_bloginfo( 'language' ); // Define fallback fonts for non-latin languages. $font_family = apply_filters( 'twentytwenty_get_localized_font_family_types', array( // Arabic. 'ar' => array( 'Tahoma', 'Arial', 'sans-serif' ), 'ary' => array( 'Tahoma', 'Arial', 'sans-serif' ), 'azb' => array( 'Tahoma', 'Arial', 'sans-serif' ), 'ckb' => array( 'Tahoma', 'Arial', 'sans-serif' ), 'fa-IR' => array( 'Tahoma', 'Arial', 'sans-serif' ), 'haz' => array( 'Tahoma', 'Arial', 'sans-serif' ), 'ps' => array( 'Tahoma', 'Arial', 'sans-serif' ), // Chinese Simplified (China) - Noto Sans SC. 'zh-CN' => array( '\'PingFang SC\'', '\'Helvetica Neue\'', '\'Microsoft YaHei New\'', '\'STHeiti Light\'', 'sans-serif' ), // Chinese Traditional (Taiwan) - Noto Sans TC. 'zh-TW' => array( '\'PingFang TC\'', '\'Helvetica Neue\'', '\'Microsoft YaHei New\'', '\'STHeiti Light\'', 'sans-serif' ), // Chinese (Hong Kong) - Noto Sans HK. 'zh-HK' => array( '\'PingFang HK\'', '\'Helvetica Neue\'', '\'Microsoft YaHei New\'', '\'STHeiti Light\'', 'sans-serif' ), // Cyrillic. 'bel' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'bg-BG' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'kk' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'mk-MK' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'mn' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'ru-RU' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'sah' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'sr-RS' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'tt-RU' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'uk' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), // Devanagari. 'bn-BD' => array( 'Arial', 'sans-serif' ), 'hi-IN' => array( 'Arial', 'sans-serif' ), 'mr' => array( 'Arial', 'sans-serif' ), 'ne-NP' => array( 'Arial', 'sans-serif' ), // Greek. 'el' => array( '\'Helvetica Neue\', Helvetica, Arial, sans-serif' ), // Gujarati. 'gu' => array( 'Arial', 'sans-serif' ), // Hebrew. 'he-IL' => array( '\'Arial Hebrew\'', 'Arial', 'sans-serif' ), // Japanese. 'ja' => array( 'sans-serif' ), // Korean. 'ko-KR' => array( '\'Apple SD Gothic Neo\'', '\'Malgun Gothic\'', '\'Nanum Gothic\'', 'Dotum', 'sans-serif' ), // Thai. 'th' => array( '\'Sukhumvit Set\'', '\'Helvetica Neue\'', 'Helvetica', 'Arial', 'sans-serif' ), // Vietnamese. 'vi' => array( '\'Libre Franklin\'', 'sans-serif' ), ) ); // Return if the selected language has no fallback fonts. if ( empty( $font_family[ $locale ] ) ) { return; } // Define elements to apply fallback fonts to. $elements = apply_filters( 'twentytwenty_get_localized_font_family_elements', array( 'front-end' => array( 'body', 'input', 'textarea', 'button', '.button', '.faux-button', '.wp-block-button__link', '.wp-block-file__button', '.has-drop-cap:not(:focus)::first-letter', '.has-drop-cap:not(:focus)::first-letter', '.entry-content .wp-block-archives', '.entry-content .wp-block-categories', '.entry-content .wp-block-cover-image', '.entry-content .wp-block-latest-comments', '.entry-content .wp-block-latest-posts', '.entry-content .wp-block-pullquote', '.entry-content .wp-block-quote.is-large', '.entry-content .wp-block-quote.is-style-large', '.entry-content .wp-block-archives *', '.entry-content .wp-block-categories *', '.entry-content .wp-block-latest-posts *', '.entry-content .wp-block-latest-comments *', '.entry-content p', '.entry-content ol', '.entry-content ul', '.entry-content dl', '.entry-content dt', '.entry-content cite', '.entry-content figcaption', '.entry-content .wp-caption-text', '.comment-content p', '.comment-content ol', '.comment-content ul', '.comment-content dl', '.comment-content dt', '.comment-content cite', '.comment-content figcaption', '.comment-content .wp-caption-text', '.widget_text p', '.widget_text ol', '.widget_text ul', '.widget_text dl', '.widget_text dt', '.widget-content .rssSummary', '.widget-content cite', '.widget-content figcaption', '.widget-content .wp-caption-text' ), 'block-editor' => array( '.editor-styles-wrapper > *', '.editor-styles-wrapper p', '.editor-styles-wrapper ol', '.editor-styles-wrapper ul', '.editor-styles-wrapper dl', '.editor-styles-wrapper dt', '.editor-post-title__block .editor-post-title__input', '.editor-styles-wrapper .wp-block h1', '.editor-styles-wrapper .wp-block h2', '.editor-styles-wrapper .wp-block h3', '.editor-styles-wrapper .wp-block h4', '.editor-styles-wrapper .wp-block h5', '.editor-styles-wrapper .wp-block h6', '.editor-styles-wrapper .has-drop-cap:not(:focus)::first-letter', '.editor-styles-wrapper cite', '.editor-styles-wrapper figcaption', '.editor-styles-wrapper .wp-caption-text' ), 'classic-editor' => array( 'body#tinymce.wp-editor', 'body#tinymce.wp-editor p', 'body#tinymce.wp-editor ol', 'body#tinymce.wp-editor ul', 'body#tinymce.wp-editor dl', 'body#tinymce.wp-editor dt', 'body#tinymce.wp-editor figcaption', 'body#tinymce.wp-editor .wp-caption-text', 'body#tinymce.wp-editor .wp-caption-dd', 'body#tinymce.wp-editor cite', 'body#tinymce.wp-editor table' ), ) ); // Return if the specified type doesn't exist. if ( empty( $elements[ $type ] ) ) { return; } // Return the specified styles. return twentytwenty_generate_css( implode( ',', $elements[ $type ] ), 'font-family', implode( ',', $font_family[ $locale ] ), null, null, false ); } } } class-twentytwenty-script-loader.php 0000644 00000002335 15252503212 0013733 0 ustar 00 <?php /** * Javascript Loader Class * * Allow `async` and `defer` while enqueuing Javascript. * * Based on a solution in WP Rig. * * @package WordPress * @subpackage Twenty_Twenty * @since Twenty Twenty 1.0 */ if ( ! class_exists( 'TwentyTwenty_Script_Loader' ) ) { /** * A class that provides a way to add `async` or `defer` attributes to scripts. */ class TwentyTwenty_Script_Loader { /** * Adds async/defer attributes to enqueued / registered scripts. * * If #12009 lands in WordPress, this function can no-op since it would be handled in core. * * @link https://core.trac.wordpress.org/ticket/12009 * * @param string $tag The script tag. * @param string $handle The script handle. * @return string Script HTML string. */ public function filter_script_loader_tag( $tag, $handle ) { foreach ( array( 'async', 'defer' ) as $attr ) { if ( ! wp_scripts()->get_data( $handle, $attr ) ) { continue; } // Prevent adding attribute when already added in #12009. if ( ! preg_match( ":\s$attr(=|>|\s):", $tag ) ) { $tag = preg_replace( ':(?=></script>):', " $attr", $tag, 1 ); } // Only allow async or defer, not both. break; } return $tag; } } } class-twentytwenty-svg-icons.php 0000644 00000205235 15252503212 0013077 0 ustar 00 <?php /** * Custom icons for this theme. * * @package WordPress * @subpackage Twenty_Twenty * @since Twenty Twenty 1.0 */ if ( ! class_exists( 'TwentyTwenty_SVG_Icons' ) ) { /** * SVG ICONS CLASS * Retrieve the SVG code for the specified icon. Based on a solution in Twenty Nineteen. */ class TwentyTwenty_SVG_Icons { /** * GET SVG CODE * Get the SVG code for the specified icon * * @param string $icon Icon name. * @param string $group Icon group. * @param string $color Color. */ public static function get_svg( $icon, $group = 'ui', $color = '#1A1A1B' ) { if ( 'ui' === $group ) { $arr = self::$ui_icons; } elseif ( 'social' === $group ) { $arr = self::$social_icons; } else { $arr = array(); } /** * Filters Twenty Twenty's array of icons. * * The dynamic portion of the hook name, `$group`, refers to * the name of the group of icons, either "ui" or "social". * * @since Twenty Twenty 1.5 * * @param array $arr Array of icons. */ $arr = apply_filters( "twentytwenty_svg_icons_{$group}", $arr ); /** * Filters an SVG icon's color. * * @since Twenty Twenty 1.5 * * @param string $color The icon color. * @param string $icon The icon name. * @param string $group The icon group. */ $color = apply_filters( 'twentytwenty_svg_icon_color', $color, $icon, $group ); if ( array_key_exists( $icon, $arr ) ) { $repl = '<svg class="svg-icon" aria-hidden="true" role="img" focusable="false" '; $svg = preg_replace( '/^<svg /', $repl, trim( $arr[ $icon ] ) ); // Add extra attributes to SVG code. $svg = str_replace( '#1A1A1B', $color, $svg ); // Replace the color. $svg = str_replace( '#', '%23', $svg ); // Urlencode hashes. $svg = preg_replace( "/([\n\t]+)/", ' ', $svg ); // Remove newlines & tabs. $svg = preg_replace( '/>\s*</', '><', $svg ); // Remove whitespace between SVG tags. return $svg; } return null; } /** * GET SOCIAL LINK SVG * Detects the social network from a URL and returns the SVG code for its icon. * * @param string $uri The URL to retrieve SVG for. */ public static function get_social_link_svg( $uri ) { static $regex_map; // Only compute regex map once, for performance. if ( ! isset( $regex_map ) ) { $regex_map = array(); /** * Filters Twenty Twenty's array of domain mappings for social icons. * * By default, each Icon ID is matched against a .com TLD. To override this behavior, * specify all the domains it covers (including the .com TLD too, if applicable). * * @since Twenty Twenty 1.5 * * @param array $social_icons_map Array of default social icons. */ $map = apply_filters( 'twentytwenty_social_icons_map', self::$social_icons_map ); /** * Filters Twenty Twenty's array of social icons. * * @since Twenty Twenty 1.5 * * @param array $social_icons Array of default social icons. */ $social_icons = apply_filters( 'twentytwenty_svg_icons_social', self::$social_icons ); foreach ( array_keys( $social_icons ) as $icon ) { $domains = array_key_exists( $icon, $map ) ? $map[ $icon ] : array( sprintf( '%s.com', $icon ) ); $domains = array_map( 'trim', $domains ); // Remove leading/trailing spaces, to prevent regex from failing to match. $domains = array_map( 'preg_quote', $domains ); $regex_map[ $icon ] = sprintf( '/(%s)/i', implode( '|', $domains ) ); } } foreach ( $regex_map as $icon => $regex ) { if ( preg_match( $regex, $uri ) ) { return twentytwenty_get_theme_svg( $icon, 'social' ); } } return null; } /** * ICON STORAGE * Store the code for all SVGs in an array. * * @var array */ public static $ui_icons = array( 'arrow-down' => '<svg xmlns="http://www.w3.org/2000/svg" width="22" height="24" viewBox="0 0 22 24"> <polygon fill="#FFF" points="721.105 856 721.105 874.315 728.083 867.313 730.204 869.41 719.59 880 709 869.41 711.074 867.313 718.076 874.315 718.076 856" transform="translate(-709 -856)"/> </svg>', 'arrow-down-circled' => '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"> <path fill="#FFF" fill-rule="evenodd" d="M16,32 C7.163444,32 0,24.836556 0,16 C0,7.163444 7.163444,0 16,0 C24.836556,0 32,7.163444 32,16 C32,24.836556 24.836556,32 16,32 Z M16.7934656,8 L15.4886113,8 L15.4886113,21.5300971 L10.082786,16.1242718 L9.18181515,17.0407767 L16.1410384,24 L23.1157957,17.0407767 L22.1915239,16.1242718 L16.7934656,21.5300971 L16.7934656,8 Z"/> </svg>', 'bookmark' => '<svg xmlns="http://www.w3.org/2000/svg" width="15" height="18" viewBox="0 0 15 18"> <path d="M12.598889,2.699762 C12.598889,2.20275 12.195981,1.799841 11.698969,1.799841 L2.699762,1.799841 C2.20275,1.799841 1.799841,2.20275 1.799841,2.699762 L1.799841,15.349777 L6.676297,11.866594 C6.989197,11.643094 7.409533,11.643094 7.722434,11.866594 L12.598889,15.349777 L12.598889,2.699762 Z M1.422989,17.830788 C0.82736,18.256238 0,17.830464 0,17.098493 L0,2.699762 C0,1.208725 1.208725,0 2.699762,0 L11.698969,0 C13.190006,0 14.398731,1.208725 14.398731,2.699762 L14.398731,17.098493 C14.398731,17.830464 13.571371,18.256238 12.975742,17.830788 L7.199365,13.704805 L1.422989,17.830788 Z"/> </svg>', 'calendar' => '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="19" viewBox="0 0 18 19"> <path fill="#1A1A1B" d="M4.60069444,4.09375 L3.25,4.09375 C2.47334957,4.09375 1.84375,4.72334957 1.84375,5.5 L1.84375,7.26736111 L16.15625,7.26736111 L16.15625,5.5 C16.15625,4.72334957 15.5266504,4.09375 14.75,4.09375 L13.3993056,4.09375 L13.3993056,4.55555556 C13.3993056,5.02154581 13.0215458,5.39930556 12.5555556,5.39930556 C12.0895653,5.39930556 11.7118056,5.02154581 11.7118056,4.55555556 L11.7118056,4.09375 L6.28819444,4.09375 L6.28819444,4.55555556 C6.28819444,5.02154581 5.9104347,5.39930556 5.44444444,5.39930556 C4.97845419,5.39930556 4.60069444,5.02154581 4.60069444,4.55555556 L4.60069444,4.09375 Z M6.28819444,2.40625 L11.7118056,2.40625 L11.7118056,1 C11.7118056,0.534009742 12.0895653,0.15625 12.5555556,0.15625 C13.0215458,0.15625 13.3993056,0.534009742 13.3993056,1 L13.3993056,2.40625 L14.75,2.40625 C16.4586309,2.40625 17.84375,3.79136906 17.84375,5.5 L17.84375,15.875 C17.84375,17.5836309 16.4586309,18.96875 14.75,18.96875 L3.25,18.96875 C1.54136906,18.96875 0.15625,17.5836309 0.15625,15.875 L0.15625,5.5 C0.15625,3.79136906 1.54136906,2.40625 3.25,2.40625 L4.60069444,2.40625 L4.60069444,1 C4.60069444,0.534009742 4.97845419,0.15625 5.44444444,0.15625 C5.9104347,0.15625 6.28819444,0.534009742 6.28819444,1 L6.28819444,2.40625 Z M1.84375,8.95486111 L1.84375,15.875 C1.84375,16.6516504 2.47334957,17.28125 3.25,17.28125 L14.75,17.28125 C15.5266504,17.28125 16.15625,16.6516504 16.15625,15.875 L16.15625,8.95486111 L1.84375,8.95486111 Z"/> </svg>', 'chevron-down' => '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="12" viewBox="0 0 20 12"> <polygon fill="#1A1A1B" fill-rule="evenodd" points="1319.899 365.778 1327.678 358 1329.799 360.121 1319.899 370.021 1310 360.121 1312.121 358" transform="translate(-1310 -358)"/> </svg>', 'comment' => '<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19"> <path d="M9.43016863,13.2235931 C9.58624731,13.094699 9.7823475,13.0241935 9.98476849,13.0241935 L15.0564516,13.0241935 C15.8581553,13.0241935 16.5080645,12.3742843 16.5080645,11.5725806 L16.5080645,3.44354839 C16.5080645,2.64184472 15.8581553,1.99193548 15.0564516,1.99193548 L3.44354839,1.99193548 C2.64184472,1.99193548 1.99193548,2.64184472 1.99193548,3.44354839 L1.99193548,11.5725806 C1.99193548,12.3742843 2.64184472,13.0241935 3.44354839,13.0241935 L5.76612903,13.0241935 C6.24715123,13.0241935 6.63709677,13.4141391 6.63709677,13.8951613 L6.63709677,15.5301903 L9.43016863,13.2235931 Z M3.44354839,14.766129 C1.67980032,14.766129 0.25,13.3363287 0.25,11.5725806 L0.25,3.44354839 C0.25,1.67980032 1.67980032,0.25 3.44354839,0.25 L15.0564516,0.25 C16.8201997,0.25 18.25,1.67980032 18.25,3.44354839 L18.25,11.5725806 C18.25,13.3363287 16.8201997,14.766129 15.0564516,14.766129 L10.2979143,14.766129 L6.32072889,18.0506004 C5.75274472,18.5196577 4.89516129,18.1156602 4.89516129,17.3790323 L4.89516129,14.766129 L3.44354839,14.766129 Z"/> </svg>', 'cross' => '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"> <polygon fill="#1A1A1B" fill-rule="evenodd" points="6.852 7.649 .399 1.195 1.445 .149 7.899 6.602 14.352 .149 15.399 1.195 8.945 7.649 15.399 14.102 14.352 15.149 7.899 8.695 1.445 15.149 .399 14.102"/> </svg>', 'ellipsis' => '<svg xmlns="http://www.w3.org/2000/svg" width="26" height="7" viewBox="0 0 26 7"> <path fill-rule="evenodd" d="M332.5,45 C330.567003,45 329,43.4329966 329,41.5 C329,39.5670034 330.567003,38 332.5,38 C334.432997,38 336,39.5670034 336,41.5 C336,43.4329966 334.432997,45 332.5,45 Z M342,45 C340.067003,45 338.5,43.4329966 338.5,41.5 C338.5,39.5670034 340.067003,38 342,38 C343.932997,38 345.5,39.5670034 345.5,41.5 C345.5,43.4329966 343.932997,45 342,45 Z M351.5,45 C349.567003,45 348,43.4329966 348,41.5 C348,39.5670034 349.567003,38 351.5,38 C353.432997,38 355,39.5670034 355,41.5 C355,43.4329966 353.432997,45 351.5,45 Z" transform="translate(-329 -38)"/> </svg>', 'edit' => '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18"> <path fill="#1A1A1B" d="M14.7272727,11.1763636 C14.7272727,10.7244943 15.0935852,10.3581818 15.5454545,10.3581818 C15.9973239,10.3581818 16.3636364,10.7244943 16.3636364,11.1763636 L16.3636364,15.5454545 C16.3636364,16.9010626 15.2646989,18 13.9090909,18 L2.45454545,18 C1.09893743,18 0,16.9010626 0,15.5454545 L0,4.09090909 C0,2.73530107 1.09893743,1.63636364 2.45454545,1.63636364 L6.82363636,1.63636364 C7.2755057,1.63636364 7.64181818,2.00267611 7.64181818,2.45454545 C7.64181818,2.9064148 7.2755057,3.27272727 6.82363636,3.27272727 L2.45454545,3.27272727 C2.00267611,3.27272727 1.63636364,3.63903975 1.63636364,4.09090909 L1.63636364,15.5454545 C1.63636364,15.9973239 2.00267611,16.3636364 2.45454545,16.3636364 L13.9090909,16.3636364 C14.3609602,16.3636364 14.7272727,15.9973239 14.7272727,15.5454545 L14.7272727,11.1763636 Z M6.54545455,9.33890201 L6.54545455,11.4545455 L8.66109799,11.4545455 L16.0247344,4.09090909 L13.9090909,1.97526564 L6.54545455,9.33890201 Z M14.4876328,0.239639906 L17.7603601,3.51236718 C18.07988,3.83188705 18.07988,4.34993113 17.7603601,4.669451 L9.57854191,12.8512692 C9.42510306,13.004708 9.21699531,13.0909091 9,13.0909091 L5.72727273,13.0909091 C5.27540339,13.0909091 4.90909091,12.7245966 4.90909091,12.2727273 L4.90909091,9 C4.90909091,8.78300469 4.99529196,8.57489694 5.14873082,8.42145809 L13.330549,0.239639906 C13.6500689,-0.0798799688 14.1681129,-0.0798799688 14.4876328,0.239639906 Z"/> </svg>', 'folder' => '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="19" viewBox="0 0 20 19"> <path fill="#1A1A1B" d="M2.8,1.85 C2.275329,1.85 1.85,2.27532949 1.85,2.8 L1.85,15.4 C1.85,15.9246705 2.275329,16.35 2.8,16.35 L17.2,16.35 C17.724671,16.35 18.15,15.9246705 18.15,15.4 L18.15,5.5 C18.15,4.97532949 17.724671,4.55 17.2,4.55 L9.1,4.55 C8.8158,4.55 8.550403,4.40796403 8.392757,4.17149517 L6.845094,1.85 L2.8,1.85 Z M17.2,2.85 C18.663555,2.85 19.85,4.03644541 19.85,5.5 L19.85,15.4 C19.85,16.8635546 18.663555,18.05 17.2,18.05 L2.8,18.05 C1.336445,18.05 0.15,16.8635546 0.15,15.4 L0.15,2.8 C0.15,1.33644541 1.336445,0.15 2.8,0.15 L7.3,0.15 C7.5842,0.15 7.849597,0.292035965 8.007243,0.528504833 L9.554906,2.85 L17.2,2.85 Z"/> </svg>', 'link' => '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18"> <path d="M6.70846497,10.3082552 C6.43780491,9.94641406 6.5117218,9.43367048 6.87356298,9.16301045 C7.23540415,8.89235035 7.74814771,8.96626726 8.01880776,9.32810842 C8.5875786,10.0884893 9.45856383,10.5643487 10.4057058,10.6321812 C11.3528479,10.7000136 12.2827563,10.3531306 12.9541853,9.68145807 L15.3987642,7.23705399 C16.6390369,5.9529049 16.6212992,3.91168563 15.3588977,2.6492841 C14.0964962,1.38688258 12.0552769,1.36914494 10.77958,2.60113525 L9.37230725,4.00022615 C9.05185726,4.31881314 8.53381538,4.31730281 8.21522839,3.99685275 C7.89664141,3.67640269 7.89815174,3.15836082 8.21860184,2.83977385 L9.63432671,1.43240056 C11.5605503,-0.42800847 14.6223793,-0.401402004 16.5159816,1.49220028 C18.4095838,3.38580256 18.4361903,6.44763148 16.5658147,8.38399647 L14.1113741,10.838437 C13.1043877,11.8457885 11.7095252,12.366113 10.2888121,12.2643643 C8.86809903,12.1626156 7.56162126,11.4488264 6.70846497,10.3082552 Z M11.291535,7.6917448 C11.5621951,8.05358597 11.4882782,8.56632952 11.126437,8.83698955 C10.7645959,9.10764965 10.2518523,9.03373274 9.98119227,8.67189158 C9.4124214,7.91151075 8.54143617,7.43565129 7.59429414,7.36781884 C6.6471521,7.29998638 5.71724372,7.64686937 5.04581464,8.31854193 L2.60123581,10.762946 C1.36096312,12.0470951 1.37870076,14.0883144 2.64110228,15.3507159 C3.90350381,16.6131174 5.94472309,16.630855 7.21873082,15.400549 L8.61782171,14.0014581 C8.93734159,13.6819382 9.45538568,13.6819382 9.77490556,14.0014581 C10.0944254,14.320978 10.0944254,14.839022 9.77490556,15.1585419 L8.36567329,16.5675994 C6.43944966,18.4280085 3.37762074,18.401402 1.48401846,16.5077998 C-0.409583822,14.6141975 -0.436190288,11.5523685 1.43418536,9.61600353 L3.88862594,7.16156298 C4.89561225,6.15421151 6.29047483,5.63388702 7.71118789,5.7356357 C9.13190097,5.83738438 10.4383788,6.55117356 11.291535,7.6917448 Z"/> </svg>', 'search' => '<svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" viewBox="0 0 23 23"> <path d="M38.710696,48.0601792 L43,52.3494831 L41.3494831,54 L37.0601792,49.710696 C35.2632422,51.1481185 32.9839107,52.0076499 30.5038249,52.0076499 C24.7027226,52.0076499 20,47.3049272 20,41.5038249 C20,35.7027226 24.7027226,31 30.5038249,31 C36.3049272,31 41.0076499,35.7027226 41.0076499,41.5038249 C41.0076499,43.9839107 40.1481185,46.2632422 38.710696,48.0601792 Z M36.3875844,47.1716785 C37.8030221,45.7026647 38.6734666,43.7048964 38.6734666,41.5038249 C38.6734666,36.9918565 35.0157934,33.3341833 30.5038249,33.3341833 C25.9918565,33.3341833 22.3341833,36.9918565 22.3341833,41.5038249 C22.3341833,46.0157934 25.9918565,49.6734666 30.5038249,49.6734666 C32.7048964,49.6734666 34.7026647,48.8030221 36.1716785,47.3875844 C36.2023931,47.347638 36.2360451,47.3092237 36.2726343,47.2726343 C36.3092237,47.2360451 36.347638,47.2023931 36.3875844,47.1716785 Z" transform="translate(-20 -31)"/> </svg>', 'tag' => '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18"> <path fill="#1A1A1B" d="M15.4496399,8.42490555 L8.66109799,1.63636364 L1.63636364,1.63636364 L1.63636364,8.66081885 L8.42522727,15.44178 C8.57869221,15.5954158 8.78693789,15.6817418 9.00409091,15.6817418 C9.22124393,15.6817418 9.42948961,15.5954158 9.58327627,15.4414581 L15.4486339,9.57610048 C15.7651495,9.25692435 15.7649133,8.74206554 15.4496399,8.42490555 Z M16.6084423,10.7304545 L10.7406818,16.59822 C10.280287,17.0591273 9.65554997,17.3181054 9.00409091,17.3181054 C8.35263185,17.3181054 7.72789481,17.0591273 7.26815877,16.5988788 L0.239976954,9.57887876 C0.0863319284,9.4254126 0,9.21716044 0,9 L0,0.818181818 C0,0.366312477 0.366312477,0 0.818181818,0 L9,0 C9.21699531,0 9.42510306,0.0862010512 9.57854191,0.239639906 L16.6084423,7.26954545 C17.5601275,8.22691012 17.5601275,9.77308988 16.6084423,10.7304545 Z M5,6 C4.44771525,6 4,5.55228475 4,5 C4,4.44771525 4.44771525,4 5,4 C5.55228475,4 6,4.44771525 6,5 C6,5.55228475 5.55228475,6 5,6 Z"/> </svg>', 'user' => '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" viewBox="0 0 18 20"> <path fill="#1A1A1B" d="M18,19 C18,19.5522847 17.5522847,20 17,20 C16.4477153,20 16,19.5522847 16,19 L16,17 C16,15.3431458 14.6568542,14 13,14 L5,14 C3.34314575,14 2,15.3431458 2,17 L2,19 C2,19.5522847 1.55228475,20 1,20 C0.44771525,20 0,19.5522847 0,19 L0,17 C0,14.2385763 2.23857625,12 5,12 L13,12 C15.7614237,12 18,14.2385763 18,17 L18,19 Z M9,10 C6.23857625,10 4,7.76142375 4,5 C4,2.23857625 6.23857625,0 9,0 C11.7614237,0 14,2.23857625 14,5 C14,7.76142375 11.7614237,10 9,10 Z M9,8 C10.6568542,8 12,6.65685425 12,5 C12,3.34314575 10.6568542,2 9,2 C7.34314575,2 6,3.34314575 6,5 C6,6.65685425 7.34314575,8 9,8 Z"/> </svg>', ); /** * Social Icons – domain mappings. * * By default, each Icon ID is matched against a .com TLD. To override this behavior, * specify all the domains it covers (including the .com TLD too, if applicable). * * @var array */ public static $social_icons_map = array( 'amazon' => array( 'amazon.com', 'amazon.cn', 'amazon.in', 'amazon.fr', 'amazon.de', 'amazon.it', 'amazon.nl', 'amazon.es', 'amazon.co', 'amazon.ca', ), 'behance' => array( 'behance.net', ), 'codepen' => array( 'codepen.io', ), 'facebook' => array( 'facebook.com', 'fb.me', ), 'feed' => array( 'feed', ), 'google' => array( 'g.page', ), 'lastfm' => array( 'last.fm', ), 'mail' => array( 'mailto:', ), 'pocket' => array( 'getpocket.com', ), 'tiktok' => array( 'tiktok.com', ), 'twitch' => array( 'twitch.tv', ), 'wordpress' => array( 'wordpress.com', 'wordpress.org', ), ); /** * Social Icons – svg sources. * * @var array */ public static $social_icons = array( '500px' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M6.94026,15.1412c.00437.01213.108.29862.168.44064a6.55008,6.55008,0,1,0,6.03191-9.09557,6.68654,6.68654,0,0,0-2.58357.51467A8.53914,8.53914,0,0,0,8.21268,8.61344L8.209,8.61725V3.22948l9.0504-.00008c.32934-.0036.32934-.46353.32934-.61466s0-.61091-.33035-.61467L7.47248,2a.43.43,0,0,0-.43131.42692v7.58355c0,.24466.30476.42131.58793.4819.553.11812.68074-.05864.81617-.2457l.018-.02481A10.52673,10.52673,0,0,1,9.32258,9.258a5.35268,5.35268,0,1,1,7.58985,7.54976,5.417,5.417,0,0,1-3.80867,1.56365,5.17483,5.17483,0,0,1-2.69822-.74478l.00342-4.61111a2.79372,2.79372,0,0,1,.71372-1.78792,2.61611,2.61611,0,0,1,1.98282-.89477,2.75683,2.75683,0,0,1,1.95525.79477,2.66867,2.66867,0,0,1,.79656,1.909,2.724,2.724,0,0,1-2.75849,2.748,4.94651,4.94651,0,0,1-.86254-.13719c-.31234-.093-.44519.34058-.48892.48349-.16811.54966.08453.65862.13687.67489a3.75751,3.75751,0,0,0,1.25234.18375,3.94634,3.94634,0,1,0-2.82444-6.742,3.67478,3.67478,0,0,0-1.13028,2.584l-.00041.02323c-.0035.11667-.00579,2.881-.00644,3.78811l-.00407-.00451a6.18521,6.18521,0,0,1-1.0851-1.86092c-.10544-.27856-.34358-.22925-.66857-.12917-.14192.04372-.57386.17677-.47833.489Zm4.65165-1.08338a.51346.51346,0,0,0,.19513.31818l.02276.022a.52945.52945,0,0,0,.3517.18416.24242.24242,0,0,0,.16577-.0611c.05473-.05082.67382-.67812.73287-.738l.69041.68819a.28978.28978,0,0,0,.21437.11032.53239.53239,0,0,0,.35708-.19486c.29792-.30419.14885-.46821.07676-.54751l-.69954-.69975.72952-.73469c.16-.17311.01874-.35708-.12218-.498-.20461-.20461-.402-.25742-.52855-.14083l-.7254.72665-.73354-.73375a.20128.20128,0,0,0-.14179-.05695.54135.54135,0,0,0-.34379.19648c-.22561.22555-.274.38149-.15656.5059l.73374.7315-.72942.73072A.26589.26589,0,0,0,11.59191,14.05782Zm1.59866-9.915A8.86081,8.86081,0,0,0,9.854,4.776a.26169.26169,0,0,0-.16938.22759.92978.92978,0,0,0,.08619.42094c.05682.14524.20779.531.50006.41955a8.40969,8.40969,0,0,1,2.91968-.55484,7.87875,7.87875,0,0,1,3.086.62286,8.61817,8.61817,0,0,1,2.30562,1.49315.2781.2781,0,0,0,.18318.07586c.15529,0,.30425-.15253.43167-.29551.21268-.23861.35873-.4369.1492-.63538a8.50425,8.50425,0,0,0-2.62312-1.694A9.0177,9.0177,0,0,0,13.19058,4.14283ZM19.50945,18.6236h0a.93171.93171,0,0,0-.36642-.25406.26589.26589,0,0,0-.27613.06613l-.06943.06929A7.90606,7.90606,0,0,1,7.60639,18.505a7.57284,7.57284,0,0,1-1.696-2.51537,8.58715,8.58715,0,0,1-.5147-1.77754l-.00871-.04864c-.04939-.25873-.28755-.27684-.62981-.22448-.14234.02178-.5755.088-.53426.39969l.001.00712a9.08807,9.08807,0,0,0,15.406,4.99094c.00193-.00192.04753-.04718.0725-.07436C19.79425,19.16234,19.87422,18.98728,19.50945,18.6236Z"></path></svg>', 'amazon' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M13.582,8.182C11.934,8.367,9.78,8.49,8.238,9.166c-1.781,0.769-3.03,2.337-3.03,4.644 c0,2.953,1.86,4.429,4.253,4.429c2.02,0,3.125-0.477,4.685-2.065c0.516,0.747,0.685,1.109,1.629,1.894 c0.212,0.114,0.483,0.103,0.672-0.066l0.006,0.006c0.567-0.505,1.599-1.401,2.18-1.888c0.231-0.188,0.19-0.496,0.009-0.754 c-0.52-0.718-1.072-1.303-1.072-2.634V8.305c0-1.876,0.133-3.599-1.249-4.891C15.23,2.369,13.422,2,12.04,2 C9.336,2,6.318,3.01,5.686,6.351C5.618,6.706,5.877,6.893,6.109,6.945l2.754,0.298C9.121,7.23,9.308,6.977,9.357,6.72 c0.236-1.151,1.2-1.706,2.284-1.706c0.584,0,1.249,0.215,1.595,0.738c0.398,0.584,0.346,1.384,0.346,2.061V8.182z M13.049,14.088 c-0.451,0.8-1.169,1.291-1.967,1.291c-1.09,0-1.728-0.83-1.728-2.061c0-2.42,2.171-2.86,4.227-2.86v0.615 C13.582,12.181,13.608,13.104,13.049,14.088z M20.683,19.339C18.329,21.076,14.917,22,11.979,22c-4.118,0-7.826-1.522-10.632-4.057 c-0.22-0.199-0.024-0.471,0.241-0.317c3.027,1.762,6.771,2.823,10.639,2.823c2.608,0,5.476-0.541,8.115-1.66 C20.739,18.62,21.072,19.051,20.683,19.339z M21.336,21.043c-0.194,0.163-0.379,0.076-0.293-0.139 c0.284-0.71,0.92-2.298,0.619-2.684c-0.301-0.386-1.99-0.183-2.749-0.092c-0.23,0.027-0.266-0.173-0.059-0.319 c1.348-0.946,3.555-0.673,3.811-0.356C22.925,17.773,22.599,19.986,21.336,21.043z"></path></svg>', 'bandcamp' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M15.27 17.289 3 17.289 8.73 6.711 21 6.711 15.27 17.289"></path></svg>', 'behance' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M7.799,5.698c0.589,0,1.12,0.051,1.606,0.156c0.482,0.102,0.894,0.273,1.241,0.507c0.344,0.235,0.612,0.546,0.804,0.938 c0.188,0.387,0.281,0.871,0.281,1.443c0,0.619-0.141,1.137-0.421,1.551c-0.284,0.413-0.7,0.751-1.255,1.014 c0.756,0.218,1.317,0.601,1.689,1.146c0.374,0.549,0.557,1.205,0.557,1.975c0,0.623-0.12,1.161-0.359,1.612 c-0.241,0.457-0.569,0.828-0.973,1.114c-0.408,0.288-0.876,0.5-1.399,0.637C9.052,17.931,8.514,18,7.963,18H2V5.698H7.799 M7.449,10.668c0.481,0,0.878-0.114,1.192-0.345c0.311-0.228,0.463-0.603,0.463-1.119c0-0.286-0.051-0.523-0.152-0.707 C8.848,8.315,8.711,8.171,8.536,8.07C8.362,7.966,8.166,7.894,7.94,7.854c-0.224-0.044-0.457-0.06-0.697-0.06H4.709v2.874H7.449z M7.6,15.905c0.267,0,0.521-0.024,0.759-0.077c0.243-0.053,0.457-0.137,0.637-0.261c0.182-0.12,0.332-0.283,0.441-0.491 C9.547,14.87,9.6,14.602,9.6,14.278c0-0.633-0.18-1.084-0.533-1.357c-0.356-0.27-0.83-0.404-1.413-0.404H4.709v3.388L7.6,15.905z M16.162,15.864c0.367,0.358,0.897,0.538,1.583,0.538c0.493,0,0.92-0.125,1.277-0.374c0.354-0.248,0.571-0.514,0.654-0.79h2.155 c-0.347,1.072-0.872,1.838-1.589,2.299C19.534,18,18.67,18.23,17.662,18.23c-0.701,0-1.332-0.113-1.899-0.337 c-0.567-0.227-1.041-0.544-1.439-0.958c-0.389-0.415-0.689-0.907-0.904-1.484c-0.213-0.574-0.32-1.21-0.32-1.899 c0-0.666,0.11-1.288,0.329-1.863c0.222-0.577,0.529-1.075,0.933-1.492c0.406-0.42,0.885-0.751,1.444-0.994 c0.558-0.241,1.175-0.363,1.857-0.363c0.754,0,1.414,0.145,1.98,0.44c0.563,0.291,1.026,0.686,1.389,1.181 c0.363,0.493,0.622,1.057,0.783,1.69c0.16,0.632,0.217,1.292,0.171,1.983h-6.428C15.557,14.84,15.795,15.506,16.162,15.864 M18.973,11.184c-0.291-0.321-0.783-0.496-1.384-0.496c-0.39,0-0.714,0.066-0.973,0.2c-0.254,0.132-0.461,0.297-0.621,0.491 c-0.157,0.197-0.265,0.405-0.328,0.628c-0.063,0.217-0.101,0.413-0.111,0.587h3.98C19.478,11.969,19.265,11.509,18.973,11.184z M15.057,7.738h4.985V6.524h-4.985L15.057,7.738z"></path></svg>', 'codepen' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22.016,8.84c-0.002-0.013-0.005-0.025-0.007-0.037c-0.005-0.025-0.008-0.048-0.015-0.072 c-0.003-0.015-0.01-0.028-0.013-0.042c-0.008-0.02-0.015-0.04-0.023-0.062c-0.007-0.015-0.013-0.028-0.02-0.042 c-0.008-0.02-0.018-0.037-0.03-0.057c-0.007-0.013-0.017-0.027-0.025-0.038c-0.012-0.018-0.023-0.035-0.035-0.052 c-0.01-0.013-0.02-0.025-0.03-0.037c-0.015-0.017-0.028-0.032-0.043-0.045c-0.01-0.012-0.022-0.023-0.035-0.035 c-0.015-0.015-0.032-0.028-0.048-0.04c-0.012-0.01-0.025-0.02-0.037-0.03c-0.005-0.003-0.01-0.008-0.015-0.012l-9.161-6.096 c-0.289-0.192-0.666-0.192-0.955,0L2.359,8.237C2.354,8.24,2.349,8.245,2.344,8.249L2.306,8.277 c-0.017,0.013-0.033,0.027-0.048,0.04C2.246,8.331,2.234,8.342,2.222,8.352c-0.015,0.015-0.028,0.03-0.042,0.047 c-0.012,0.013-0.022,0.023-0.03,0.037C2.139,8.453,2.125,8.471,2.115,8.488C2.107,8.501,2.099,8.514,2.09,8.526 C2.079,8.548,2.069,8.565,2.06,8.585C2.054,8.6,2.047,8.613,2.04,8.626C2.032,8.648,2.025,8.67,2.019,8.69 c-0.005,0.013-0.01,0.027-0.013,0.042C1.999,8.755,1.995,8.778,1.99,8.803C1.989,8.817,1.985,8.828,1.984,8.84 C1.978,8.879,1.975,8.915,1.975,8.954v6.093c0,0.037,0.003,0.075,0.008,0.112c0.002,0.012,0.005,0.025,0.007,0.038 c0.005,0.023,0.008,0.047,0.015,0.072c0.003,0.015,0.008,0.028,0.013,0.04c0.007,0.022,0.013,0.042,0.022,0.063 c0.007,0.015,0.013,0.028,0.02,0.04c0.008,0.02,0.018,0.038,0.03,0.058c0.007,0.013,0.015,0.027,0.025,0.038 c0.012,0.018,0.023,0.035,0.035,0.052c0.01,0.013,0.02,0.025,0.03,0.037c0.013,0.015,0.028,0.032,0.042,0.045 c0.012,0.012,0.023,0.023,0.035,0.035c0.015,0.013,0.032,0.028,0.048,0.04l0.038,0.03c0.005,0.003,0.01,0.007,0.013,0.01 l9.163,6.095C11.668,21.953,11.833,22,12,22c0.167,0,0.332-0.047,0.478-0.144l9.163-6.095l0.015-0.01 c0.013-0.01,0.027-0.02,0.037-0.03c0.018-0.013,0.035-0.028,0.048-0.04c0.013-0.012,0.025-0.023,0.035-0.035 c0.017-0.015,0.03-0.032,0.043-0.045c0.01-0.013,0.02-0.025,0.03-0.037c0.013-0.018,0.025-0.035,0.035-0.052 c0.008-0.013,0.018-0.027,0.025-0.038c0.012-0.02,0.022-0.038,0.03-0.058c0.007-0.013,0.013-0.027,0.02-0.04 c0.008-0.022,0.015-0.042,0.023-0.063c0.003-0.013,0.01-0.027,0.013-0.04c0.007-0.025,0.01-0.048,0.015-0.072 c0.002-0.013,0.005-0.027,0.007-0.037c0.003-0.042,0.007-0.079,0.007-0.117V8.954C22.025,8.915,22.022,8.879,22.016,8.84z M12.862,4.464l6.751,4.49l-3.016,2.013l-3.735-2.492V4.464z M11.138,4.464v4.009l-3.735,2.494L4.389,8.954L11.138,4.464z M3.699,10.562L5.853,12l-2.155,1.438V10.562z M11.138,19.536l-6.749-4.491l3.015-2.011l3.735,2.492V19.536z M12,14.035L8.953,12 L12,9.966L15.047,12L12,14.035z M12.862,19.536v-4.009l3.735-2.492l3.016,2.011L12.862,19.536z M20.303,13.438L18.147,12 l2.156-1.438L20.303,13.438z"></path></svg>', 'deviantart' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M 18.19 5.636 18.19 2 18.188 2 14.553 2 14.19 2.366 12.474 5.636 11.935 6 5.81 6 5.81 10.994 9.177 10.994 9.477 11.357 5.81 18.363 5.81 22 5.811 22 9.447 22 9.81 21.634 11.526 18.364 12.065 18 18.19 18 18.19 13.006 14.823 13.006 14.523 12.641 18.19 5.636z"></path></svg>', 'dribbble' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,22C6.486,22,2,17.514,2,12S6.486,2,12,2c5.514,0,10,4.486,10,10S17.514,22,12,22z M20.434,13.369 c-0.292-0.092-2.644-0.794-5.32-0.365c1.117,3.07,1.572,5.57,1.659,6.09C18.689,17.798,20.053,15.745,20.434,13.369z M15.336,19.876c-0.127-0.749-0.623-3.361-1.822-6.477c-0.019,0.006-0.038,0.013-0.056,0.019c-4.818,1.679-6.547,5.02-6.701,5.334 c1.448,1.129,3.268,1.803,5.243,1.803C13.183,20.555,14.311,20.313,15.336,19.876z M5.654,17.724 c0.193-0.331,2.538-4.213,6.943-5.637c0.111-0.036,0.224-0.07,0.337-0.102c-0.214-0.485-0.448-0.971-0.692-1.45 c-4.266,1.277-8.405,1.223-8.778,1.216c-0.003,0.087-0.004,0.174-0.004,0.261C3.458,14.207,4.29,16.21,5.654,17.724z M3.639,10.264 c0.382,0.005,3.901,0.02,7.897-1.041c-1.415-2.516-2.942-4.631-3.167-4.94C5.979,5.41,4.193,7.613,3.639,10.264z M9.998,3.709 c0.236,0.316,1.787,2.429,3.187,5c3.037-1.138,4.323-2.867,4.477-3.085C16.154,4.286,14.17,3.471,12,3.471 C11.311,3.471,10.641,3.554,9.998,3.709z M18.612,6.612C18.432,6.855,17,8.69,13.842,9.979c0.199,0.407,0.389,0.821,0.567,1.237 c0.063,0.148,0.124,0.295,0.184,0.441c2.842-0.357,5.666,0.215,5.948,0.275C20.522,9.916,19.801,8.065,18.612,6.612z"></path></svg>', 'dropbox' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,6.134L6.069,9.797L2,6.54l5.883-3.843L12,6.134z M2,13.054l5.883,3.843L12,13.459L6.069,9.797L2,13.054z M12,13.459 l4.116,3.439L22,13.054l-4.069-3.257L12,13.459z M22,6.54l-5.884-3.843L12,6.134l5.931,3.663L22,6.54z M12.011,14.2l-4.129,3.426 l-1.767-1.153v1.291l5.896,3.539l5.897-3.539v-1.291l-1.769,1.153L12.011,14.2z"></path></svg>', 'etsy' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M9.16033,4.038c0-.27174.02717-.43478.48913-.43478h6.22283c1.087,0,1.68478.92391,2.11957,2.663l.35326,1.38587h1.05978C19.59511,3.712,19.75815,2,19.75815,2s-2.663.29891-4.23913.29891h-7.962L3.29076,2.163v1.1413L4.731,3.57609c1.00543.19022,1.25.40761,1.33152,1.33152,0,0,.08152,2.71739.08152,7.20109s-.08152,7.17391-.08152,7.17391c0,.81522-.32609,1.11413-1.33152,1.30435l-1.44022.27174V22l4.2663-.13587h7.11957c1.60326,0,5.32609.13587,5.32609.13587.08152-.97826.625-5.40761.70652-5.89674H19.7038L18.644,18.52174c-.84239,1.90217-2.06522,2.038-3.42391,2.038H11.1712c-1.3587,0-2.01087-.54348-2.01087-1.712V12.65217s3.0163,0,3.99457.08152c.76087.05435,1.22283.27174,1.46739,1.33152l.32609,1.413h1.16848l-.08152-3.55978.163-3.587H15.02989l-.38043,1.57609c-.24457,1.03261-.40761,1.22283-1.46739,1.33152-1.38587.13587-4.02174.1087-4.02174.1087Z"></path></svg>', 'facebook' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg>', 'feed' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M2,8.667V12c5.515,0,10,4.485,10,10h3.333C15.333,14.637,9.363,8.667,2,8.667z M2,2v3.333 c9.19,0,16.667,7.477,16.667,16.667H22C22,10.955,13.045,2,2,2z M4.5,17C3.118,17,2,18.12,2,19.5S3.118,22,4.5,22S7,20.88,7,19.5 S5.882,17,4.5,17z"></path></svg>', 'flickr' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M6.5,7c-2.75,0-5,2.25-5,5s2.25,5,5,5s5-2.25,5-5S9.25,7,6.5,7z M17.5,7c-2.75,0-5,2.25-5,5s2.25,5,5,5s5-2.25,5-5 S20.25,7,17.5,7z"></path></svg>', 'foursquare' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M17.573,2c0,0-9.197,0-10.668,0S5,3.107,5,3.805s0,16.948,0,16.948c0,0.785,0.422,1.077,0.66,1.172 c0.238,0.097,0.892,0.177,1.285-0.275c0,0,5.035-5.843,5.122-5.93c0.132-0.132,0.132-0.132,0.262-0.132h3.26 c1.368,0,1.588-0.977,1.732-1.552c0.078-0.318,0.692-3.428,1.225-6.122l0.675-3.368C19.56,2.893,19.14,2,17.573,2z M16.495,7.22 c-0.053,0.252-0.372,0.518-0.665,0.518c-0.293,0-4.157,0-4.157,0c-0.467,0-0.802,0.318-0.802,0.787v0.508 c0,0.467,0.337,0.798,0.805,0.798c0,0,3.197,0,3.528,0s0.655,0.362,0.583,0.715c-0.072,0.353-0.407,2.102-0.448,2.295 c-0.04,0.193-0.262,0.523-0.655,0.523c-0.33,0-2.88,0-2.88,0c-0.523,0-0.683,0.068-1.033,0.503 c-0.35,0.437-3.505,4.223-3.505,4.223c-0.032,0.035-0.063,0.027-0.063-0.015V4.852c0-0.298,0.26-0.648,0.648-0.648 c0,0,8.228,0,8.562,0c0.315,0,0.61,0.297,0.528,0.683L16.495,7.22z"></path></svg>', 'goodreads' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M17.3,17.5c-0.2,0.8-0.5,1.4-1,1.9c-0.4,0.5-1,0.9-1.7,1.2C13.9,20.9,13.1,21,12,21c-0.6,0-1.3-0.1-1.9-0.2 c-0.6-0.1-1.1-0.4-1.6-0.7c-0.5-0.3-0.9-0.7-1.2-1.2c-0.3-0.5-0.5-1.1-0.5-1.7h1.5c0.1,0.5,0.2,0.9,0.5,1.2 c0.2,0.3,0.5,0.6,0.9,0.8c0.3,0.2,0.7,0.3,1.1,0.4c0.4,0.1,0.8,0.1,1.2,0.1c1.4,0,2.5-0.4,3.1-1.2c0.6-0.8,1-2,1-3.5v-1.7h0 c-0.4,0.8-0.9,1.4-1.6,1.9c-0.7,0.5-1.5,0.7-2.4,0.7c-1,0-1.9-0.2-2.6-0.5C8.7,15,8.1,14.5,7.7,14c-0.5-0.6-0.8-1.3-1-2.1 c-0.2-0.8-0.3-1.6-0.3-2.5c0-0.9,0.1-1.7,0.4-2.5c0.3-0.8,0.6-1.5,1.1-2c0.5-0.6,1.1-1,1.8-1.4C10.3,3.2,11.1,3,12,3 c0.5,0,0.9,0.1,1.3,0.2c0.4,0.1,0.8,0.3,1.1,0.5c0.3,0.2,0.6,0.5,0.9,0.8c0.3,0.3,0.5,0.6,0.6,1h0V3.4h1.5V15 C17.6,15.9,17.5,16.7,17.3,17.5z M13.8,14.1c0.5-0.3,0.9-0.7,1.3-1.1c0.3-0.5,0.6-1,0.8-1.6c0.2-0.6,0.3-1.2,0.3-1.9 c0-0.6-0.1-1.2-0.2-1.9c-0.1-0.6-0.4-1.2-0.7-1.7c-0.3-0.5-0.7-0.9-1.3-1.2c-0.5-0.3-1.1-0.5-1.9-0.5s-1.4,0.2-1.9,0.5 c-0.5,0.3-1,0.7-1.3,1.2C8.5,6.4,8.3,7,8.1,7.6C8,8.2,7.9,8.9,7.9,9.5c0,0.6,0.1,1.3,0.2,1.9C8.3,12,8.6,12.5,8.9,13 c0.3,0.5,0.8,0.8,1.3,1.1c0.5,0.3,1.1,0.4,1.9,0.4C12.7,14.5,13.3,14.4,13.8,14.1z"></path></svg>', 'google' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.02,10.18v3.72v0.01h5.51c-0.26,1.57-1.67,4.22-5.5,4.22c-3.31,0-6.01-2.75-6.01-6.12s2.7-6.12,6.01-6.12 c1.87,0,3.13,0.8,3.85,1.48l2.84-2.76C16.99,2.99,14.73,2,12.03,2c-5.52,0-10,4.48-10,10s4.48,10,10,10c5.77,0,9.6-4.06,9.6-9.77 c0-0.83-0.11-1.42-0.25-2.05H12.02z"></path></svg>', 'github' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg>', 'instagram' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,4.622c2.403,0,2.688,0.009,3.637,0.052c0.877,0.04,1.354,0.187,1.671,0.31c0.42,0.163,0.72,0.358,1.035,0.673 c0.315,0.315,0.51,0.615,0.673,1.035c0.123,0.317,0.27,0.794,0.31,1.671c0.043,0.949,0.052,1.234,0.052,3.637 s-0.009,2.688-0.052,3.637c-0.04,0.877-0.187,1.354-0.31,1.671c-0.163,0.42-0.358,0.72-0.673,1.035 c-0.315,0.315-0.615,0.51-1.035,0.673c-0.317,0.123-0.794,0.27-1.671,0.31c-0.949,0.043-1.233,0.052-3.637,0.052 s-2.688-0.009-3.637-0.052c-0.877-0.04-1.354-0.187-1.671-0.31c-0.42-0.163-0.72-0.358-1.035-0.673 c-0.315-0.315-0.51-0.615-0.673-1.035c-0.123-0.317-0.27-0.794-0.31-1.671C4.631,14.688,4.622,14.403,4.622,12 s0.009-2.688,0.052-3.637c0.04-0.877,0.187-1.354,0.31-1.671c0.163-0.42,0.358-0.72,0.673-1.035 c0.315-0.315,0.615-0.51,1.035-0.673c0.317-0.123,0.794-0.27,1.671-0.31C9.312,4.631,9.597,4.622,12,4.622 M12,3 C9.556,3,9.249,3.01,8.289,3.054C7.331,3.098,6.677,3.25,6.105,3.472C5.513,3.702,5.011,4.01,4.511,4.511 c-0.5,0.5-0.808,1.002-1.038,1.594C3.25,6.677,3.098,7.331,3.054,8.289C3.01,9.249,3,9.556,3,12c0,2.444,0.01,2.751,0.054,3.711 c0.044,0.958,0.196,1.612,0.418,2.185c0.23,0.592,0.538,1.094,1.038,1.594c0.5,0.5,1.002,0.808,1.594,1.038 c0.572,0.222,1.227,0.375,2.185,0.418C9.249,20.99,9.556,21,12,21s2.751-0.01,3.711-0.054c0.958-0.044,1.612-0.196,2.185-0.418 c0.592-0.23,1.094-0.538,1.594-1.038c0.5-0.5,0.808-1.002,1.038-1.594c0.222-0.572,0.375-1.227,0.418-2.185 C20.99,14.751,21,14.444,21,12s-0.01-2.751-0.054-3.711c-0.044-0.958-0.196-1.612-0.418-2.185c-0.23-0.592-0.538-1.094-1.038-1.594 c-0.5-0.5-1.002-0.808-1.594-1.038c-0.572-0.222-1.227-0.375-2.185-0.418C14.751,3.01,14.444,3,12,3L12,3z M12,7.378 c-2.552,0-4.622,2.069-4.622,4.622S9.448,16.622,12,16.622s4.622-2.069,4.622-4.622S14.552,7.378,12,7.378z M12,15 c-1.657,0-3-1.343-3-3s1.343-3,3-3s3,1.343,3,3S13.657,15,12,15z M16.804,6.116c-0.596,0-1.08,0.484-1.08,1.08 s0.484,1.08,1.08,1.08c0.596,0,1.08-0.484,1.08-1.08S17.401,6.116,16.804,6.116z"></path></svg>', 'lastfm' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M10.5002,0 C4.7006,0 0,4.70109753 0,10.4998496 C0,16.2989526 4.7006,21 10.5002,21 C16.299,21 21,16.2989526 21,10.4998496 C21,4.70109753 16.299,0 10.5002,0 Z M14.69735,14.7204413 C13.3164,14.7151781 12.4346,14.0870017 11.83445,12.6859357 L11.6816001,12.3451305 L10.35405,9.31011397 C9.92709997,8.26875064 8.85260001,7.57120012 7.68010001,7.57120012 C6.06945001,7.57120012 4.75925001,8.88509738 4.75925001,10.5009524 C4.75925001,12.1164565 6.06945001,13.4303036 7.68010001,13.4303036 C8.77200001,13.4303036 9.76514999,12.827541 10.2719501,11.8567047 C10.2893,11.8235214 10.3239,11.8019673 10.36305,11.8038219 C10.4007,11.8053759 10.43535,11.8287847 10.4504,11.8631709 L10.98655,13.1045863 C11.0016,13.1389726 10.9956,13.17782 10.97225,13.2068931 C10.1605001,14.1995341 8.96020001,14.7683115 7.68010001,14.7683115 C5.33305,14.7683115 3.42340001,12.8535563 3.42340001,10.5009524 C3.42340001,8.14679459 5.33300001,6.23203946 7.68010001,6.23203946 C9.45720002,6.23203946 10.8909,7.19074535 11.6138,8.86359341 C11.6205501,8.88018505 12.3412,10.5707777 12.97445,12.0190621 C13.34865,12.8739575 13.64615,13.3959676 14.6288,13.4291508 C15.5663001,13.4612814 16.25375,12.9121534 16.25375,12.1484869 C16.25375,11.4691321 15.8320501,11.3003585 14.8803,10.98216 C13.2365,10.4397989 12.34495,9.88605929 12.34495,8.51817658 C12.34495,7.1809207 13.26665,6.31615054 14.692,6.31615054 C15.62875,6.31615054 16.3155,6.7286858 16.79215,7.5768142 C16.80495,7.60062396 16.8079001,7.62814302 16.8004001,7.65420843 C16.7929,7.68027384 16.7748,7.70212868 16.7507001,7.713808 L15.86145,8.16900031 C15.8178001,8.19200805 15.7643,8.17807308 15.73565,8.13847371 C15.43295,7.71345711 15.0956,7.52513451 14.6423,7.52513451 C14.05125,7.52513451 13.6220001,7.92899802 13.6220001,8.48649708 C13.6220001,9.17382194 14.1529001,9.34144259 15.0339,9.61923972 C15.14915,9.65578139 15.26955,9.69397731 15.39385,9.73432853 C16.7763,10.1865133 17.57675,10.7311301 17.57675,12.1836251 C17.57685,13.629654 16.3389,14.7204413 14.69735,14.7204413 Z"></path></svg>', 'linkedin' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg>', 'mail' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M20,4H4C2.895,4,2,4.895,2,6v12c0,1.105,0.895,2,2,2h16c1.105,0,2-0.895,2-2V6C22,4.895,21.105,4,20,4z M20,8.236l-8,4.882 L4,8.236V6h16V8.236z"></path></svg>', 'mastodon' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M23.193 7.879c0-5.206-3.411-6.732-3.411-6.732C18.062.357 15.108.025 12.041 0h-.076c-3.068.025-6.02.357-7.74 1.147 0 0-3.411 1.526-3.411 6.732 0 1.192-.023 2.618.015 4.129.124 5.092.934 10.109 5.641 11.355 2.17.574 4.034.695 5.535.612 2.722-.15 4.25-.972 4.25-.972l-.09-1.975s-1.945.613-4.129.539c-2.165-.074-4.449-.233-4.799-2.891a5.499 5.499 0 0 1-.048-.745s2.125.52 4.817.643c1.646.075 3.19-.097 4.758-.283 3.007-.359 5.625-2.212 5.954-3.905.517-2.665.475-6.507.475-6.507zm-4.024 6.709h-2.497V8.469c0-1.29-.543-1.944-1.628-1.944-1.2 0-1.802.776-1.802 2.312v3.349h-2.483v-3.35c0-1.536-.602-2.312-1.802-2.312-1.085 0-1.628.655-1.628 1.944v6.119H4.832V8.284c0-1.289.328-2.313.987-3.07.68-.758 1.569-1.146 2.674-1.146 1.278 0 2.246.491 2.886 1.474L12 6.585l.622-1.043c.64-.983 1.608-1.474 2.886-1.474 1.104 0 1.994.388 2.674 1.146.658.757.986 1.781.986 3.07v6.304z"/></svg>', 'medium' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M20.962,7.257l-5.457,8.867l-3.923-6.375l3.126-5.08c0.112-0.182,0.319-0.286,0.527-0.286c0.05,0,0.1,0.008,0.149,0.02 c0.039,0.01,0.078,0.023,0.114,0.041l5.43,2.715l0.006,0.003c0.004,0.002,0.007,0.006,0.011,0.008 C20.971,7.191,20.98,7.227,20.962,7.257z M9.86,8.592v5.783l5.14,2.57L9.86,8.592z M15.772,17.331l4.231,2.115 C20.554,19.721,21,19.529,21,19.016V8.835L15.772,17.331z M8.968,7.178L3.665,4.527C3.569,4.479,3.478,4.456,3.395,4.456 C3.163,4.456,3,4.636,3,4.938v11.45c0,0.306,0.224,0.669,0.498,0.806l4.671,2.335c0.12,0.06,0.234,0.088,0.337,0.088 c0.29,0,0.494-0.225,0.494-0.602V7.231C9,7.208,8.988,7.188,8.968,7.178z"></path></svg>', 'meetup' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M19.24775,14.722a3.57032,3.57032,0,0,1-2.94457,3.52073,3.61886,3.61886,0,0,1-.64652.05634c-.07314-.0008-.10187.02846-.12507.09547A2.38881,2.38881,0,0,1,13.49453,20.094a2.33092,2.33092,0,0,1-1.827-.50716.13635.13635,0,0,0-.19878-.00408,3.191,3.191,0,0,1-2.104.60248,3.26309,3.26309,0,0,1-3.00324-2.71993,2.19076,2.19076,0,0,1-.03512-.30865c-.00156-.08579-.03413-.1189-.11608-.13493a2.86421,2.86421,0,0,1-1.23189-.56111,2.945,2.945,0,0,1-1.166-2.05749,2.97484,2.97484,0,0,1,.87524-2.50774.112.112,0,0,0,.02091-.16107,2.7213,2.7213,0,0,1-.36648-1.48A2.81256,2.81256,0,0,1,6.57673,7.58838a.35764.35764,0,0,0,.28869-.22819,4.2208,4.2208,0,0,1,6.02892-1.90111.25161.25161,0,0,0,.22023.0243,3.65608,3.65608,0,0,1,3.76031.90678A3.57244,3.57244,0,0,1,17.95918,8.626a2.97339,2.97339,0,0,1,.01829.57356.10637.10637,0,0,0,.0853.12792,1.97669,1.97669,0,0,1,1.27939,1.33733,2.00266,2.00266,0,0,1-.57112,2.12652c-.05284.05166-.04168.08328-.01173.13489A3.51189,3.51189,0,0,1,19.24775,14.722Zm-6.35959-.27836a1.6984,1.6984,0,0,0,1.14556,1.61113,3.82039,3.82039,0,0,0,1.036.17935,1.46888,1.46888,0,0,0,.73509-.12255.44082.44082,0,0,0,.26057-.44274.45312.45312,0,0,0-.29211-.43375.97191.97191,0,0,0-.20678-.063c-.21326-.03806-.42754-.0701-.63973-.11215a.54787.54787,0,0,1-.50172-.60926,2.75864,2.75864,0,0,1,.1773-.901c.1763-.535.414-1.045.64183-1.55913A12.686,12.686,0,0,0,15.85,10.47863a1.58461,1.58461,0,0,0,.04861-.87208,1.04531,1.04531,0,0,0-.85432-.83981,1.60658,1.60658,0,0,0-1.23654.16594.27593.27593,0,0,1-.36286-.03413c-.085-.0747-.16594-.15379-.24918-.23055a.98682.98682,0,0,0-1.33577-.04933,6.1468,6.1468,0,0,1-.4989.41615.47762.47762,0,0,1-.51535.03566c-.17448-.09307-.35512-.175-.53531-.25665a1.74949,1.74949,0,0,0-.56476-.2016,1.69943,1.69943,0,0,0-1.61654.91787,8.05815,8.05815,0,0,0-.32952.80126c-.45471,1.2557-.82507,2.53825-1.20838,3.81639a1.24151,1.24151,0,0,0,.51532,1.44389,1.42659,1.42659,0,0,0,1.22008.17166,1.09728,1.09728,0,0,0,.66994-.69764c.44145-1.04111.839-2.09989,1.25981-3.14926.11581-.28876.22792-.57874.35078-.86438a.44548.44548,0,0,1,.69189-.19539.50521.50521,0,0,1,.15044.43836,1.75625,1.75625,0,0,1-.14731.50453c-.27379.69219-.55265,1.38236-.82766,2.074a2.0836,2.0836,0,0,0-.14038.42876.50719.50719,0,0,0,.27082.57722.87236.87236,0,0,0,.66145.02739.99137.99137,0,0,0,.53406-.532q.61571-1.20914,1.228-2.42031.28423-.55863.57585-1.1133a.87189.87189,0,0,1,.29055-.35253.34987.34987,0,0,1,.37634-.01265.30291.30291,0,0,1,.12434.31459.56716.56716,0,0,1-.04655.1915c-.05318.12739-.10286.25669-.16183.38156-.34118.71775-.68754,1.43273-1.02568,2.152A2.00213,2.00213,0,0,0,12.88816,14.44366Zm4.78568,5.28972a.88573.88573,0,0,0-1.77139.00465.8857.8857,0,0,0,1.77139-.00465Zm-14.83838-7.296a.84329.84329,0,1,0,.00827-1.68655.8433.8433,0,0,0-.00827,1.68655Zm10.366-9.43673a.83506.83506,0,1,0-.0091,1.67.83505.83505,0,0,0,.0091-1.67Zm6.85014,5.22a.71651.71651,0,0,0-1.433.0093.71656.71656,0,0,0,1.433-.0093ZM5.37528,6.17908A.63823.63823,0,1,0,6.015,5.54483.62292.62292,0,0,0,5.37528,6.17908Zm6.68214,14.80843a.54949.54949,0,1,0-.55052.541A.54556.54556,0,0,0,12.05742,20.98752Zm8.53235-8.49689a.54777.54777,0,0,0-.54027.54023.53327.53327,0,0,0,.532.52293.51548.51548,0,0,0,.53272-.5237A.53187.53187,0,0,0,20.58977,12.49063ZM7.82846,2.4715a.44927.44927,0,1,0,.44484.44766A.43821.43821,0,0,0,7.82846,2.4715Zm13.775,7.60492a.41186.41186,0,0,0-.40065.39623.40178.40178,0,0,0,.40168.40168A.38994.38994,0,0,0,22,10.48172.39946.39946,0,0,0,21.60349,10.07642ZM5.79193,17.96207a.40469.40469,0,0,0-.397-.39646.399.399,0,0,0-.396.405.39234.39234,0,0,0,.39939.389A.39857.39857,0,0,0,5.79193,17.96207Z"></path></svg>', 'pinterest' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.289,2C6.617,2,3.606,5.648,3.606,9.622c0,1.846,1.025,4.146,2.666,4.878c0.25,0.111,0.381,0.063,0.439-0.169 c0.044-0.175,0.267-1.029,0.365-1.428c0.032-0.128,0.017-0.237-0.091-0.362C6.445,11.911,6.01,10.75,6.01,9.668 c0-2.777,2.194-5.464,5.933-5.464c3.23,0,5.49,2.108,5.49,5.122c0,3.407-1.794,5.768-4.13,5.768c-1.291,0-2.257-1.021-1.948-2.277 c0.372-1.495,1.089-3.112,1.089-4.191c0-0.967-0.542-1.775-1.663-1.775c-1.319,0-2.379,1.309-2.379,3.059 c0,1.115,0.394,1.869,0.394,1.869s-1.302,5.279-1.54,6.261c-0.405,1.666,0.053,4.368,0.094,4.604 c0.021,0.126,0.167,0.169,0.25,0.063c0.129-0.165,1.699-2.419,2.142-4.051c0.158-0.59,0.817-2.995,0.817-2.995 c0.43,0.784,1.681,1.446,3.013,1.446c3.963,0,6.822-3.494,6.822-7.833C20.394,5.112,16.849,2,12.289,2"></path></svg>', 'pocket' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M21.927,4.194C21.667,3.48,20.982,3,20.222,3h-0.01h-1.721H3.839C3.092,3,2.411,3.47,2.145,4.17 C2.066,4.378,2.026,4.594,2.026,4.814v6.035l0.069,1.2c0.29,2.73,1.707,5.115,3.899,6.778c0.039,0.03,0.079,0.059,0.119,0.089 l0.025,0.018c1.175,0.859,2.491,1.441,3.91,1.727c0.655,0.132,1.325,0.2,1.991,0.2c0.615,0,1.232-0.057,1.839-0.17 c0.073-0.014,0.145-0.028,0.219-0.044c0.02-0.004,0.042-0.012,0.064-0.023c1.359-0.297,2.621-0.864,3.753-1.691l0.025-0.018 c0.04-0.029,0.08-0.058,0.119-0.089c2.192-1.664,3.609-4.049,3.898-6.778l0.069-1.2V4.814C22.026,4.605,22,4.398,21.927,4.194z M17.692,10.481l-4.704,4.512c-0.266,0.254-0.608,0.382-0.949,0.382c-0.342,0-0.684-0.128-0.949-0.382l-4.705-4.512 C5.838,9.957,5.82,9.089,6.344,8.542c0.524-0.547,1.392-0.565,1.939-0.04l3.756,3.601l3.755-3.601 c0.547-0.524,1.415-0.506,1.939,0.04C18.256,9.089,18.238,9.956,17.692,10.481z"></path></svg>', 'reddit' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22,11.816c0-1.256-1.021-2.277-2.277-2.277c-0.593,0-1.122,0.24-1.526,0.614c-1.481-0.965-3.455-1.594-5.647-1.69 l1.171-3.702l3.18,0.748c0.008,1.028,0.846,1.862,1.876,1.862c1.035,0,1.877-0.842,1.877-1.878c0-1.035-0.842-1.877-1.877-1.877 c-0.769,0-1.431,0.466-1.72,1.13l-3.508-0.826c-0.203-0.047-0.399,0.067-0.46,0.261l-1.35,4.268 c-2.316,0.038-4.411,0.67-5.97,1.671C5.368,9.765,4.853,9.539,4.277,9.539C3.021,9.539,2,10.56,2,11.816 c0,0.814,0.433,1.523,1.078,1.925c-0.037,0.221-0.061,0.444-0.061,0.672c0,3.292,4.011,5.97,8.941,5.97s8.941-2.678,8.941-5.97 c0-0.214-0.02-0.424-0.053-0.632C21.533,13.39,22,12.661,22,11.816z M18.776,4.394c0.606,0,1.1,0.493,1.1,1.1s-0.493,1.1-1.1,1.1 s-1.1-0.494-1.1-1.1S18.169,4.394,18.776,4.394z M2.777,11.816c0-0.827,0.672-1.5,1.499-1.5c0.313,0,0.598,0.103,0.838,0.269 c-0.851,0.676-1.477,1.479-1.812,2.36C2.983,12.672,2.777,12.27,2.777,11.816z M11.959,19.606c-4.501,0-8.164-2.329-8.164-5.193 S7.457,9.22,11.959,9.22s8.164,2.329,8.164,5.193S16.46,19.606,11.959,19.606z M20.636,13.001c-0.326-0.89-0.948-1.701-1.797-2.384 c0.248-0.186,0.55-0.301,0.883-0.301c0.827,0,1.5,0.673,1.5,1.5C21.223,12.299,20.992,12.727,20.636,13.001z M8.996,14.704 c-0.76,0-1.397-0.616-1.397-1.376c0-0.76,0.637-1.397,1.397-1.397c0.76,0,1.376,0.637,1.376,1.397 C10.372,14.088,9.756,14.704,8.996,14.704z M16.401,13.328c0,0.76-0.616,1.376-1.376,1.376c-0.76,0-1.399-0.616-1.399-1.376 c0-0.76,0.639-1.397,1.399-1.397C15.785,11.931,16.401,12.568,16.401,13.328z M15.229,16.708c0.152,0.152,0.152,0.398,0,0.55 c-0.674,0.674-1.727,1.002-3.219,1.002c-0.004,0-0.007-0.002-0.011-0.002c-0.004,0-0.007,0.002-0.011,0.002 c-1.492,0-2.544-0.328-3.218-1.002c-0.152-0.152-0.152-0.398,0-0.55c0.152-0.152,0.399-0.151,0.55,0 c0.521,0.521,1.394,0.775,2.669,0.775c0.004,0,0.007,0.002,0.011,0.002c0.004,0,0.007-0.002,0.011-0.002 c1.275,0,2.148-0.253,2.669-0.775C14.831,16.556,15.078,16.556,15.229,16.708z"></path></svg>', 'skype' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M10.113,2.699c0.033-0.006,0.067-0.013,0.1-0.02c0.033,0.017,0.066,0.033,0.098,0.051L10.113,2.699z M2.72,10.223 c-0.006,0.034-0.011,0.069-0.017,0.103c0.018,0.032,0.033,0.064,0.051,0.095L2.72,10.223z M21.275,13.771 c0.007-0.035,0.011-0.071,0.018-0.106c-0.018-0.031-0.033-0.064-0.052-0.095L21.275,13.771z M13.563,21.199 c0.032,0.019,0.065,0.035,0.096,0.053c0.036-0.006,0.071-0.011,0.105-0.017L13.563,21.199z M22,16.386 c0,1.494-0.581,2.898-1.637,3.953c-1.056,1.057-2.459,1.637-3.953,1.637c-0.967,0-1.914-0.251-2.75-0.725 c0.036-0.006,0.071-0.011,0.105-0.017l-0.202-0.035c0.032,0.019,0.065,0.035,0.096,0.053c-0.543,0.096-1.099,0.147-1.654,0.147 c-1.275,0-2.512-0.25-3.676-0.743c-1.125-0.474-2.135-1.156-3.002-2.023c-0.867-0.867-1.548-1.877-2.023-3.002 c-0.493-1.164-0.743-2.401-0.743-3.676c0-0.546,0.049-1.093,0.142-1.628c0.018,0.032,0.033,0.064,0.051,0.095L2.72,10.223 c-0.006,0.034-0.011,0.069-0.017,0.103C2.244,9.5,2,8.566,2,7.615c0-1.493,0.582-2.898,1.637-3.953 c1.056-1.056,2.46-1.638,3.953-1.638c0.915,0,1.818,0.228,2.622,0.655c-0.033,0.007-0.067,0.013-0.1,0.02l0.199,0.031 c-0.032-0.018-0.066-0.034-0.098-0.051c0.002,0,0.003-0.001,0.004-0.001c0.586-0.112,1.187-0.169,1.788-0.169 c1.275,0,2.512,0.249,3.676,0.742c1.124,0.476,2.135,1.156,3.002,2.024c0.868,0.867,1.548,1.877,2.024,3.002 c0.493,1.164,0.743,2.401,0.743,3.676c0,0.575-0.054,1.15-0.157,1.712c-0.018-0.031-0.033-0.064-0.052-0.095l0.034,0.201 c0.007-0.035,0.011-0.071,0.018-0.106C21.754,14.494,22,15.432,22,16.386z M16.817,14.138c0-1.331-0.613-2.743-3.033-3.282 l-2.209-0.49c-0.84-0.192-1.807-0.444-1.807-1.237c0-0.794,0.679-1.348,1.903-1.348c2.468,0,2.243,1.696,3.468,1.696 c0.645,0,1.209-0.379,1.209-1.031c0-1.521-2.435-2.663-4.5-2.663c-2.242,0-4.63,0.952-4.63,3.488c0,1.221,0.436,2.521,2.839,3.123 l2.984,0.745c0.903,0.223,1.129,0.731,1.129,1.189c0,0.762-0.758,1.507-2.129,1.507c-2.679,0-2.307-2.062-3.743-2.062 c-0.645,0-1.113,0.444-1.113,1.078c0,1.236,1.501,2.886,4.856,2.886C15.236,17.737,16.817,16.199,16.817,14.138z"></path></svg>', 'snapchat' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.065,2a5.526,5.526,0,0,1,3.132.892A5.854,5.854,0,0,1,17.326,5.4a5.821,5.821,0,0,1,.351,2.33q0,.612-.117,2.487a.809.809,0,0,0,.365.091,1.93,1.93,0,0,0,.664-.176,1.93,1.93,0,0,1,.664-.176,1.3,1.3,0,0,1,.729.234.7.7,0,0,1,.351.6.839.839,0,0,1-.41.7,2.732,2.732,0,0,1-.9.41,3.192,3.192,0,0,0-.9.378.728.728,0,0,0-.41.618,1.575,1.575,0,0,0,.156.56,6.9,6.9,0,0,0,1.334,1.953,5.6,5.6,0,0,0,1.881,1.315,5.875,5.875,0,0,0,1.042.3.42.42,0,0,1,.365.456q0,.911-2.852,1.341a1.379,1.379,0,0,0-.143.507,1.8,1.8,0,0,1-.182.605.451.451,0,0,1-.429.241,5.878,5.878,0,0,1-.807-.085,5.917,5.917,0,0,0-.833-.085,4.217,4.217,0,0,0-.807.065,2.42,2.42,0,0,0-.82.293,6.682,6.682,0,0,0-.755.5q-.351.267-.755.527a3.886,3.886,0,0,1-.989.436A4.471,4.471,0,0,1,11.831,22a4.307,4.307,0,0,1-1.256-.176,3.784,3.784,0,0,1-.976-.436q-.4-.26-.749-.527a6.682,6.682,0,0,0-.755-.5,2.422,2.422,0,0,0-.807-.293,4.432,4.432,0,0,0-.82-.065,5.089,5.089,0,0,0-.853.1,5,5,0,0,1-.762.1.474.474,0,0,1-.456-.241,1.819,1.819,0,0,1-.182-.618,1.411,1.411,0,0,0-.143-.521q-2.852-.429-2.852-1.341a.42.42,0,0,1,.365-.456,5.793,5.793,0,0,0,1.042-.3,5.524,5.524,0,0,0,1.881-1.315,6.789,6.789,0,0,0,1.334-1.953A1.575,1.575,0,0,0,6,12.9a.728.728,0,0,0-.41-.618,3.323,3.323,0,0,0-.9-.384,2.912,2.912,0,0,1-.9-.41.814.814,0,0,1-.41-.684.71.71,0,0,1,.338-.593,1.208,1.208,0,0,1,.716-.241,1.976,1.976,0,0,1,.625.169,2.008,2.008,0,0,0,.69.169.919.919,0,0,0,.416-.091q-.117-1.849-.117-2.474A5.861,5.861,0,0,1,6.385,5.4,5.516,5.516,0,0,1,8.625,2.819,7.075,7.075,0,0,1,12.062,2Z"></path></svg>', 'soundcloud' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M8.9,16.1L9,14L8.9,9.5c0-0.1,0-0.1-0.1-0.1c0,0-0.1-0.1-0.1-0.1c-0.1,0-0.1,0-0.1,0.1c0,0-0.1,0.1-0.1,0.1L8.3,14l0.1,2.1 c0,0.1,0,0.1,0.1,0.1c0,0,0.1,0.1,0.1,0.1C8.8,16.3,8.9,16.3,8.9,16.1z M11.4,15.9l0.1-1.8L11.4,9c0-0.1,0-0.2-0.1-0.2 c0,0-0.1,0-0.1,0s-0.1,0-0.1,0c-0.1,0-0.1,0.1-0.1,0.2l0,0.1l-0.1,5c0,0,0,0.7,0.1,2v0c0,0.1,0,0.1,0.1,0.1c0.1,0.1,0.1,0.1,0.2,0.1 c0.1,0,0.1,0,0.2-0.1c0.1,0,0.1-0.1,0.1-0.2L11.4,15.9z M2.4,12.9L2.5,14l-0.2,1.1c0,0.1,0,0.1-0.1,0.1c0,0-0.1,0-0.1-0.1L2.1,14 l0.1-1.1C2.2,12.9,2.3,12.9,2.4,12.9C2.3,12.9,2.4,12.9,2.4,12.9z M3.1,12.2L3.3,14l-0.2,1.8c0,0.1,0,0.1-0.1,0.1 c-0.1,0-0.1,0-0.1-0.1L2.8,14L3,12.2C3,12.2,3,12.2,3.1,12.2C3.1,12.2,3.1,12.2,3.1,12.2z M3.9,11.9L4.1,14l-0.2,2.1 c0,0.1,0,0.1-0.1,0.1c-0.1,0-0.1,0-0.1-0.1L3.5,14l0.2-2.1c0-0.1,0-0.1,0.1-0.1C3.9,11.8,3.9,11.8,3.9,11.9z M4.7,11.9L4.9,14 l-0.2,2.1c0,0.1-0.1,0.1-0.1,0.1c-0.1,0-0.1,0-0.1-0.1L4.3,14l0.2-2.2c0-0.1,0-0.1,0.1-0.1C4.7,11.7,4.7,11.8,4.7,11.9z M5.6,12 l0.2,2l-0.2,2.1c0,0.1-0.1,0.1-0.1,0.1c0,0-0.1,0-0.1,0c0,0,0-0.1,0-0.1L5.1,14l0.2-2c0,0,0-0.1,0-0.1s0.1,0,0.1,0 C5.5,11.9,5.5,11.9,5.6,12L5.6,12z M6.4,10.7L6.6,14l-0.2,2.1c0,0,0,0.1,0,0.1c0,0-0.1,0-0.1,0c-0.1,0-0.1-0.1-0.2-0.2L5.9,14 l0.2-3.3c0-0.1,0.1-0.2,0.2-0.2c0,0,0.1,0,0.1,0C6.4,10.7,6.4,10.7,6.4,10.7z M7.2,10l0.2,4.1l-0.2,2.1c0,0,0,0.1,0,0.1 c0,0-0.1,0-0.1,0c-0.1,0-0.2-0.1-0.2-0.2l-0.1-2.1L6.8,10c0-0.1,0.1-0.2,0.2-0.2c0,0,0.1,0,0.1,0S7.2,9.9,7.2,10z M8,9.6L8.2,14 L8,16.1c0,0.1-0.1,0.2-0.2,0.2c-0.1,0-0.2-0.1-0.2-0.2L7.5,14l0.1-4.4c0-0.1,0-0.1,0.1-0.1c0,0,0.1-0.1,0.1-0.1c0.1,0,0.1,0,0.1,0.1 C8,9.6,8,9.6,8,9.6z M11.4,16.1L11.4,16.1L11.4,16.1z M9.7,9.6L9.8,14l-0.1,2.1c0,0.1,0,0.1-0.1,0.2s-0.1,0.1-0.2,0.1 c-0.1,0-0.1,0-0.1-0.1s-0.1-0.1-0.1-0.2L9.2,14l0.1-4.4c0-0.1,0-0.1,0.1-0.2s0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.2,0.1S9.7,9.5,9.7,9.6 L9.7,9.6z M10.6,9.8l0.1,4.3l-0.1,2c0,0.1,0,0.1-0.1,0.2c0,0-0.1,0.1-0.2,0.1c-0.1,0-0.1,0-0.2-0.1c0,0-0.1-0.1-0.1-0.2L10,14 l0.1-4.3c0-0.1,0-0.1,0.1-0.2c0,0,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.2,0.1S10.6,9.7,10.6,9.8z M12.4,14l-0.1,2c0,0.1,0,0.1-0.1,0.2 c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0-0.1,0-0.2-0.1c-0.1-0.1-0.1-0.1-0.1-0.2l-0.1-1l-0.1-1l0.1-5.5v0c0-0.1,0-0.2,0.1-0.2 c0.1,0,0.1-0.1,0.2-0.1c0,0,0.1,0,0.1,0c0.1,0,0.1,0.1,0.1,0.2L12.4,14z M22.1,13.9c0,0.7-0.2,1.3-0.7,1.7c-0.5,0.5-1.1,0.7-1.7,0.7 h-6.8c-0.1,0-0.1,0-0.2-0.1c-0.1-0.1-0.1-0.1-0.1-0.2V8.2c0-0.1,0.1-0.2,0.2-0.3c0.5-0.2,1-0.3,1.6-0.3c1.1,0,2.1,0.4,2.9,1.1 c0.8,0.8,1.3,1.7,1.4,2.8c0.3-0.1,0.6-0.2,1-0.2c0.7,0,1.3,0.2,1.7,0.7C21.8,12.6,22.1,13.2,22.1,13.9L22.1,13.9z"></path></svg>', 'spotify' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,2C6.477,2,2,6.477,2,12c0,5.523,4.477,10,10,10c5.523,0,10-4.477,10-10C22,6.477,17.523,2,12,2 M16.586,16.424 c-0.18,0.295-0.563,0.387-0.857,0.207c-2.348-1.435-5.304-1.76-8.785-0.964c-0.335,0.077-0.67-0.133-0.746-0.469 c-0.077-0.335,0.132-0.67,0.469-0.746c3.809-0.871,7.077-0.496,9.713,1.115C16.673,15.746,16.766,16.13,16.586,16.424 M17.81,13.7 c-0.226,0.367-0.706,0.482-1.072,0.257c-2.687-1.652-6.785-2.131-9.965-1.166C6.36,12.917,5.925,12.684,5.8,12.273 C5.675,11.86,5.908,11.425,6.32,11.3c3.632-1.102,8.147-0.568,11.234,1.328C17.92,12.854,18.035,13.335,17.81,13.7 M17.915,10.865 c-3.223-1.914-8.54-2.09-11.618-1.156C5.804,9.859,5.281,9.58,5.131,9.086C4.982,8.591,5.26,8.069,5.755,7.919 c3.532-1.072,9.404-0.865,13.115,1.338c0.445,0.264,0.59,0.838,0.327,1.282C18.933,10.983,18.359,11.129,17.915,10.865"></path></svg>', 'tumblr' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M16.749,17.396c-0.357,0.17-1.041,0.319-1.551,0.332c-1.539,0.041-1.837-1.081-1.85-1.896V9.847h3.861V6.937h-3.847V2.039 c0,0-2.77,0-2.817,0c-0.046,0-0.127,0.041-0.138,0.144c-0.165,1.499-0.867,4.13-3.783,5.181v2.484h1.945v6.282 c0,2.151,1.587,5.206,5.775,5.135c1.413-0.024,2.982-0.616,3.329-1.126L16.749,17.396z"></path></svg>', 'tiktok' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22.601273,3.99398422 C22.3543419,3.81786432 22.035286,3.77722295 21.7519316,3.88579503 C20.7673827,4.3053476 19.6367473,4.19781761 18.749359,3.60023293 C17.8619707,3.00264826 17.3390468,1.99663905 17.3606558,0.92862387 C17.366873,0.687165991 17.2757319,0.453316101 17.1076605,0.279488738 C16.937965,0.101864383 16.7030375,0.000936521363 16.4571011,0 L12.8428824,0 C12.343863,0 11.9393277,0.403649581 11.9393277,0.901576573 L11.9393277,16.3365675 C11.9393277,17.581385 10.9279897,18.5905089 9.68044104,18.5905089 C8.43289237,18.5905089 7.42155434,17.581385 7.42155434,16.3365675 C7.42155434,15.09175 8.43289237,14.0826261 9.68044104,14.0826261 C10.1794605,14.0826261 10.5839957,13.6789765 10.5839957,13.1810495 L10.5839957,9.57474321 C10.5839957,9.07681622 10.1794605,8.67316663 9.68044104,8.67316663 C5.44083962,8.67813472 2.00520525,12.1062476 2.00022626,16.3365675 C1.98771579,17.9546233 2.49430163,19.5342383 3.44591375,20.8444504 C3.61458557,21.0808398 5.05966461,19.9481604 4.91870788,19.7535427 C4.19555103,18.760421 3.80646351,17.5641499 3.80733562,16.3365675 C3.81165144,13.4484211 5.91803869,10.991254 8.77688636,10.5394301 L8.77688636,12.3425833 C6.70706914,12.8134053 5.34862709,14.7938709 5.65804701,16.8895228 C5.96746693,18.9851748 7.84059425,20.4905907 9.95854931,20.3457987 C12.0765044,20.2010067 13.7263573,18.4547454 13.7464371,16.3365675 L13.7464371,1.80315315 L15.6167953,1.80315315 C16.0103639,4.20249558 18.0864975,5.96506252 20.5230972,5.96843692 C20.7496837,5.96688212 20.975975,5.95182905 21.2007632,5.92335809 L21.2007632,7.67241664 C19.7293748,7.92650626 18.2152284,7.66195137 16.917914,6.92410808 C16.6383532,6.76305694 16.2939201,6.76305694 16.0143593,6.92410808 C15.7336844,7.0857977 15.5612953,7.38509793 15.562582,7.7084797 L15.562582,16.3365675 C15.5580692,18.2941869 14.5756972,20.1206948 12.9432814,21.2065896 C11.9060301,21.8965766 10.6930991,22.229824 9.48148608,22.189012 C8.78627447,22.1655944 8.08246121,22.0477035 7.42155434,21.774707 C7.12504167,21.5395062 5.484375,20.8444504 4.91870788,19.7535427 C4.66351437,19.2613936 3.0238563,20.6306805 3.44591375,20.8444504 C4.91870788,23.1351563 7.99726562,23.9999684 9.69851213,23.9999684 C13.7074483,23.9999684 17.0406982,20.9190082 17.3606558,16.931608 C17.3657425,16.8836579 17.3657425,16.8353059 17.3606558,16.7873558 L17.3606558,9.10592339 C18.9684136,9.66657941 20.7106733,9.71696914 22.3482777,9.25017564 C22.7469793,9.13449784 23.0153499,8.76257691 22.998837,8.34859907 L22.998837,4.7873716 C23.0148813,4.47165088 22.8640303,4.17060935 22.601273,3.99398422 Z" /></svg>', 'twitch' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M16.499,8.089h-1.636v4.91h1.636V8.089z M12,8.089h-1.637v4.91H12V8.089z M4.228,3.178L3,6.451v13.092h4.499V22h2.456 l2.454-2.456h3.681L21,14.636V3.178H4.228z M19.364,13.816l-2.864,2.865H12l-2.453,2.453V16.68H5.863V4.814h13.501V13.816z"></path></svg>', 'twitter' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22.23,5.924c-0.736,0.326-1.527,0.547-2.357,0.646c0.847-0.508,1.498-1.312,1.804-2.27 c-0.793,0.47-1.671,0.812-2.606,0.996C18.324,4.498,17.257,4,16.077,4c-2.266,0-4.103,1.837-4.103,4.103 c0,0.322,0.036,0.635,0.106,0.935C8.67,8.867,5.647,7.234,3.623,4.751C3.27,5.357,3.067,6.062,3.067,6.814 c0,1.424,0.724,2.679,1.825,3.415c-0.673-0.021-1.305-0.206-1.859-0.513c0,0.017,0,0.034,0,0.052c0,1.988,1.414,3.647,3.292,4.023 c-0.344,0.094-0.707,0.144-1.081,0.144c-0.264,0-0.521-0.026-0.772-0.074c0.522,1.63,2.038,2.816,3.833,2.85 c-1.404,1.1-3.174,1.756-5.096,1.756c-0.331,0-0.658-0.019-0.979-0.057c1.816,1.164,3.973,1.843,6.29,1.843 c7.547,0,11.675-6.252,11.675-11.675c0-0.178-0.004-0.355-0.012-0.531C20.985,7.47,21.68,6.747,22.23,5.924z"></path></svg>', 'vimeo' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22.396,7.164c-0.093,2.026-1.507,4.799-4.245,8.32C15.322,19.161,12.928,21,10.97,21c-1.214,0-2.24-1.119-3.079-3.359 c-0.56-2.053-1.119-4.106-1.68-6.159C5.588,9.243,4.921,8.122,4.206,8.122c-0.156,0-0.701,0.328-1.634,0.98L1.594,7.841 c1.027-0.902,2.04-1.805,3.037-2.708C6.001,3.95,7.03,3.327,7.715,3.264c1.619-0.156,2.616,0.951,2.99,3.321 c0.404,2.557,0.685,4.147,0.841,4.769c0.467,2.121,0.981,3.181,1.542,3.181c0.435,0,1.09-0.688,1.963-2.065 c0.871-1.376,1.338-2.422,1.401-3.142c0.125-1.187-0.343-1.782-1.401-1.782c-0.498,0-1.012,0.115-1.541,0.341 c1.023-3.35,2.977-4.977,5.862-4.884C21.511,3.066,22.52,4.453,22.396,7.164z"></path></svg>', 'vk' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22,7.1c0.2,0.4-0.4,1.5-1.6,3.1c-0.2,0.2-0.4,0.5-0.7,0.9c-0.5,0.7-0.9,1.1-0.9,1.4c-0.1,0.3-0.1,0.6,0.1,0.8 c0.1,0.1,0.4,0.4,0.8,0.9h0l0,0c1,0.9,1.6,1.7,2,2.3c0,0,0,0.1,0.1,0.1c0,0.1,0,0.1,0.1,0.3c0,0.1,0,0.2,0,0.4 c0,0.1-0.1,0.2-0.3,0.3c-0.1,0.1-0.4,0.1-0.6,0.1l-2.7,0c-0.2,0-0.4,0-0.6-0.1c-0.2-0.1-0.4-0.1-0.5-0.2l-0.2-0.1 c-0.2-0.1-0.5-0.4-0.7-0.7s-0.5-0.6-0.7-0.8c-0.2-0.2-0.4-0.4-0.6-0.6C14.8,15,14.6,15,14.4,15c0,0,0,0-0.1,0c0,0-0.1,0.1-0.2,0.2 c-0.1,0.1-0.2,0.2-0.2,0.3c-0.1,0.1-0.1,0.3-0.2,0.5c-0.1,0.2-0.1,0.5-0.1,0.8c0,0.1,0,0.2,0,0.3c0,0.1-0.1,0.2-0.1,0.2l0,0.1 c-0.1,0.1-0.3,0.2-0.6,0.2h-1.2c-0.5,0-1,0-1.5-0.2c-0.5-0.1-1-0.3-1.4-0.6s-0.7-0.5-1.1-0.7s-0.6-0.4-0.7-0.6l-0.3-0.3 c-0.1-0.1-0.2-0.2-0.3-0.3s-0.4-0.5-0.7-0.9s-0.7-1-1.1-1.6c-0.4-0.6-0.8-1.3-1.3-2.2C2.9,9.4,2.5,8.5,2.1,7.5C2,7.4,2,7.3,2,7.2 c0-0.1,0-0.1,0-0.2l0-0.1c0.1-0.1,0.3-0.2,0.6-0.2l2.9,0c0.1,0,0.2,0,0.2,0.1S5.9,6.9,5.9,7L6,7c0.1,0.1,0.2,0.2,0.3,0.3 C6.4,7.7,6.5,8,6.7,8.4C6.9,8.8,7,9,7.1,9.2l0.2,0.3c0.2,0.4,0.4,0.8,0.6,1.1c0.2,0.3,0.4,0.5,0.5,0.7s0.3,0.3,0.4,0.4 c0.1,0.1,0.3,0.1,0.4,0.1c0.1,0,0.2,0,0.3-0.1c0,0,0,0,0.1-0.1c0,0,0.1-0.1,0.1-0.2c0.1-0.1,0.1-0.3,0.1-0.5c0-0.2,0.1-0.5,0.1-0.8 c0-0.4,0-0.8,0-1.3c0-0.3,0-0.5-0.1-0.8c0-0.2-0.1-0.4-0.1-0.5L9.6,7.6C9.4,7.3,9.1,7.2,8.7,7.1C8.6,7.1,8.6,7,8.7,6.9 C8.9,6.7,9,6.6,9.1,6.5c0.4-0.2,1.2-0.3,2.5-0.3c0.6,0,1,0.1,1.4,0.1c0.1,0,0.3,0.1,0.3,0.1c0.1,0.1,0.2,0.1,0.2,0.3 c0,0.1,0.1,0.2,0.1,0.3s0,0.3,0,0.5c0,0.2,0,0.4,0,0.6c0,0.2,0,0.4,0,0.7c0,0.3,0,0.6,0,0.9c0,0.1,0,0.2,0,0.4c0,0.2,0,0.4,0,0.5 c0,0.1,0,0.3,0,0.4s0.1,0.3,0.1,0.4c0.1,0.1,0.1,0.2,0.2,0.3c0.1,0,0.1,0,0.2,0c0.1,0,0.2,0,0.3-0.1c0.1-0.1,0.2-0.2,0.4-0.4 s0.3-0.4,0.5-0.7c0.2-0.3,0.5-0.7,0.7-1.1c0.4-0.7,0.8-1.5,1.1-2.3c0-0.1,0.1-0.1,0.1-0.2c0-0.1,0.1-0.1,0.1-0.1l0,0l0.1,0 c0,0,0,0,0.1,0s0.2,0,0.2,0l3,0c0.3,0,0.5,0,0.7,0S21.9,7,21.9,7L22,7.1z"></path></svg>', 'whatsapp' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M16.75,13.96C17,14.09 17.16,14.16 17.21,14.26C17.27,14.37 17.25,14.87 17,15.44C16.8,16 15.76,16.54 15.3,16.56C14.84,16.58 14.83,16.92 12.34,15.83C9.85,14.74 8.35,12.08 8.23,11.91C8.11,11.74 7.27,10.53 7.31,9.3C7.36,8.08 8,7.5 8.26,7.26C8.5,7 8.77,6.97 8.94,7H9.41C9.56,7 9.77,6.94 9.96,7.45L10.65,9.32C10.71,9.45 10.75,9.6 10.66,9.76L10.39,10.17L10,10.59C9.88,10.71 9.74,10.84 9.88,11.09C10,11.35 10.5,12.18 11.2,12.87C12.11,13.75 12.91,14.04 13.15,14.17C13.39,14.31 13.54,14.29 13.69,14.13L14.5,13.19C14.69,12.94 14.85,13 15.08,13.08L16.75,13.96M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C10.03,22 8.2,21.43 6.65,20.45L2,22L3.55,17.35C2.57,15.8 2,13.97 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12C4,13.72 4.54,15.31 5.46,16.61L4.5,19.5L7.39,18.54C8.69,19.46 10.28,20 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" /> </svg>', // phpcs:disable WordPress.WP.CapitalPDangit.Misspelled 'wordpress' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.158,12.786L9.46,20.625c0.806,0.237,1.657,0.366,2.54,0.366c1.047,0,2.051-0.181,2.986-0.51 c-0.024-0.038-0.046-0.079-0.065-0.124L12.158,12.786z M3.009,12c0,3.559,2.068,6.634,5.067,8.092L3.788,8.341 C3.289,9.459,3.009,10.696,3.009,12z M18.069,11.546c0-1.112-0.399-1.881-0.741-2.48c-0.456-0.741-0.883-1.368-0.883-2.109 c0-0.826,0.627-1.596,1.51-1.596c0.04,0,0.078,0.005,0.116,0.007C16.472,3.904,14.34,3.009,12,3.009 c-3.141,0-5.904,1.612-7.512,4.052c0.211,0.007,0.41,0.011,0.579,0.011c0.94,0,2.396-0.114,2.396-0.114 C7.947,6.93,8.004,7.642,7.52,7.699c0,0-0.487,0.057-1.029,0.085l3.274,9.739l1.968-5.901l-1.401-3.838 C9.848,7.756,9.389,7.699,9.389,7.699C8.904,7.67,8.961,6.93,9.446,6.958c0,0,1.484,0.114,2.368,0.114 c0.94,0,2.397-0.114,2.397-0.114c0.485-0.028,0.542,0.684,0.057,0.741c0,0-0.488,0.057-1.029,0.085l3.249,9.665l0.897-2.996 C17.841,13.284,18.069,12.316,18.069,11.546z M19.889,7.686c0.039,0.286,0.06,0.593,0.06,0.924c0,0.912-0.171,1.938-0.684,3.22 l-2.746,7.94c2.673-1.558,4.47-4.454,4.47-7.771C20.991,10.436,20.591,8.967,19.889,7.686z M12,22C6.486,22,2,17.514,2,12 C2,6.486,6.486,2,12,2c5.514,0,10,4.486,10,10C22,17.514,17.514,22,12,22z"></path></svg>', 'yelp' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.271,16.718v1.417q-.011,3.257-.067,3.4a.707.707,0,0,1-.569.446,4.637,4.637,0,0,1-2.024-.424A4.609,4.609,0,0,1,7.8,20.565a.844.844,0,0,1-.19-.4.692.692,0,0,1,.044-.29,3.181,3.181,0,0,1,.379-.524q.335-.412,2.019-2.409.011,0,.669-.781a.757.757,0,0,1,.44-.274.965.965,0,0,1,.552.039.945.945,0,0,1,.418.324.732.732,0,0,1,.139.468Zm-1.662-2.8a.783.783,0,0,1-.58.781l-1.339.435q-3.067.981-3.257.981a.711.711,0,0,1-.6-.4,2.636,2.636,0,0,1-.19-.836,9.134,9.134,0,0,1,.011-1.857,3.559,3.559,0,0,1,.335-1.389.659.659,0,0,1,.625-.357,22.629,22.629,0,0,1,2.253.859q.781.324,1.283.524l.937.379a.771.771,0,0,1,.4.34A.982.982,0,0,1,10.609,13.917Zm9.213,3.313a4.467,4.467,0,0,1-1.021,1.8,4.559,4.559,0,0,1-1.512,1.417.671.671,0,0,1-.7-.078q-.156-.112-2.052-3.2l-.524-.859a.761.761,0,0,1-.128-.513.957.957,0,0,1,.217-.513.774.774,0,0,1,.926-.29q.011.011,1.327.446,2.264.736,2.7.887a2.082,2.082,0,0,1,.524.229.673.673,0,0,1,.245.68Zm-7.5-7.049q.056,1.137-.6,1.361-.647.19-1.272-.792L6.237,4.08a.7.7,0,0,1,.212-.691,5.788,5.788,0,0,1,2.314-1,5.928,5.928,0,0,1,2.5-.352.681.681,0,0,1,.547.5q.034.2.245,3.407T12.327,10.181Zm7.384,1.2a.679.679,0,0,1-.29.658q-.167.112-3.67.959-.747.167-1.015.257l.011-.022a.769.769,0,0,1-.513-.044.914.914,0,0,1-.413-.357.786.786,0,0,1,0-.971q.011-.011.836-1.137,1.394-1.908,1.673-2.275a2.423,2.423,0,0,1,.379-.435A.7.7,0,0,1,17.435,8a4.482,4.482,0,0,1,1.372,1.489,4.81,4.81,0,0,1,.9,1.868v.034Z"></path></svg>', 'youtube' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg>', ); } } class-twentytwenty-walker-page.php 0000644 00000012152 15252503212 0013360 0 ustar 00 <?php /** * Custom page walker for this theme. * * @package WordPress * @subpackage Twenty_Twenty * @since Twenty Twenty 1.0 */ if ( ! class_exists( 'TwentyTwenty_Walker_Page' ) ) { /** * CUSTOM PAGE WALKER * A custom walker for pages. */ class TwentyTwenty_Walker_Page extends Walker_Page { /** * Outputs the beginning of the current element in the tree. * * @see Walker::start_el() * @since 2.1.0 * * @param string $output Used to append additional content. Passed by reference. * @param WP_Post $page Page data object. * @param int $depth Optional. Depth of page. Used for padding. Default 0. * @param array $args Optional. Array of arguments. Default empty array. * @param int $current_page Optional. Page ID. Default 0. */ public function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } if ( $depth ) { $indent = str_repeat( $t, $depth ); } else { $indent = ''; } $css_class = array( 'page_item', 'page-item-' . $page->ID ); if ( isset( $args['pages_with_children'][ $page->ID ] ) ) { $css_class[] = 'page_item_has_children'; } if ( ! empty( $current_page ) ) { $_current_page = get_post( $current_page ); if ( $_current_page && in_array( $page->ID, $_current_page->ancestors, true ) ) { $css_class[] = 'current_page_ancestor'; } if ( $page->ID === $current_page ) { $css_class[] = 'current_page_item'; } elseif ( $_current_page && $page->ID === $_current_page->post_parent ) { $css_class[] = 'current_page_parent'; } } elseif ( get_option( 'page_for_posts' ) === $page->ID ) { $css_class[] = 'current_page_parent'; } /** This filter is documented in wp-includes/class-walker-page.php */ $css_classes = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) ); $css_classes = $css_classes ? ' class="' . esc_attr( $css_classes ) . '"' : ''; if ( '' === $page->post_title ) { /* translators: %d: ID of a post. */ $page->post_title = sprintf( __( '#%d (no title)', 'twentytwenty' ), $page->ID ); } $args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before']; $args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after']; $atts = array(); $atts['href'] = get_permalink( $page->ID ); $atts['aria-current'] = ( $page->ID === $current_page ) ? 'page' : ''; /** This filter is documented in wp-includes/class-walker-page.php */ $atts = apply_filters( 'page_menu_link_attributes', $atts, $page, $depth, $args, $current_page ); $attributes = ''; foreach ( $atts as $attr => $value ) { if ( ! empty( $value ) ) { $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } } $args['list_item_before'] = ''; $args['list_item_after'] = ''; // Wrap the link in a div and append a sub menu toggle. if ( isset( $args['show_toggles'] ) && true === $args['show_toggles'] ) { // Wrap the menu item link contents in a div, used for positioning. $args['list_item_before'] = '<div class="ancestor-wrapper">'; $args['list_item_after'] = ''; // Add a toggle to items with children. if ( isset( $args['pages_with_children'][ $page->ID ] ) ) { $toggle_target_string = '.menu-modal .page-item-' . $page->ID . ' > ul'; $toggle_duration = twentytwenty_toggle_duration(); // Add the sub menu toggle. $args['list_item_after'] .= '<button class="toggle sub-menu-toggle fill-children-current-color" data-toggle-target="' . $toggle_target_string . '" data-toggle-type="slidetoggle" data-toggle-duration="' . absint( $toggle_duration ) . '" aria-expanded="false"><span class="screen-reader-text">' . __( 'Show sub menu', 'twentytwenty' ) . '</span>' . twentytwenty_get_theme_svg( 'chevron-down' ) . '</button>'; } // Close the wrapper. $args['list_item_after'] .= '</div><!-- .ancestor-wrapper -->'; } // Add icons to menu items with children. if ( isset( $args['show_sub_menu_icons'] ) && true === $args['show_sub_menu_icons'] ) { if ( isset( $args['pages_with_children'][ $page->ID ] ) ) { $args['list_item_after'] = '<span class="icon"></span>'; } } $output .= $indent . sprintf( '<li%s>%s<a%s>%s%s%s</a>%s', $css_classes, $args['list_item_before'], $attributes, $args['link_before'], /** This filter is documented in wp-includes/post-template.php */ apply_filters( 'the_title', $page->post_title, $page->ID ), $args['link_after'], $args['list_item_after'] ); if ( ! empty( $args['show_date'] ) ) { if ( 'modified' === $args['show_date'] ) { $time = $page->post_modified; } else { $time = $page->post_date; } $date_format = empty( $args['date_format'] ) ? '' : $args['date_format']; $output .= ' ' . mysql2date( $date_format, $time ); } } } } class-twentytwenty-separator-control.php 0000644 00000000734 15252503212 0014642 0 ustar 00 <?php /** * Customizer Separator Control settings for this theme. * * @package WordPress * @subpackage Twenty_Twenty * @since Twenty Twenty 1.0 */ if ( class_exists( 'WP_Customize_Control' ) ) { if ( ! class_exists( 'TwentyTwenty_Separator_Control' ) ) { /** * Separator Control. */ class TwentyTwenty_Separator_Control extends WP_Customize_Control { /** * Render the hr. */ public function render_content() { echo '<hr/>'; } } } } class-twentytwenty-walker-comment.php 0000644 00000011177 15252503212 0014114 0 ustar 00 <?php /** * Custom comment walker for this theme. * * @package WordPress * @subpackage Twenty_Twenty * @since Twenty Twenty 1.0 */ if ( ! class_exists( 'TwentyTwenty_Walker_Comment' ) ) { /** * CUSTOM COMMENT WALKER * A custom walker for comments, based on the walker in Twenty Nineteen. */ class TwentyTwenty_Walker_Comment extends Walker_Comment { /** * Outputs a comment in the HTML5 format. * * @see wp_list_comments() * @see https://developer.wordpress.org/reference/functions/get_comment_author_url/ * @see https://developer.wordpress.org/reference/functions/get_comment_author/ * @see https://developer.wordpress.org/reference/functions/get_avatar/ * @see https://developer.wordpress.org/reference/functions/get_comment_reply_link/ * @see https://developer.wordpress.org/reference/functions/get_edit_comment_link/ * * @param WP_Comment $comment Comment to display. * @param int $depth Depth of the current comment. * @param array $args An array of arguments. */ protected function html5_comment( $comment, $depth, $args ) { $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; ?> <<?php echo $tag; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- static output ?> id="comment-<?php comment_ID(); ?>" <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?>> <article id="div-comment-<?php comment_ID(); ?>" class="comment-body"> <footer class="comment-meta"> <div class="comment-author vcard"> <?php $comment_author_url = get_comment_author_url( $comment ); $comment_author = get_comment_author( $comment ); $avatar = get_avatar( $comment, $args['avatar_size'] ); if ( 0 !== $args['avatar_size'] ) { if ( empty( $comment_author_url ) ) { echo wp_kses_post( $avatar ); } else { printf( '<a href="%s" rel="external nofollow" class="url">', $comment_author_url ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped --Escaped in https://developer.wordpress.org/reference/functions/get_comment_author_url/ echo wp_kses_post( $avatar ); } } printf( '<span class="fn">%1$s</span><span class="screen-reader-text says">%2$s</span>', esc_html( $comment_author ), __( 'says:', 'twentytwenty' ) ); if ( ! empty( $comment_author_url ) ) { echo '</a>'; } ?> </div><!-- .comment-author --> <div class="comment-metadata"> <a href="<?php echo esc_url( get_comment_link( $comment, $args ) ); ?>"> <?php /* translators: 1: Comment date, 2: Comment time. */ $comment_timestamp = sprintf( __( '%1$s at %2$s', 'twentytwenty' ), get_comment_date( '', $comment ), get_comment_time() ); ?> <time datetime="<?php comment_time( 'c' ); ?>" title="<?php echo esc_attr( $comment_timestamp ); ?>"> <?php echo esc_html( $comment_timestamp ); ?> </time> </a> <?php if ( get_edit_comment_link() ) { echo ' <span aria-hidden="true">•</span> <a class="comment-edit-link" href="' . esc_url( get_edit_comment_link() ) . '">' . __( 'Edit', 'twentytwenty' ) . '</a>'; } ?> </div><!-- .comment-metadata --> </footer><!-- .comment-meta --> <div class="comment-content entry-content"> <?php comment_text(); if ( '0' === $comment->comment_approved ) { ?> <p class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.', 'twentytwenty' ); ?></p> <?php } ?> </div><!-- .comment-content --> <?php $comment_reply_link = get_comment_reply_link( array_merge( $args, array( 'add_below' => 'div-comment', 'depth' => $depth, 'max_depth' => $args['max_depth'], 'before' => '<span class="comment-reply">', 'after' => '</span>', ) ) ); $by_post_author = twentytwenty_is_comment_by_post_author( $comment ); if ( $comment_reply_link || $by_post_author ) { ?> <footer class="comment-footer-meta"> <?php if ( $comment_reply_link ) { echo $comment_reply_link; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Link is escaped in https://developer.wordpress.org/reference/functions/get_comment_reply_link/ } if ( $by_post_author ) { echo '<span class="by-post-author">' . __( 'By Post Author', 'twentytwenty' ) . '</span>'; } ?> </footer> <?php } ?> </article><!-- .comment-body --> <?php } } } class-twentytwenty-customize.php 0000644 00000033724 15252503212 0013213 0 ustar 00 <?php /** * Customizer settings for this theme. * * @package WordPress * @subpackage Twenty_Twenty * @since Twenty Twenty 1.0 */ if ( ! class_exists( 'TwentyTwenty_Customize' ) ) { /** * CUSTOMIZER SETTINGS */ class TwentyTwenty_Customize { /** * Register customizer options. * * @param WP_Customize_Manager $wp_customize Theme Customizer object. */ public static function register( $wp_customize ) { /** * Site Title & Description. * */ $wp_customize->get_setting( 'blogname' )->transport = 'postMessage'; $wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage'; $wp_customize->selective_refresh->add_partial( 'blogname', array( 'selector' => '.site-title a', 'render_callback' => 'twentytwenty_customize_partial_blogname', ) ); $wp_customize->selective_refresh->add_partial( 'blogdescription', array( 'selector' => '.site-description', 'render_callback' => 'twentytwenty_customize_partial_blogdescription', ) ); $wp_customize->selective_refresh->add_partial( 'custom_logo', array( 'selector' => '.header-titles [class*=site-]:not(.site-description)', 'render_callback' => 'twentytwenty_customize_partial_site_logo', ) ); $wp_customize->selective_refresh->add_partial( 'retina_logo', array( 'selector' => '.header-titles [class*=site-]:not(.site-description)', 'render_callback' => 'twentytwenty_customize_partial_site_logo', ) ); /** * Site Identity */ /* 2X Header Logo ---------------- */ $wp_customize->add_setting( 'retina_logo', array( 'capability' => 'edit_theme_options', 'sanitize_callback' => array( __CLASS__, 'sanitize_checkbox' ), 'transport' => 'postMessage', ) ); $wp_customize->add_control( 'retina_logo', array( 'type' => 'checkbox', 'section' => 'title_tagline', 'priority' => 10, 'label' => __( 'Retina logo', 'twentytwenty' ), 'description' => __( 'Scales the logo to half its uploaded size, making it sharp on high-res screens.', 'twentytwenty' ), ) ); // Header & Footer Background Color. $wp_customize->add_setting( 'header_footer_background_color', array( 'default' => '#ffffff', 'sanitize_callback' => 'sanitize_hex_color', 'transport' => 'postMessage', ) ); $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'header_footer_background_color', array( 'label' => __( 'Header & Footer Background Color', 'twentytwenty' ), 'section' => 'colors', ) ) ); // Enable picking an accent color. $wp_customize->add_setting( 'accent_hue_active', array( 'capability' => 'edit_theme_options', 'sanitize_callback' => array( __CLASS__, 'sanitize_select' ), 'transport' => 'postMessage', 'default' => 'default', ) ); $wp_customize->add_control( 'accent_hue_active', array( 'type' => 'radio', 'section' => 'colors', 'label' => __( 'Primary Color', 'twentytwenty' ), 'choices' => array( 'default' => __( 'Default', 'twentytwenty' ), 'custom' => __( 'Custom', 'twentytwenty' ), ), ) ); /** * Implementation for the accent color. * This is different to all other color options because of the accessibility enhancements. * The control is a hue-only colorpicker, and there is a separate setting that holds values * for other colors calculated based on the selected hue and various background-colors on the page. * * @since Twenty Twenty 1.0 */ // Add the setting for the hue colorpicker. $wp_customize->add_setting( 'accent_hue', array( 'default' => 344, 'type' => 'theme_mod', 'sanitize_callback' => 'absint', 'transport' => 'postMessage', ) ); // Add setting to hold colors derived from the accent hue. $wp_customize->add_setting( 'accent_accessible_colors', array( 'default' => array( 'content' => array( 'text' => '#000000', 'accent' => '#cd2653', 'secondary' => '#6d6d6d', 'borders' => '#dcd7ca', ), 'header-footer' => array( 'text' => '#000000', 'accent' => '#cd2653', 'secondary' => '#6d6d6d', 'borders' => '#dcd7ca', ), ), 'type' => 'theme_mod', 'transport' => 'postMessage', 'sanitize_callback' => array( __CLASS__, 'sanitize_accent_accessible_colors' ), ) ); // Add the hue-only colorpicker for the accent color. $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'accent_hue', array( 'section' => 'colors', 'settings' => 'accent_hue', 'description' => __( 'Apply a custom color for links, buttons, featured images.', 'twentytwenty' ), 'mode' => 'hue', 'active_callback' => function() use ( $wp_customize ) { return ( 'custom' === $wp_customize->get_setting( 'accent_hue_active' )->value() ); }, ) ) ); // Update background color with postMessage, so inline CSS output is updated as well. $wp_customize->get_setting( 'background_color' )->transport = 'postMessage'; /** * Theme Options */ $wp_customize->add_section( 'options', array( 'title' => __( 'Theme Options', 'twentytwenty' ), 'priority' => 40, 'capability' => 'edit_theme_options', ) ); /* Enable Header Search ----------------------------------------------- */ $wp_customize->add_setting( 'enable_header_search', array( 'capability' => 'edit_theme_options', 'default' => true, 'sanitize_callback' => array( __CLASS__, 'sanitize_checkbox' ), ) ); $wp_customize->add_control( 'enable_header_search', array( 'type' => 'checkbox', 'section' => 'options', 'priority' => 10, 'label' => __( 'Show search in header', 'twentytwenty' ), ) ); /* Show author bio ---------------------------------------------------- */ $wp_customize->add_setting( 'show_author_bio', array( 'capability' => 'edit_theme_options', 'default' => true, 'sanitize_callback' => array( __CLASS__, 'sanitize_checkbox' ), ) ); $wp_customize->add_control( 'show_author_bio', array( 'type' => 'checkbox', 'section' => 'options', 'priority' => 10, 'label' => __( 'Show author bio', 'twentytwenty' ), ) ); /* Display full content or excerpts on the blog and archives --------- */ $wp_customize->add_setting( 'blog_content', array( 'capability' => 'edit_theme_options', 'default' => 'full', 'sanitize_callback' => array( __CLASS__, 'sanitize_select' ), ) ); $wp_customize->add_control( 'blog_content', array( 'type' => 'radio', 'section' => 'options', 'priority' => 10, 'label' => __( 'On archive pages, posts show:', 'twentytwenty' ), 'choices' => array( 'full' => __( 'Full text', 'twentytwenty' ), 'summary' => __( 'Summary', 'twentytwenty' ), ), ) ); /** * Template: Cover Template. */ $wp_customize->add_section( 'cover_template_options', array( 'title' => __( 'Cover Template', 'twentytwenty' ), 'capability' => 'edit_theme_options', 'description' => __( 'Settings for the "Cover Template" page template. Add a featured image to use as background.', 'twentytwenty' ), 'priority' => 42, ) ); /* Overlay Fixed Background ------ */ $wp_customize->add_setting( 'cover_template_fixed_background', array( 'capability' => 'edit_theme_options', 'default' => true, 'sanitize_callback' => array( __CLASS__, 'sanitize_checkbox' ), 'transport' => 'postMessage', ) ); $wp_customize->add_control( 'cover_template_fixed_background', array( 'type' => 'checkbox', 'section' => 'cover_template_options', 'label' => __( 'Fixed Background Image', 'twentytwenty' ), 'description' => __( 'Creates a parallax effect when the visitor scrolls.', 'twentytwenty' ), ) ); $wp_customize->selective_refresh->add_partial( 'cover_template_fixed_background', array( 'selector' => '.cover-header', 'type' => 'cover_fixed', ) ); /* Separator --------------------- */ $wp_customize->add_setting( 'cover_template_separator_1', array( 'sanitize_callback' => 'wp_filter_nohtml_kses', ) ); $wp_customize->add_control( new TwentyTwenty_Separator_Control( $wp_customize, 'cover_template_separator_1', array( 'section' => 'cover_template_options', ) ) ); /* Overlay Background Color ------ */ $wp_customize->add_setting( 'cover_template_overlay_background_color', array( 'default' => twentytwenty_get_color_for_area( 'content', 'accent' ), 'sanitize_callback' => 'sanitize_hex_color', ) ); $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'cover_template_overlay_background_color', array( 'label' => __( 'Overlay Background Color', 'twentytwenty' ), 'description' => __( 'The color used for the overlay. Defaults to the accent color.', 'twentytwenty' ), 'section' => 'cover_template_options', ) ) ); /* Overlay Text Color ------------ */ $wp_customize->add_setting( 'cover_template_overlay_text_color', array( 'default' => '#ffffff', 'sanitize_callback' => 'sanitize_hex_color', ) ); $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'cover_template_overlay_text_color', array( 'label' => __( 'Overlay Text Color', 'twentytwenty' ), 'description' => __( 'The color used for the text in the overlay.', 'twentytwenty' ), 'section' => 'cover_template_options', ) ) ); /* Overlay Color Opacity --------- */ $wp_customize->add_setting( 'cover_template_overlay_opacity', array( 'default' => 80, 'sanitize_callback' => 'absint', 'transport' => 'postMessage', ) ); $wp_customize->add_control( 'cover_template_overlay_opacity', array( 'label' => __( 'Overlay Opacity', 'twentytwenty' ), 'description' => __( 'Make sure that the contrast is high enough so that the text is readable.', 'twentytwenty' ), 'section' => 'cover_template_options', 'type' => 'range', 'input_attrs' => twentytwenty_customize_opacity_range(), ) ); $wp_customize->selective_refresh->add_partial( 'cover_template_overlay_opacity', array( 'selector' => '.cover-color-overlay', 'type' => 'cover_opacity', ) ); } /** * Sanitization callback for the "accent_accessible_colors" setting. * * @static * @access public * @since Twenty Twenty 1.0 * @param array $value The value we want to sanitize. * @return array Returns sanitized value. Each item in the array gets sanitized separately. */ public static function sanitize_accent_accessible_colors( $value ) { // Make sure the value is an array. Do not typecast, use empty array as fallback. $value = is_array( $value ) ? $value : array(); // Loop values. foreach ( $value as $area => $values ) { foreach ( $values as $context => $color_val ) { $value[ $area ][ $context ] = sanitize_hex_color( $color_val ); } } return $value; } /** * Sanitize select. * * @param string $input The input from the setting. * @param object $setting The selected setting. * @return string The input from the setting or the default setting. */ public static function sanitize_select( $input, $setting ) { $input = sanitize_key( $input ); $choices = $setting->manager->get_control( $setting->id )->choices; return ( array_key_exists( $input, $choices ) ? $input : $setting->default ); } /** * Sanitize boolean for checkbox. * * @param bool $checked Whether or not a box is checked. * @return bool */ public static function sanitize_checkbox( $checked ) { return ( ( isset( $checked ) && true === $checked ) ? true : false ); } } // Setup the Theme Customizer settings and controls. add_action( 'customize_register', array( 'TwentyTwenty_Customize', 'register' ) ); } /** * PARTIAL REFRESH FUNCTIONS * */ if ( ! function_exists( 'twentytwenty_customize_partial_blogname' ) ) { /** * Render the site title for the selective refresh partial. */ function twentytwenty_customize_partial_blogname() { bloginfo( 'name' ); } } if ( ! function_exists( 'twentytwenty_customize_partial_blogdescription' ) ) { /** * Render the site description for the selective refresh partial. */ function twentytwenty_customize_partial_blogdescription() { bloginfo( 'description' ); } } if ( ! function_exists( 'twentytwenty_customize_partial_site_logo' ) ) { /** * Render the site logo for the selective refresh partial. * * Doing it this way so we don't have issues with `render_callback`'s arguments. */ function twentytwenty_customize_partial_site_logo() { twentytwenty_site_logo(); } } /** * Input attributes for cover overlay opacity option. * * @return array Array containing attribute names and their values. */ function twentytwenty_customize_opacity_range() { /** * Filter the input attributes for opacity * * @param array $attrs { * The attributes * * @type int $min Minimum value * @type int $max Maximum value * @type int $step Interval between numbers * } */ return apply_filters( 'twentytwenty_customize_opacity_range', array( 'min' => 0, 'max' => 90, 'step' => 5, ) ); } class-twenty-twenty-one-customize.php 0000644 00000011541 15252503401 0014040 0 ustar 00 <?php /** * Customizer settings for this theme. * * @package WordPress * @subpackage Twenty_Twenty_One * @since 1.0.0 */ if ( ! class_exists( 'Twenty_Twenty_One_Customize' ) ) { /** * Customizer Settings. * * @since 1.0.0 */ class Twenty_Twenty_One_Customize { /** * Constructor. Instantiate the object. * * @access public * * @since 1.0.0 */ public function __construct() { add_action( 'customize_register', array( $this, 'register' ) ); } /** * Register customizer options. * * @access public * * @since 1.0.0 * * @param WP_Customize_Manager $wp_customize Theme Customizer object. * * @return void */ public function register( $wp_customize ) { // Change site-title & description to postMessage. $wp_customize->get_setting( 'blogname' )->transport = 'postMessage'; // @phpstan-ignore-line. Assume that this setting exists. $wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage'; // @phpstan-ignore-line. Assume that this setting exists. // Add partial for blogname. $wp_customize->selective_refresh->add_partial( 'blogname', array( 'selector' => '.site-title', 'render_callback' => array( $this, 'partial_blogname' ), ) ); // Add partial for blogdescription. $wp_customize->selective_refresh->add_partial( 'blogdescription', array( 'selector' => '.site-description', 'render_callback' => array( $this, 'partial_blogdescription' ), ) ); // Add "display_title_and_tagline" setting for displaying the site-title & tagline. $wp_customize->add_setting( 'display_title_and_tagline', array( 'capability' => 'edit_theme_options', 'default' => true, 'sanitize_callback' => array( __CLASS__, 'sanitize_checkbox' ), ) ); // Add control for the "display_title_and_tagline" setting. $wp_customize->add_control( 'display_title_and_tagline', array( 'type' => 'checkbox', 'section' => 'title_tagline', 'label' => esc_html__( 'Display Site Title & Tagline', 'twentytwentyone' ), ) ); /** * Add excerpt or full text selector to customizer */ $wp_customize->add_section( 'excerpt_settings', array( 'title' => esc_html__( 'Excerpt Settings', 'twentytwentyone' ), 'priority' => 120, ) ); $wp_customize->add_setting( 'display_excerpt_or_full_post', array( 'capability' => 'edit_theme_options', 'default' => 'excerpt', 'sanitize_callback' => function( $value ) { return 'excerpt' === $value || 'full' === $value ? $value : 'excerpt'; }, ) ); $wp_customize->add_control( 'display_excerpt_or_full_post', array( 'type' => 'radio', 'section' => 'excerpt_settings', 'label' => esc_html__( 'On Archive Pages, posts show:', 'twentytwentyone' ), 'choices' => array( 'excerpt' => esc_html__( 'Summary', 'twentytwentyone' ), 'full' => esc_html__( 'Full text', 'twentytwentyone' ), ), ) ); // Background color. // Include the custom control class. include_once get_theme_file_path( 'classes/class-twenty-twenty-one-customize-color-control.php' ); // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude.FileIncludeFound // Register the custom control. $wp_customize->register_control_type( 'Twenty_Twenty_One_Customize_Color_Control' ); // Get the palette from theme-supports. $palette = get_theme_support( 'editor-color-palette' ); // Build the colors array from theme-support. $colors = array(); if ( isset( $palette[0] ) && is_array( $palette[0] ) ) { foreach ( $palette[0] as $palette_color ) { $colors[] = $palette_color['color']; } } // Add the control. Overrides the default background-color control. $wp_customize->add_control( new Twenty_Twenty_One_Customize_Color_Control( $wp_customize, 'background_color', array( 'label' => esc_html_x( 'Background color', 'Customizer control', 'twentytwentyone' ), 'section' => 'colors', 'palette' => $colors, ) ) ); } /** * Sanitize boolean for checkbox. * * @access public * * @since 1.0.0 * * @param bool $checked Whether or not a box is checked. * * @return bool */ public static function sanitize_checkbox( $checked = null ) { return (bool) isset( $checked ) && true === $checked; } /** * Render the site title for the selective refresh partial. * * @access public * * @since 1.0.0 * * @return void */ public function partial_blogname() { bloginfo( 'name' ); } /** * Render the site tagline for the selective refresh partial. * * @access public * * @since 1.0.0 * * @return void */ public function partial_blogdescription() { bloginfo( 'description' ); } } } class-twenty-twenty-one-svg-icons.php 0000644 00000147242 15252503401 0013736 0 ustar 00 <?php /** * SVG Icons class * * @package WordPress * @subpackage Twenty_Twenty_One * @since 1.0.0 */ /** * This class is in charge of displaying SVG icons across the site. * * Place each <svg> source on its own array key, without adding either * the `width` or `height` attributes, since these are added dynamically, * before rendering the SVG code. * * All icons are assumed to have equal width and height, hence the option * to only specify a `$size` parameter in the svg methods. * * @since 1.0.0 */ class Twenty_Twenty_One_SVG_Icons { /** * User Interface icons – svg sources. * * @access protected * * @since 1.0.0 * * @var array */ protected static $icons = array( 'arrow_right' => '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="m4 13v-2h12l-4-4 1-2 7 7-7 7-1-2 4-4z" fill="currentColor"/></svg>', 'arrow_left' => '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M20 13v-2H8l4-4-1-2-7 7 7 7 1-2-4-4z" fill="currentColor"/></svg>', 'close' => '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 10.9394L5.53033 4.46973L4.46967 5.53039L10.9393 12.0001L4.46967 18.4697L5.53033 19.5304L12 13.0607L18.4697 19.5304L19.5303 18.4697L13.0607 12.0001L19.5303 5.53039L18.4697 4.46973L12 10.9394Z" fill="currentColor"/></svg>', 'menu' => '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 6H19.5V7.5H4.5V6ZM4.5 12H19.5V13.5H4.5V12ZM19.5 18H4.5V19.5H19.5V18Z" fill="currentColor"/></svg>', 'plus' => '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M18 11.2h-5.2V6h-1.6v5.2H6v1.6h5.2V18h1.6v-5.2H18z" fill="currentColor"/></svg>', 'minus' => '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 11h12v2H6z" fill="currentColor"/></svg>', ); /** * Social Icons – svg sources. * * @access protected * * @since 1.0.0 * * @var array */ protected static $social_icons = array( '500px' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M6.94026,15.1412c.00437.01213.108.29862.168.44064a6.55008,6.55008,0,1,0,6.03191-9.09557,6.68654,6.68654,0,0,0-2.58357.51467A8.53914,8.53914,0,0,0,8.21268,8.61344L8.209,8.61725V3.22948l9.0504-.00008c.32934-.0036.32934-.46353.32934-.61466s0-.61091-.33035-.61467L7.47248,2a.43.43,0,0,0-.43131.42692v7.58355c0,.24466.30476.42131.58793.4819.553.11812.68074-.05864.81617-.2457l.018-.02481A10.52673,10.52673,0,0,1,9.32258,9.258a5.35268,5.35268,0,1,1,7.58985,7.54976,5.417,5.417,0,0,1-3.80867,1.56365,5.17483,5.17483,0,0,1-2.69822-.74478l.00342-4.61111a2.79372,2.79372,0,0,1,.71372-1.78792,2.61611,2.61611,0,0,1,1.98282-.89477,2.75683,2.75683,0,0,1,1.95525.79477,2.66867,2.66867,0,0,1,.79656,1.909,2.724,2.724,0,0,1-2.75849,2.748,4.94651,4.94651,0,0,1-.86254-.13719c-.31234-.093-.44519.34058-.48892.48349-.16811.54966.08453.65862.13687.67489a3.75751,3.75751,0,0,0,1.25234.18375,3.94634,3.94634,0,1,0-2.82444-6.742,3.67478,3.67478,0,0,0-1.13028,2.584l-.00041.02323c-.0035.11667-.00579,2.881-.00644,3.78811l-.00407-.00451a6.18521,6.18521,0,0,1-1.0851-1.86092c-.10544-.27856-.34358-.22925-.66857-.12917-.14192.04372-.57386.17677-.47833.489Zm4.65165-1.08338a.51346.51346,0,0,0,.19513.31818l.02276.022a.52945.52945,0,0,0,.3517.18416.24242.24242,0,0,0,.16577-.0611c.05473-.05082.67382-.67812.73287-.738l.69041.68819a.28978.28978,0,0,0,.21437.11032.53239.53239,0,0,0,.35708-.19486c.29792-.30419.14885-.46821.07676-.54751l-.69954-.69975.72952-.73469c.16-.17311.01874-.35708-.12218-.498-.20461-.20461-.402-.25742-.52855-.14083l-.7254.72665-.73354-.73375a.20128.20128,0,0,0-.14179-.05695.54135.54135,0,0,0-.34379.19648c-.22561.22555-.274.38149-.15656.5059l.73374.7315-.72942.73072A.26589.26589,0,0,0,11.59191,14.05782Zm1.59866-9.915A8.86081,8.86081,0,0,0,9.854,4.776a.26169.26169,0,0,0-.16938.22759.92978.92978,0,0,0,.08619.42094c.05682.14524.20779.531.50006.41955a8.40969,8.40969,0,0,1,2.91968-.55484,7.87875,7.87875,0,0,1,3.086.62286,8.61817,8.61817,0,0,1,2.30562,1.49315.2781.2781,0,0,0,.18318.07586c.15529,0,.30425-.15253.43167-.29551.21268-.23861.35873-.4369.1492-.63538a8.50425,8.50425,0,0,0-2.62312-1.694A9.0177,9.0177,0,0,0,13.19058,4.14283ZM19.50945,18.6236h0a.93171.93171,0,0,0-.36642-.25406.26589.26589,0,0,0-.27613.06613l-.06943.06929A7.90606,7.90606,0,0,1,7.60639,18.505a7.57284,7.57284,0,0,1-1.696-2.51537,8.58715,8.58715,0,0,1-.5147-1.77754l-.00871-.04864c-.04939-.25873-.28755-.27684-.62981-.22448-.14234.02178-.5755.088-.53426.39969l.001.00712a9.08807,9.08807,0,0,0,15.406,4.99094c.00193-.00192.04753-.04718.0725-.07436C19.79425,19.16234,19.87422,18.98728,19.50945,18.6236Z"></path></svg>', 'amazon' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M13.582,8.182C11.934,8.367,9.78,8.49,8.238,9.166c-1.781,0.769-3.03,2.337-3.03,4.644 c0,2.953,1.86,4.429,4.253,4.429c2.02,0,3.125-0.477,4.685-2.065c0.516,0.747,0.685,1.109,1.629,1.894 c0.212,0.114,0.483,0.103,0.672-0.066l0.006,0.006c0.567-0.505,1.599-1.401,2.18-1.888c0.231-0.188,0.19-0.496,0.009-0.754 c-0.52-0.718-1.072-1.303-1.072-2.634V8.305c0-1.876,0.133-3.599-1.249-4.891C15.23,2.369,13.422,2,12.04,2 C9.336,2,6.318,3.01,5.686,6.351C5.618,6.706,5.877,6.893,6.109,6.945l2.754,0.298C9.121,7.23,9.308,6.977,9.357,6.72 c0.236-1.151,1.2-1.706,2.284-1.706c0.584,0,1.249,0.215,1.595,0.738c0.398,0.584,0.346,1.384,0.346,2.061V8.182z M13.049,14.088 c-0.451,0.8-1.169,1.291-1.967,1.291c-1.09,0-1.728-0.83-1.728-2.061c0-2.42,2.171-2.86,4.227-2.86v0.615 C13.582,12.181,13.608,13.104,13.049,14.088z M20.683,19.339C18.329,21.076,14.917,22,11.979,22c-4.118,0-7.826-1.522-10.632-4.057 c-0.22-0.199-0.024-0.471,0.241-0.317c3.027,1.762,6.771,2.823,10.639,2.823c2.608,0,5.476-0.541,8.115-1.66 C20.739,18.62,21.072,19.051,20.683,19.339z M21.336,21.043c-0.194,0.163-0.379,0.076-0.293-0.139 c0.284-0.71,0.92-2.298,0.619-2.684c-0.301-0.386-1.99-0.183-2.749-0.092c-0.23,0.027-0.266-0.173-0.059-0.319 c1.348-0.946,3.555-0.673,3.811-0.356C22.925,17.773,22.599,19.986,21.336,21.043z"></path></svg>', 'bandcamp' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M15.27 17.289 3 17.289 8.73 6.711 21 6.711 15.27 17.289"></path></svg>', 'behance' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M7.799,5.698c0.589,0,1.12,0.051,1.606,0.156c0.482,0.102,0.894,0.273,1.241,0.507c0.344,0.235,0.612,0.546,0.804,0.938 c0.188,0.387,0.281,0.871,0.281,1.443c0,0.619-0.141,1.137-0.421,1.551c-0.284,0.413-0.7,0.751-1.255,1.014 c0.756,0.218,1.317,0.601,1.689,1.146c0.374,0.549,0.557,1.205,0.557,1.975c0,0.623-0.12,1.161-0.359,1.612 c-0.241,0.457-0.569,0.828-0.973,1.114c-0.408,0.288-0.876,0.5-1.399,0.637C9.052,17.931,8.514,18,7.963,18H2V5.698H7.799 M7.449,10.668c0.481,0,0.878-0.114,1.192-0.345c0.311-0.228,0.463-0.603,0.463-1.119c0-0.286-0.051-0.523-0.152-0.707 C8.848,8.315,8.711,8.171,8.536,8.07C8.362,7.966,8.166,7.894,7.94,7.854c-0.224-0.044-0.457-0.06-0.697-0.06H4.709v2.874H7.449z M7.6,15.905c0.267,0,0.521-0.024,0.759-0.077c0.243-0.053,0.457-0.137,0.637-0.261c0.182-0.12,0.332-0.283,0.441-0.491 C9.547,14.87,9.6,14.602,9.6,14.278c0-0.633-0.18-1.084-0.533-1.357c-0.356-0.27-0.83-0.404-1.413-0.404H4.709v3.388L7.6,15.905z M16.162,15.864c0.367,0.358,0.897,0.538,1.583,0.538c0.493,0,0.92-0.125,1.277-0.374c0.354-0.248,0.571-0.514,0.654-0.79h2.155 c-0.347,1.072-0.872,1.838-1.589,2.299C19.534,18,18.67,18.23,17.662,18.23c-0.701,0-1.332-0.113-1.899-0.337 c-0.567-0.227-1.041-0.544-1.439-0.958c-0.389-0.415-0.689-0.907-0.904-1.484c-0.213-0.574-0.32-1.21-0.32-1.899 c0-0.666,0.11-1.288,0.329-1.863c0.222-0.577,0.529-1.075,0.933-1.492c0.406-0.42,0.885-0.751,1.444-0.994 c0.558-0.241,1.175-0.363,1.857-0.363c0.754,0,1.414,0.145,1.98,0.44c0.563,0.291,1.026,0.686,1.389,1.181 c0.363,0.493,0.622,1.057,0.783,1.69c0.16,0.632,0.217,1.292,0.171,1.983h-6.428C15.557,14.84,15.795,15.506,16.162,15.864 M18.973,11.184c-0.291-0.321-0.783-0.496-1.384-0.496c-0.39,0-0.714,0.066-0.973,0.2c-0.254,0.132-0.461,0.297-0.621,0.491 c-0.157,0.197-0.265,0.405-0.328,0.628c-0.063,0.217-0.101,0.413-0.111,0.587h3.98C19.478,11.969,19.265,11.509,18.973,11.184z M15.057,7.738h4.985V6.524h-4.985L15.057,7.738z"></path></svg>', 'codepen' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22.016,8.84c-0.002-0.013-0.005-0.025-0.007-0.037c-0.005-0.025-0.008-0.048-0.015-0.072 c-0.003-0.015-0.01-0.028-0.013-0.042c-0.008-0.02-0.015-0.04-0.023-0.062c-0.007-0.015-0.013-0.028-0.02-0.042 c-0.008-0.02-0.018-0.037-0.03-0.057c-0.007-0.013-0.017-0.027-0.025-0.038c-0.012-0.018-0.023-0.035-0.035-0.052 c-0.01-0.013-0.02-0.025-0.03-0.037c-0.015-0.017-0.028-0.032-0.043-0.045c-0.01-0.012-0.022-0.023-0.035-0.035 c-0.015-0.015-0.032-0.028-0.048-0.04c-0.012-0.01-0.025-0.02-0.037-0.03c-0.005-0.003-0.01-0.008-0.015-0.012l-9.161-6.096 c-0.289-0.192-0.666-0.192-0.955,0L2.359,8.237C2.354,8.24,2.349,8.245,2.344,8.249L2.306,8.277 c-0.017,0.013-0.033,0.027-0.048,0.04C2.246,8.331,2.234,8.342,2.222,8.352c-0.015,0.015-0.028,0.03-0.042,0.047 c-0.012,0.013-0.022,0.023-0.03,0.037C2.139,8.453,2.125,8.471,2.115,8.488C2.107,8.501,2.099,8.514,2.09,8.526 C2.079,8.548,2.069,8.565,2.06,8.585C2.054,8.6,2.047,8.613,2.04,8.626C2.032,8.648,2.025,8.67,2.019,8.69 c-0.005,0.013-0.01,0.027-0.013,0.042C1.999,8.755,1.995,8.778,1.99,8.803C1.989,8.817,1.985,8.828,1.984,8.84 C1.978,8.879,1.975,8.915,1.975,8.954v6.093c0,0.037,0.003,0.075,0.008,0.112c0.002,0.012,0.005,0.025,0.007,0.038 c0.005,0.023,0.008,0.047,0.015,0.072c0.003,0.015,0.008,0.028,0.013,0.04c0.007,0.022,0.013,0.042,0.022,0.063 c0.007,0.015,0.013,0.028,0.02,0.04c0.008,0.02,0.018,0.038,0.03,0.058c0.007,0.013,0.015,0.027,0.025,0.038 c0.012,0.018,0.023,0.035,0.035,0.052c0.01,0.013,0.02,0.025,0.03,0.037c0.013,0.015,0.028,0.032,0.042,0.045 c0.012,0.012,0.023,0.023,0.035,0.035c0.015,0.013,0.032,0.028,0.048,0.04l0.038,0.03c0.005,0.003,0.01,0.007,0.013,0.01 l9.163,6.095C11.668,21.953,11.833,22,12,22c0.167,0,0.332-0.047,0.478-0.144l9.163-6.095l0.015-0.01 c0.013-0.01,0.027-0.02,0.037-0.03c0.018-0.013,0.035-0.028,0.048-0.04c0.013-0.012,0.025-0.023,0.035-0.035 c0.017-0.015,0.03-0.032,0.043-0.045c0.01-0.013,0.02-0.025,0.03-0.037c0.013-0.018,0.025-0.035,0.035-0.052 c0.008-0.013,0.018-0.027,0.025-0.038c0.012-0.02,0.022-0.038,0.03-0.058c0.007-0.013,0.013-0.027,0.02-0.04 c0.008-0.022,0.015-0.042,0.023-0.063c0.003-0.013,0.01-0.027,0.013-0.04c0.007-0.025,0.01-0.048,0.015-0.072 c0.002-0.013,0.005-0.027,0.007-0.037c0.003-0.042,0.007-0.079,0.007-0.117V8.954C22.025,8.915,22.022,8.879,22.016,8.84z M12.862,4.464l6.751,4.49l-3.016,2.013l-3.735-2.492V4.464z M11.138,4.464v4.009l-3.735,2.494L4.389,8.954L11.138,4.464z M3.699,10.562L5.853,12l-2.155,1.438V10.562z M11.138,19.536l-6.749-4.491l3.015-2.011l3.735,2.492V19.536z M12,14.035L8.953,12 L12,9.966L15.047,12L12,14.035z M12.862,19.536v-4.009l3.735-2.492l3.016,2.011L12.862,19.536z M20.303,13.438L18.147,12 l2.156-1.438L20.303,13.438z"></path></svg>', 'deviantart' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M 18.19 5.636 18.19 2 18.188 2 14.553 2 14.19 2.366 12.474 5.636 11.935 6 5.81 6 5.81 10.994 9.177 10.994 9.477 11.357 5.81 18.363 5.81 22 5.811 22 9.447 22 9.81 21.634 11.526 18.364 12.065 18 18.19 18 18.19 13.006 14.823 13.006 14.523 12.641 18.19 5.636z"></path></svg>', 'dribbble' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,22C6.486,22,2,17.514,2,12S6.486,2,12,2c5.514,0,10,4.486,10,10S17.514,22,12,22z M20.434,13.369 c-0.292-0.092-2.644-0.794-5.32-0.365c1.117,3.07,1.572,5.57,1.659,6.09C18.689,17.798,20.053,15.745,20.434,13.369z M15.336,19.876c-0.127-0.749-0.623-3.361-1.822-6.477c-0.019,0.006-0.038,0.013-0.056,0.019c-4.818,1.679-6.547,5.02-6.701,5.334 c1.448,1.129,3.268,1.803,5.243,1.803C13.183,20.555,14.311,20.313,15.336,19.876z M5.654,17.724 c0.193-0.331,2.538-4.213,6.943-5.637c0.111-0.036,0.224-0.07,0.337-0.102c-0.214-0.485-0.448-0.971-0.692-1.45 c-4.266,1.277-8.405,1.223-8.778,1.216c-0.003,0.087-0.004,0.174-0.004,0.261C3.458,14.207,4.29,16.21,5.654,17.724z M3.639,10.264 c0.382,0.005,3.901,0.02,7.897-1.041c-1.415-2.516-2.942-4.631-3.167-4.94C5.979,5.41,4.193,7.613,3.639,10.264z M9.998,3.709 c0.236,0.316,1.787,2.429,3.187,5c3.037-1.138,4.323-2.867,4.477-3.085C16.154,4.286,14.17,3.471,12,3.471 C11.311,3.471,10.641,3.554,9.998,3.709z M18.612,6.612C18.432,6.855,17,8.69,13.842,9.979c0.199,0.407,0.389,0.821,0.567,1.237 c0.063,0.148,0.124,0.295,0.184,0.441c2.842-0.357,5.666,0.215,5.948,0.275C20.522,9.916,19.801,8.065,18.612,6.612z"></path></svg>', 'dropbox' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,6.134L6.069,9.797L2,6.54l5.883-3.843L12,6.134z M2,13.054l5.883,3.843L12,13.459L6.069,9.797L2,13.054z M12,13.459 l4.116,3.439L22,13.054l-4.069-3.257L12,13.459z M22,6.54l-5.884-3.843L12,6.134l5.931,3.663L22,6.54z M12.011,14.2l-4.129,3.426 l-1.767-1.153v1.291l5.896,3.539l5.897-3.539v-1.291l-1.769,1.153L12.011,14.2z"></path></svg>', 'etsy' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M9.16033,4.038c0-.27174.02717-.43478.48913-.43478h6.22283c1.087,0,1.68478.92391,2.11957,2.663l.35326,1.38587h1.05978C19.59511,3.712,19.75815,2,19.75815,2s-2.663.29891-4.23913.29891h-7.962L3.29076,2.163v1.1413L4.731,3.57609c1.00543.19022,1.25.40761,1.33152,1.33152,0,0,.08152,2.71739.08152,7.20109s-.08152,7.17391-.08152,7.17391c0,.81522-.32609,1.11413-1.33152,1.30435l-1.44022.27174V22l4.2663-.13587h7.11957c1.60326,0,5.32609.13587,5.32609.13587.08152-.97826.625-5.40761.70652-5.89674H19.7038L18.644,18.52174c-.84239,1.90217-2.06522,2.038-3.42391,2.038H11.1712c-1.3587,0-2.01087-.54348-2.01087-1.712V12.65217s3.0163,0,3.99457.08152c.76087.05435,1.22283.27174,1.46739,1.33152l.32609,1.413h1.16848l-.08152-3.55978.163-3.587H15.02989l-.38043,1.57609c-.24457,1.03261-.40761,1.22283-1.46739,1.33152-1.38587.13587-4.02174.1087-4.02174.1087Z"></path></svg>', 'facebook' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg>', 'feed' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M2,8.667V12c5.515,0,10,4.485,10,10h3.333C15.333,14.637,9.363,8.667,2,8.667z M2,2v3.333 c9.19,0,16.667,7.477,16.667,16.667H22C22,10.955,13.045,2,2,2z M4.5,17C3.118,17,2,18.12,2,19.5S3.118,22,4.5,22S7,20.88,7,19.5 S5.882,17,4.5,17z"></path></svg>', 'flickr' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M6.5,7c-2.75,0-5,2.25-5,5s2.25,5,5,5s5-2.25,5-5S9.25,7,6.5,7z M17.5,7c-2.75,0-5,2.25-5,5s2.25,5,5,5s5-2.25,5-5 S20.25,7,17.5,7z"></path></svg>', 'foursquare' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M17.573,2c0,0-9.197,0-10.668,0S5,3.107,5,3.805s0,16.948,0,16.948c0,0.785,0.422,1.077,0.66,1.172 c0.238,0.097,0.892,0.177,1.285-0.275c0,0,5.035-5.843,5.122-5.93c0.132-0.132,0.132-0.132,0.262-0.132h3.26 c1.368,0,1.588-0.977,1.732-1.552c0.078-0.318,0.692-3.428,1.225-6.122l0.675-3.368C19.56,2.893,19.14,2,17.573,2z M16.495,7.22 c-0.053,0.252-0.372,0.518-0.665,0.518c-0.293,0-4.157,0-4.157,0c-0.467,0-0.802,0.318-0.802,0.787v0.508 c0,0.467,0.337,0.798,0.805,0.798c0,0,3.197,0,3.528,0s0.655,0.362,0.583,0.715c-0.072,0.353-0.407,2.102-0.448,2.295 c-0.04,0.193-0.262,0.523-0.655,0.523c-0.33,0-2.88,0-2.88,0c-0.523,0-0.683,0.068-1.033,0.503 c-0.35,0.437-3.505,4.223-3.505,4.223c-0.032,0.035-0.063,0.027-0.063-0.015V4.852c0-0.298,0.26-0.648,0.648-0.648 c0,0,8.228,0,8.562,0c0.315,0,0.61,0.297,0.528,0.683L16.495,7.22z"></path></svg>', 'goodreads' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M17.3,17.5c-0.2,0.8-0.5,1.4-1,1.9c-0.4,0.5-1,0.9-1.7,1.2C13.9,20.9,13.1,21,12,21c-0.6,0-1.3-0.1-1.9-0.2 c-0.6-0.1-1.1-0.4-1.6-0.7c-0.5-0.3-0.9-0.7-1.2-1.2c-0.3-0.5-0.5-1.1-0.5-1.7h1.5c0.1,0.5,0.2,0.9,0.5,1.2 c0.2,0.3,0.5,0.6,0.9,0.8c0.3,0.2,0.7,0.3,1.1,0.4c0.4,0.1,0.8,0.1,1.2,0.1c1.4,0,2.5-0.4,3.1-1.2c0.6-0.8,1-2,1-3.5v-1.7h0 c-0.4,0.8-0.9,1.4-1.6,1.9c-0.7,0.5-1.5,0.7-2.4,0.7c-1,0-1.9-0.2-2.6-0.5C8.7,15,8.1,14.5,7.7,14c-0.5-0.6-0.8-1.3-1-2.1 c-0.2-0.8-0.3-1.6-0.3-2.5c0-0.9,0.1-1.7,0.4-2.5c0.3-0.8,0.6-1.5,1.1-2c0.5-0.6,1.1-1,1.8-1.4C10.3,3.2,11.1,3,12,3 c0.5,0,0.9,0.1,1.3,0.2c0.4,0.1,0.8,0.3,1.1,0.5c0.3,0.2,0.6,0.5,0.9,0.8c0.3,0.3,0.5,0.6,0.6,1h0V3.4h1.5V15 C17.6,15.9,17.5,16.7,17.3,17.5z M13.8,14.1c0.5-0.3,0.9-0.7,1.3-1.1c0.3-0.5,0.6-1,0.8-1.6c0.2-0.6,0.3-1.2,0.3-1.9 c0-0.6-0.1-1.2-0.2-1.9c-0.1-0.6-0.4-1.2-0.7-1.7c-0.3-0.5-0.7-0.9-1.3-1.2c-0.5-0.3-1.1-0.5-1.9-0.5s-1.4,0.2-1.9,0.5 c-0.5,0.3-1,0.7-1.3,1.2C8.5,6.4,8.3,7,8.1,7.6C8,8.2,7.9,8.9,7.9,9.5c0,0.6,0.1,1.3,0.2,1.9C8.3,12,8.6,12.5,8.9,13 c0.3,0.5,0.8,0.8,1.3,1.1c0.5,0.3,1.1,0.4,1.9,0.4C12.7,14.5,13.3,14.4,13.8,14.1z"></path></svg>', 'google' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.02,10.18v3.72v0.01h5.51c-0.26,1.57-1.67,4.22-5.5,4.22c-3.31,0-6.01-2.75-6.01-6.12s2.7-6.12,6.01-6.12 c1.87,0,3.13,0.8,3.85,1.48l2.84-2.76C16.99,2.99,14.73,2,12.03,2c-5.52,0-10,4.48-10,10s4.48,10,10,10c5.77,0,9.6-4.06,9.6-9.77 c0-0.83-0.11-1.42-0.25-2.05H12.02z"></path></svg>', 'github' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg>', 'instagram' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,4.622c2.403,0,2.688,0.009,3.637,0.052c0.877,0.04,1.354,0.187,1.671,0.31c0.42,0.163,0.72,0.358,1.035,0.673 c0.315,0.315,0.51,0.615,0.673,1.035c0.123,0.317,0.27,0.794,0.31,1.671c0.043,0.949,0.052,1.234,0.052,3.637 s-0.009,2.688-0.052,3.637c-0.04,0.877-0.187,1.354-0.31,1.671c-0.163,0.42-0.358,0.72-0.673,1.035 c-0.315,0.315-0.615,0.51-1.035,0.673c-0.317,0.123-0.794,0.27-1.671,0.31c-0.949,0.043-1.233,0.052-3.637,0.052 s-2.688-0.009-3.637-0.052c-0.877-0.04-1.354-0.187-1.671-0.31c-0.42-0.163-0.72-0.358-1.035-0.673 c-0.315-0.315-0.51-0.615-0.673-1.035c-0.123-0.317-0.27-0.794-0.31-1.671C4.631,14.688,4.622,14.403,4.622,12 s0.009-2.688,0.052-3.637c0.04-0.877,0.187-1.354,0.31-1.671c0.163-0.42,0.358-0.72,0.673-1.035 c0.315-0.315,0.615-0.51,1.035-0.673c0.317-0.123,0.794-0.27,1.671-0.31C9.312,4.631,9.597,4.622,12,4.622 M12,3 C9.556,3,9.249,3.01,8.289,3.054C7.331,3.098,6.677,3.25,6.105,3.472C5.513,3.702,5.011,4.01,4.511,4.511 c-0.5,0.5-0.808,1.002-1.038,1.594C3.25,6.677,3.098,7.331,3.054,8.289C3.01,9.249,3,9.556,3,12c0,2.444,0.01,2.751,0.054,3.711 c0.044,0.958,0.196,1.612,0.418,2.185c0.23,0.592,0.538,1.094,1.038,1.594c0.5,0.5,1.002,0.808,1.594,1.038 c0.572,0.222,1.227,0.375,2.185,0.418C9.249,20.99,9.556,21,12,21s2.751-0.01,3.711-0.054c0.958-0.044,1.612-0.196,2.185-0.418 c0.592-0.23,1.094-0.538,1.594-1.038c0.5-0.5,0.808-1.002,1.038-1.594c0.222-0.572,0.375-1.227,0.418-2.185 C20.99,14.751,21,14.444,21,12s-0.01-2.751-0.054-3.711c-0.044-0.958-0.196-1.612-0.418-2.185c-0.23-0.592-0.538-1.094-1.038-1.594 c-0.5-0.5-1.002-0.808-1.594-1.038c-0.572-0.222-1.227-0.375-2.185-0.418C14.751,3.01,14.444,3,12,3L12,3z M12,7.378 c-2.552,0-4.622,2.069-4.622,4.622S9.448,16.622,12,16.622s4.622-2.069,4.622-4.622S14.552,7.378,12,7.378z M12,15 c-1.657,0-3-1.343-3-3s1.343-3,3-3s3,1.343,3,3S13.657,15,12,15z M16.804,6.116c-0.596,0-1.08,0.484-1.08,1.08 s0.484,1.08,1.08,1.08c0.596,0,1.08-0.484,1.08-1.08S17.401,6.116,16.804,6.116z"></path></svg>', 'lastfm' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M10.5002,0 C4.7006,0 0,4.70109753 0,10.4998496 C0,16.2989526 4.7006,21 10.5002,21 C16.299,21 21,16.2989526 21,10.4998496 C21,4.70109753 16.299,0 10.5002,0 Z M14.69735,14.7204413 C13.3164,14.7151781 12.4346,14.0870017 11.83445,12.6859357 L11.6816001,12.3451305 L10.35405,9.31011397 C9.92709997,8.26875064 8.85260001,7.57120012 7.68010001,7.57120012 C6.06945001,7.57120012 4.75925001,8.88509738 4.75925001,10.5009524 C4.75925001,12.1164565 6.06945001,13.4303036 7.68010001,13.4303036 C8.77200001,13.4303036 9.76514999,12.827541 10.2719501,11.8567047 C10.2893,11.8235214 10.3239,11.8019673 10.36305,11.8038219 C10.4007,11.8053759 10.43535,11.8287847 10.4504,11.8631709 L10.98655,13.1045863 C11.0016,13.1389726 10.9956,13.17782 10.97225,13.2068931 C10.1605001,14.1995341 8.96020001,14.7683115 7.68010001,14.7683115 C5.33305,14.7683115 3.42340001,12.8535563 3.42340001,10.5009524 C3.42340001,8.14679459 5.33300001,6.23203946 7.68010001,6.23203946 C9.45720002,6.23203946 10.8909,7.19074535 11.6138,8.86359341 C11.6205501,8.88018505 12.3412,10.5707777 12.97445,12.0190621 C13.34865,12.8739575 13.64615,13.3959676 14.6288,13.4291508 C15.5663001,13.4612814 16.25375,12.9121534 16.25375,12.1484869 C16.25375,11.4691321 15.8320501,11.3003585 14.8803,10.98216 C13.2365,10.4397989 12.34495,9.88605929 12.34495,8.51817658 C12.34495,7.1809207 13.26665,6.31615054 14.692,6.31615054 C15.62875,6.31615054 16.3155,6.7286858 16.79215,7.5768142 C16.80495,7.60062396 16.8079001,7.62814302 16.8004001,7.65420843 C16.7929,7.68027384 16.7748,7.70212868 16.7507001,7.713808 L15.86145,8.16900031 C15.8178001,8.19200805 15.7643,8.17807308 15.73565,8.13847371 C15.43295,7.71345711 15.0956,7.52513451 14.6423,7.52513451 C14.05125,7.52513451 13.6220001,7.92899802 13.6220001,8.48649708 C13.6220001,9.17382194 14.1529001,9.34144259 15.0339,9.61923972 C15.14915,9.65578139 15.26955,9.69397731 15.39385,9.73432853 C16.7763,10.1865133 17.57675,10.7311301 17.57675,12.1836251 C17.57685,13.629654 16.3389,14.7204413 14.69735,14.7204413 Z"></path></svg>', 'linkedin' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg>', 'mail' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M20,4H4C2.895,4,2,4.895,2,6v12c0,1.105,0.895,2,2,2h16c1.105,0,2-0.895,2-2V6C22,4.895,21.105,4,20,4z M20,8.236l-8,4.882 L4,8.236V6h16V8.236z"></path></svg>', 'mastodon' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M23.193 7.879c0-5.206-3.411-6.732-3.411-6.732C18.062.357 15.108.025 12.041 0h-.076c-3.068.025-6.02.357-7.74 1.147 0 0-3.411 1.526-3.411 6.732 0 1.192-.023 2.618.015 4.129.124 5.092.934 10.109 5.641 11.355 2.17.574 4.034.695 5.535.612 2.722-.15 4.25-.972 4.25-.972l-.09-1.975s-1.945.613-4.129.539c-2.165-.074-4.449-.233-4.799-2.891a5.499 5.499 0 0 1-.048-.745s2.125.52 4.817.643c1.646.075 3.19-.097 4.758-.283 3.007-.359 5.625-2.212 5.954-3.905.517-2.665.475-6.507.475-6.507zm-4.024 6.709h-2.497V8.469c0-1.29-.543-1.944-1.628-1.944-1.2 0-1.802.776-1.802 2.312v3.349h-2.483v-3.35c0-1.536-.602-2.312-1.802-2.312-1.085 0-1.628.655-1.628 1.944v6.119H4.832V8.284c0-1.289.328-2.313.987-3.07.68-.758 1.569-1.146 2.674-1.146 1.278 0 2.246.491 2.886 1.474L12 6.585l.622-1.043c.64-.983 1.608-1.474 2.886-1.474 1.104 0 1.994.388 2.674 1.146.658.757.986 1.781.986 3.07v6.304z"/></svg>', 'medium' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M20.962,7.257l-5.457,8.867l-3.923-6.375l3.126-5.08c0.112-0.182,0.319-0.286,0.527-0.286c0.05,0,0.1,0.008,0.149,0.02 c0.039,0.01,0.078,0.023,0.114,0.041l5.43,2.715l0.006,0.003c0.004,0.002,0.007,0.006,0.011,0.008 C20.971,7.191,20.98,7.227,20.962,7.257z M9.86,8.592v5.783l5.14,2.57L9.86,8.592z M15.772,17.331l4.231,2.115 C20.554,19.721,21,19.529,21,19.016V8.835L15.772,17.331z M8.968,7.178L3.665,4.527C3.569,4.479,3.478,4.456,3.395,4.456 C3.163,4.456,3,4.636,3,4.938v11.45c0,0.306,0.224,0.669,0.498,0.806l4.671,2.335c0.12,0.06,0.234,0.088,0.337,0.088 c0.29,0,0.494-0.225,0.494-0.602V7.231C9,7.208,8.988,7.188,8.968,7.178z"></path></svg>', 'meetup' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M19.24775,14.722a3.57032,3.57032,0,0,1-2.94457,3.52073,3.61886,3.61886,0,0,1-.64652.05634c-.07314-.0008-.10187.02846-.12507.09547A2.38881,2.38881,0,0,1,13.49453,20.094a2.33092,2.33092,0,0,1-1.827-.50716.13635.13635,0,0,0-.19878-.00408,3.191,3.191,0,0,1-2.104.60248,3.26309,3.26309,0,0,1-3.00324-2.71993,2.19076,2.19076,0,0,1-.03512-.30865c-.00156-.08579-.03413-.1189-.11608-.13493a2.86421,2.86421,0,0,1-1.23189-.56111,2.945,2.945,0,0,1-1.166-2.05749,2.97484,2.97484,0,0,1,.87524-2.50774.112.112,0,0,0,.02091-.16107,2.7213,2.7213,0,0,1-.36648-1.48A2.81256,2.81256,0,0,1,6.57673,7.58838a.35764.35764,0,0,0,.28869-.22819,4.2208,4.2208,0,0,1,6.02892-1.90111.25161.25161,0,0,0,.22023.0243,3.65608,3.65608,0,0,1,3.76031.90678A3.57244,3.57244,0,0,1,17.95918,8.626a2.97339,2.97339,0,0,1,.01829.57356.10637.10637,0,0,0,.0853.12792,1.97669,1.97669,0,0,1,1.27939,1.33733,2.00266,2.00266,0,0,1-.57112,2.12652c-.05284.05166-.04168.08328-.01173.13489A3.51189,3.51189,0,0,1,19.24775,14.722Zm-6.35959-.27836a1.6984,1.6984,0,0,0,1.14556,1.61113,3.82039,3.82039,0,0,0,1.036.17935,1.46888,1.46888,0,0,0,.73509-.12255.44082.44082,0,0,0,.26057-.44274.45312.45312,0,0,0-.29211-.43375.97191.97191,0,0,0-.20678-.063c-.21326-.03806-.42754-.0701-.63973-.11215a.54787.54787,0,0,1-.50172-.60926,2.75864,2.75864,0,0,1,.1773-.901c.1763-.535.414-1.045.64183-1.55913A12.686,12.686,0,0,0,15.85,10.47863a1.58461,1.58461,0,0,0,.04861-.87208,1.04531,1.04531,0,0,0-.85432-.83981,1.60658,1.60658,0,0,0-1.23654.16594.27593.27593,0,0,1-.36286-.03413c-.085-.0747-.16594-.15379-.24918-.23055a.98682.98682,0,0,0-1.33577-.04933,6.1468,6.1468,0,0,1-.4989.41615.47762.47762,0,0,1-.51535.03566c-.17448-.09307-.35512-.175-.53531-.25665a1.74949,1.74949,0,0,0-.56476-.2016,1.69943,1.69943,0,0,0-1.61654.91787,8.05815,8.05815,0,0,0-.32952.80126c-.45471,1.2557-.82507,2.53825-1.20838,3.81639a1.24151,1.24151,0,0,0,.51532,1.44389,1.42659,1.42659,0,0,0,1.22008.17166,1.09728,1.09728,0,0,0,.66994-.69764c.44145-1.04111.839-2.09989,1.25981-3.14926.11581-.28876.22792-.57874.35078-.86438a.44548.44548,0,0,1,.69189-.19539.50521.50521,0,0,1,.15044.43836,1.75625,1.75625,0,0,1-.14731.50453c-.27379.69219-.55265,1.38236-.82766,2.074a2.0836,2.0836,0,0,0-.14038.42876.50719.50719,0,0,0,.27082.57722.87236.87236,0,0,0,.66145.02739.99137.99137,0,0,0,.53406-.532q.61571-1.20914,1.228-2.42031.28423-.55863.57585-1.1133a.87189.87189,0,0,1,.29055-.35253.34987.34987,0,0,1,.37634-.01265.30291.30291,0,0,1,.12434.31459.56716.56716,0,0,1-.04655.1915c-.05318.12739-.10286.25669-.16183.38156-.34118.71775-.68754,1.43273-1.02568,2.152A2.00213,2.00213,0,0,0,12.88816,14.44366Zm4.78568,5.28972a.88573.88573,0,0,0-1.77139.00465.8857.8857,0,0,0,1.77139-.00465Zm-14.83838-7.296a.84329.84329,0,1,0,.00827-1.68655.8433.8433,0,0,0-.00827,1.68655Zm10.366-9.43673a.83506.83506,0,1,0-.0091,1.67.83505.83505,0,0,0,.0091-1.67Zm6.85014,5.22a.71651.71651,0,0,0-1.433.0093.71656.71656,0,0,0,1.433-.0093ZM5.37528,6.17908A.63823.63823,0,1,0,6.015,5.54483.62292.62292,0,0,0,5.37528,6.17908Zm6.68214,14.80843a.54949.54949,0,1,0-.55052.541A.54556.54556,0,0,0,12.05742,20.98752Zm8.53235-8.49689a.54777.54777,0,0,0-.54027.54023.53327.53327,0,0,0,.532.52293.51548.51548,0,0,0,.53272-.5237A.53187.53187,0,0,0,20.58977,12.49063ZM7.82846,2.4715a.44927.44927,0,1,0,.44484.44766A.43821.43821,0,0,0,7.82846,2.4715Zm13.775,7.60492a.41186.41186,0,0,0-.40065.39623.40178.40178,0,0,0,.40168.40168A.38994.38994,0,0,0,22,10.48172.39946.39946,0,0,0,21.60349,10.07642ZM5.79193,17.96207a.40469.40469,0,0,0-.397-.39646.399.399,0,0,0-.396.405.39234.39234,0,0,0,.39939.389A.39857.39857,0,0,0,5.79193,17.96207Z"></path></svg>', 'pinterest' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.289,2C6.617,2,3.606,5.648,3.606,9.622c0,1.846,1.025,4.146,2.666,4.878c0.25,0.111,0.381,0.063,0.439-0.169 c0.044-0.175,0.267-1.029,0.365-1.428c0.032-0.128,0.017-0.237-0.091-0.362C6.445,11.911,6.01,10.75,6.01,9.668 c0-2.777,2.194-5.464,5.933-5.464c3.23,0,5.49,2.108,5.49,5.122c0,3.407-1.794,5.768-4.13,5.768c-1.291,0-2.257-1.021-1.948-2.277 c0.372-1.495,1.089-3.112,1.089-4.191c0-0.967-0.542-1.775-1.663-1.775c-1.319,0-2.379,1.309-2.379,3.059 c0,1.115,0.394,1.869,0.394,1.869s-1.302,5.279-1.54,6.261c-0.405,1.666,0.053,4.368,0.094,4.604 c0.021,0.126,0.167,0.169,0.25,0.063c0.129-0.165,1.699-2.419,2.142-4.051c0.158-0.59,0.817-2.995,0.817-2.995 c0.43,0.784,1.681,1.446,3.013,1.446c3.963,0,6.822-3.494,6.822-7.833C20.394,5.112,16.849,2,12.289,2"></path></svg>', 'pocket' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M21.927,4.194C21.667,3.48,20.982,3,20.222,3h-0.01h-1.721H3.839C3.092,3,2.411,3.47,2.145,4.17 C2.066,4.378,2.026,4.594,2.026,4.814v6.035l0.069,1.2c0.29,2.73,1.707,5.115,3.899,6.778c0.039,0.03,0.079,0.059,0.119,0.089 l0.025,0.018c1.175,0.859,2.491,1.441,3.91,1.727c0.655,0.132,1.325,0.2,1.991,0.2c0.615,0,1.232-0.057,1.839-0.17 c0.073-0.014,0.145-0.028,0.219-0.044c0.02-0.004,0.042-0.012,0.064-0.023c1.359-0.297,2.621-0.864,3.753-1.691l0.025-0.018 c0.04-0.029,0.08-0.058,0.119-0.089c2.192-1.664,3.609-4.049,3.898-6.778l0.069-1.2V4.814C22.026,4.605,22,4.398,21.927,4.194z M17.692,10.481l-4.704,4.512c-0.266,0.254-0.608,0.382-0.949,0.382c-0.342,0-0.684-0.128-0.949-0.382l-4.705-4.512 C5.838,9.957,5.82,9.089,6.344,8.542c0.524-0.547,1.392-0.565,1.939-0.04l3.756,3.601l3.755-3.601 c0.547-0.524,1.415-0.506,1.939,0.04C18.256,9.089,18.238,9.956,17.692,10.481z"></path></svg>', 'reddit' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22,11.816c0-1.256-1.021-2.277-2.277-2.277c-0.593,0-1.122,0.24-1.526,0.614c-1.481-0.965-3.455-1.594-5.647-1.69 l1.171-3.702l3.18,0.748c0.008,1.028,0.846,1.862,1.876,1.862c1.035,0,1.877-0.842,1.877-1.878c0-1.035-0.842-1.877-1.877-1.877 c-0.769,0-1.431,0.466-1.72,1.13l-3.508-0.826c-0.203-0.047-0.399,0.067-0.46,0.261l-1.35,4.268 c-2.316,0.038-4.411,0.67-5.97,1.671C5.368,9.765,4.853,9.539,4.277,9.539C3.021,9.539,2,10.56,2,11.816 c0,0.814,0.433,1.523,1.078,1.925c-0.037,0.221-0.061,0.444-0.061,0.672c0,3.292,4.011,5.97,8.941,5.97s8.941-2.678,8.941-5.97 c0-0.214-0.02-0.424-0.053-0.632C21.533,13.39,22,12.661,22,11.816z M18.776,4.394c0.606,0,1.1,0.493,1.1,1.1s-0.493,1.1-1.1,1.1 s-1.1-0.494-1.1-1.1S18.169,4.394,18.776,4.394z M2.777,11.816c0-0.827,0.672-1.5,1.499-1.5c0.313,0,0.598,0.103,0.838,0.269 c-0.851,0.676-1.477,1.479-1.812,2.36C2.983,12.672,2.777,12.27,2.777,11.816z M11.959,19.606c-4.501,0-8.164-2.329-8.164-5.193 S7.457,9.22,11.959,9.22s8.164,2.329,8.164,5.193S16.46,19.606,11.959,19.606z M20.636,13.001c-0.326-0.89-0.948-1.701-1.797-2.384 c0.248-0.186,0.55-0.301,0.883-0.301c0.827,0,1.5,0.673,1.5,1.5C21.223,12.299,20.992,12.727,20.636,13.001z M8.996,14.704 c-0.76,0-1.397-0.616-1.397-1.376c0-0.76,0.637-1.397,1.397-1.397c0.76,0,1.376,0.637,1.376,1.397 C10.372,14.088,9.756,14.704,8.996,14.704z M16.401,13.328c0,0.76-0.616,1.376-1.376,1.376c-0.76,0-1.399-0.616-1.399-1.376 c0-0.76,0.639-1.397,1.399-1.397C15.785,11.931,16.401,12.568,16.401,13.328z M15.229,16.708c0.152,0.152,0.152,0.398,0,0.55 c-0.674,0.674-1.727,1.002-3.219,1.002c-0.004,0-0.007-0.002-0.011-0.002c-0.004,0-0.007,0.002-0.011,0.002 c-1.492,0-2.544-0.328-3.218-1.002c-0.152-0.152-0.152-0.398,0-0.55c0.152-0.152,0.399-0.151,0.55,0 c0.521,0.521,1.394,0.775,2.669,0.775c0.004,0,0.007,0.002,0.011,0.002c0.004,0,0.007-0.002,0.011-0.002 c1.275,0,2.148-0.253,2.669-0.775C14.831,16.556,15.078,16.556,15.229,16.708z"></path></svg>', 'skype' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M10.113,2.699c0.033-0.006,0.067-0.013,0.1-0.02c0.033,0.017,0.066,0.033,0.098,0.051L10.113,2.699z M2.72,10.223 c-0.006,0.034-0.011,0.069-0.017,0.103c0.018,0.032,0.033,0.064,0.051,0.095L2.72,10.223z M21.275,13.771 c0.007-0.035,0.011-0.071,0.018-0.106c-0.018-0.031-0.033-0.064-0.052-0.095L21.275,13.771z M13.563,21.199 c0.032,0.019,0.065,0.035,0.096,0.053c0.036-0.006,0.071-0.011,0.105-0.017L13.563,21.199z M22,16.386 c0,1.494-0.581,2.898-1.637,3.953c-1.056,1.057-2.459,1.637-3.953,1.637c-0.967,0-1.914-0.251-2.75-0.725 c0.036-0.006,0.071-0.011,0.105-0.017l-0.202-0.035c0.032,0.019,0.065,0.035,0.096,0.053c-0.543,0.096-1.099,0.147-1.654,0.147 c-1.275,0-2.512-0.25-3.676-0.743c-1.125-0.474-2.135-1.156-3.002-2.023c-0.867-0.867-1.548-1.877-2.023-3.002 c-0.493-1.164-0.743-2.401-0.743-3.676c0-0.546,0.049-1.093,0.142-1.628c0.018,0.032,0.033,0.064,0.051,0.095L2.72,10.223 c-0.006,0.034-0.011,0.069-0.017,0.103C2.244,9.5,2,8.566,2,7.615c0-1.493,0.582-2.898,1.637-3.953 c1.056-1.056,2.46-1.638,3.953-1.638c0.915,0,1.818,0.228,2.622,0.655c-0.033,0.007-0.067,0.013-0.1,0.02l0.199,0.031 c-0.032-0.018-0.066-0.034-0.098-0.051c0.002,0,0.003-0.001,0.004-0.001c0.586-0.112,1.187-0.169,1.788-0.169 c1.275,0,2.512,0.249,3.676,0.742c1.124,0.476,2.135,1.156,3.002,2.024c0.868,0.867,1.548,1.877,2.024,3.002 c0.493,1.164,0.743,2.401,0.743,3.676c0,0.575-0.054,1.15-0.157,1.712c-0.018-0.031-0.033-0.064-0.052-0.095l0.034,0.201 c0.007-0.035,0.011-0.071,0.018-0.106C21.754,14.494,22,15.432,22,16.386z M16.817,14.138c0-1.331-0.613-2.743-3.033-3.282 l-2.209-0.49c-0.84-0.192-1.807-0.444-1.807-1.237c0-0.794,0.679-1.348,1.903-1.348c2.468,0,2.243,1.696,3.468,1.696 c0.645,0,1.209-0.379,1.209-1.031c0-1.521-2.435-2.663-4.5-2.663c-2.242,0-4.63,0.952-4.63,3.488c0,1.221,0.436,2.521,2.839,3.123 l2.984,0.745c0.903,0.223,1.129,0.731,1.129,1.189c0,0.762-0.758,1.507-2.129,1.507c-2.679,0-2.307-2.062-3.743-2.062 c-0.645,0-1.113,0.444-1.113,1.078c0,1.236,1.501,2.886,4.856,2.886C15.236,17.737,16.817,16.199,16.817,14.138z"></path></svg>', 'snapchat' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.065,2a5.526,5.526,0,0,1,3.132.892A5.854,5.854,0,0,1,17.326,5.4a5.821,5.821,0,0,1,.351,2.33q0,.612-.117,2.487a.809.809,0,0,0,.365.091,1.93,1.93,0,0,0,.664-.176,1.93,1.93,0,0,1,.664-.176,1.3,1.3,0,0,1,.729.234.7.7,0,0,1,.351.6.839.839,0,0,1-.41.7,2.732,2.732,0,0,1-.9.41,3.192,3.192,0,0,0-.9.378.728.728,0,0,0-.41.618,1.575,1.575,0,0,0,.156.56,6.9,6.9,0,0,0,1.334,1.953,5.6,5.6,0,0,0,1.881,1.315,5.875,5.875,0,0,0,1.042.3.42.42,0,0,1,.365.456q0,.911-2.852,1.341a1.379,1.379,0,0,0-.143.507,1.8,1.8,0,0,1-.182.605.451.451,0,0,1-.429.241,5.878,5.878,0,0,1-.807-.085,5.917,5.917,0,0,0-.833-.085,4.217,4.217,0,0,0-.807.065,2.42,2.42,0,0,0-.82.293,6.682,6.682,0,0,0-.755.5q-.351.267-.755.527a3.886,3.886,0,0,1-.989.436A4.471,4.471,0,0,1,11.831,22a4.307,4.307,0,0,1-1.256-.176,3.784,3.784,0,0,1-.976-.436q-.4-.26-.749-.527a6.682,6.682,0,0,0-.755-.5,2.422,2.422,0,0,0-.807-.293,4.432,4.432,0,0,0-.82-.065,5.089,5.089,0,0,0-.853.1,5,5,0,0,1-.762.1.474.474,0,0,1-.456-.241,1.819,1.819,0,0,1-.182-.618,1.411,1.411,0,0,0-.143-.521q-2.852-.429-2.852-1.341a.42.42,0,0,1,.365-.456,5.793,5.793,0,0,0,1.042-.3,5.524,5.524,0,0,0,1.881-1.315,6.789,6.789,0,0,0,1.334-1.953A1.575,1.575,0,0,0,6,12.9a.728.728,0,0,0-.41-.618,3.323,3.323,0,0,0-.9-.384,2.912,2.912,0,0,1-.9-.41.814.814,0,0,1-.41-.684.71.71,0,0,1,.338-.593,1.208,1.208,0,0,1,.716-.241,1.976,1.976,0,0,1,.625.169,2.008,2.008,0,0,0,.69.169.919.919,0,0,0,.416-.091q-.117-1.849-.117-2.474A5.861,5.861,0,0,1,6.385,5.4,5.516,5.516,0,0,1,8.625,2.819,7.075,7.075,0,0,1,12.062,2Z"></path></svg>', 'soundcloud' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M8.9,16.1L9,14L8.9,9.5c0-0.1,0-0.1-0.1-0.1c0,0-0.1-0.1-0.1-0.1c-0.1,0-0.1,0-0.1,0.1c0,0-0.1,0.1-0.1,0.1L8.3,14l0.1,2.1 c0,0.1,0,0.1,0.1,0.1c0,0,0.1,0.1,0.1,0.1C8.8,16.3,8.9,16.3,8.9,16.1z M11.4,15.9l0.1-1.8L11.4,9c0-0.1,0-0.2-0.1-0.2 c0,0-0.1,0-0.1,0s-0.1,0-0.1,0c-0.1,0-0.1,0.1-0.1,0.2l0,0.1l-0.1,5c0,0,0,0.7,0.1,2v0c0,0.1,0,0.1,0.1,0.1c0.1,0.1,0.1,0.1,0.2,0.1 c0.1,0,0.1,0,0.2-0.1c0.1,0,0.1-0.1,0.1-0.2L11.4,15.9z M2.4,12.9L2.5,14l-0.2,1.1c0,0.1,0,0.1-0.1,0.1c0,0-0.1,0-0.1-0.1L2.1,14 l0.1-1.1C2.2,12.9,2.3,12.9,2.4,12.9C2.3,12.9,2.4,12.9,2.4,12.9z M3.1,12.2L3.3,14l-0.2,1.8c0,0.1,0,0.1-0.1,0.1 c-0.1,0-0.1,0-0.1-0.1L2.8,14L3,12.2C3,12.2,3,12.2,3.1,12.2C3.1,12.2,3.1,12.2,3.1,12.2z M3.9,11.9L4.1,14l-0.2,2.1 c0,0.1,0,0.1-0.1,0.1c-0.1,0-0.1,0-0.1-0.1L3.5,14l0.2-2.1c0-0.1,0-0.1,0.1-0.1C3.9,11.8,3.9,11.8,3.9,11.9z M4.7,11.9L4.9,14 l-0.2,2.1c0,0.1-0.1,0.1-0.1,0.1c-0.1,0-0.1,0-0.1-0.1L4.3,14l0.2-2.2c0-0.1,0-0.1,0.1-0.1C4.7,11.7,4.7,11.8,4.7,11.9z M5.6,12 l0.2,2l-0.2,2.1c0,0.1-0.1,0.1-0.1,0.1c0,0-0.1,0-0.1,0c0,0,0-0.1,0-0.1L5.1,14l0.2-2c0,0,0-0.1,0-0.1s0.1,0,0.1,0 C5.5,11.9,5.5,11.9,5.6,12L5.6,12z M6.4,10.7L6.6,14l-0.2,2.1c0,0,0,0.1,0,0.1c0,0-0.1,0-0.1,0c-0.1,0-0.1-0.1-0.2-0.2L5.9,14 l0.2-3.3c0-0.1,0.1-0.2,0.2-0.2c0,0,0.1,0,0.1,0C6.4,10.7,6.4,10.7,6.4,10.7z M7.2,10l0.2,4.1l-0.2,2.1c0,0,0,0.1,0,0.1 c0,0-0.1,0-0.1,0c-0.1,0-0.2-0.1-0.2-0.2l-0.1-2.1L6.8,10c0-0.1,0.1-0.2,0.2-0.2c0,0,0.1,0,0.1,0S7.2,9.9,7.2,10z M8,9.6L8.2,14 L8,16.1c0,0.1-0.1,0.2-0.2,0.2c-0.1,0-0.2-0.1-0.2-0.2L7.5,14l0.1-4.4c0-0.1,0-0.1,0.1-0.1c0,0,0.1-0.1,0.1-0.1c0.1,0,0.1,0,0.1,0.1 C8,9.6,8,9.6,8,9.6z M11.4,16.1L11.4,16.1L11.4,16.1z M9.7,9.6L9.8,14l-0.1,2.1c0,0.1,0,0.1-0.1,0.2s-0.1,0.1-0.2,0.1 c-0.1,0-0.1,0-0.1-0.1s-0.1-0.1-0.1-0.2L9.2,14l0.1-4.4c0-0.1,0-0.1,0.1-0.2s0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.2,0.1S9.7,9.5,9.7,9.6 L9.7,9.6z M10.6,9.8l0.1,4.3l-0.1,2c0,0.1,0,0.1-0.1,0.2c0,0-0.1,0.1-0.2,0.1c-0.1,0-0.1,0-0.2-0.1c0,0-0.1-0.1-0.1-0.2L10,14 l0.1-4.3c0-0.1,0-0.1,0.1-0.2c0,0,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.2,0.1S10.6,9.7,10.6,9.8z M12.4,14l-0.1,2c0,0.1,0,0.1-0.1,0.2 c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0-0.1,0-0.2-0.1c-0.1-0.1-0.1-0.1-0.1-0.2l-0.1-1l-0.1-1l0.1-5.5v0c0-0.1,0-0.2,0.1-0.2 c0.1,0,0.1-0.1,0.2-0.1c0,0,0.1,0,0.1,0c0.1,0,0.1,0.1,0.1,0.2L12.4,14z M22.1,13.9c0,0.7-0.2,1.3-0.7,1.7c-0.5,0.5-1.1,0.7-1.7,0.7 h-6.8c-0.1,0-0.1,0-0.2-0.1c-0.1-0.1-0.1-0.1-0.1-0.2V8.2c0-0.1,0.1-0.2,0.2-0.3c0.5-0.2,1-0.3,1.6-0.3c1.1,0,2.1,0.4,2.9,1.1 c0.8,0.8,1.3,1.7,1.4,2.8c0.3-0.1,0.6-0.2,1-0.2c0.7,0,1.3,0.2,1.7,0.7C21.8,12.6,22.1,13.2,22.1,13.9L22.1,13.9z"></path></svg>', 'spotify' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,2C6.477,2,2,6.477,2,12c0,5.523,4.477,10,10,10c5.523,0,10-4.477,10-10C22,6.477,17.523,2,12,2 M16.586,16.424 c-0.18,0.295-0.563,0.387-0.857,0.207c-2.348-1.435-5.304-1.76-8.785-0.964c-0.335,0.077-0.67-0.133-0.746-0.469 c-0.077-0.335,0.132-0.67,0.469-0.746c3.809-0.871,7.077-0.496,9.713,1.115C16.673,15.746,16.766,16.13,16.586,16.424 M17.81,13.7 c-0.226,0.367-0.706,0.482-1.072,0.257c-2.687-1.652-6.785-2.131-9.965-1.166C6.36,12.917,5.925,12.684,5.8,12.273 C5.675,11.86,5.908,11.425,6.32,11.3c3.632-1.102,8.147-0.568,11.234,1.328C17.92,12.854,18.035,13.335,17.81,13.7 M17.915,10.865 c-3.223-1.914-8.54-2.09-11.618-1.156C5.804,9.859,5.281,9.58,5.131,9.086C4.982,8.591,5.26,8.069,5.755,7.919 c3.532-1.072,9.404-0.865,13.115,1.338c0.445,0.264,0.59,0.838,0.327,1.282C18.933,10.983,18.359,11.129,17.915,10.865"></path></svg>', 'tumblr' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M16.749,17.396c-0.357,0.17-1.041,0.319-1.551,0.332c-1.539,0.041-1.837-1.081-1.85-1.896V9.847h3.861V6.937h-3.847V2.039 c0,0-2.77,0-2.817,0c-0.046,0-0.127,0.041-0.138,0.144c-0.165,1.499-0.867,4.13-3.783,5.181v2.484h1.945v6.282 c0,2.151,1.587,5.206,5.775,5.135c1.413-0.024,2.982-0.616,3.329-1.126L16.749,17.396z"></path></svg>', 'twitch' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M16.499,8.089h-1.636v4.91h1.636V8.089z M12,8.089h-1.637v4.91H12V8.089z M4.228,3.178L3,6.451v13.092h4.499V22h2.456 l2.454-2.456h3.681L21,14.636V3.178H4.228z M19.364,13.816l-2.864,2.865H12l-2.453,2.453V16.68H5.863V4.814h13.501V13.816z"></path></svg>', 'twitter' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22.23,5.924c-0.736,0.326-1.527,0.547-2.357,0.646c0.847-0.508,1.498-1.312,1.804-2.27 c-0.793,0.47-1.671,0.812-2.606,0.996C18.324,4.498,17.257,4,16.077,4c-2.266,0-4.103,1.837-4.103,4.103 c0,0.322,0.036,0.635,0.106,0.935C8.67,8.867,5.647,7.234,3.623,4.751C3.27,5.357,3.067,6.062,3.067,6.814 c0,1.424,0.724,2.679,1.825,3.415c-0.673-0.021-1.305-0.206-1.859-0.513c0,0.017,0,0.034,0,0.052c0,1.988,1.414,3.647,3.292,4.023 c-0.344,0.094-0.707,0.144-1.081,0.144c-0.264,0-0.521-0.026-0.772-0.074c0.522,1.63,2.038,2.816,3.833,2.85 c-1.404,1.1-3.174,1.756-5.096,1.756c-0.331,0-0.658-0.019-0.979-0.057c1.816,1.164,3.973,1.843,6.29,1.843 c7.547,0,11.675-6.252,11.675-11.675c0-0.178-0.004-0.355-0.012-0.531C20.985,7.47,21.68,6.747,22.23,5.924z"></path></svg>', 'vimeo' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22.396,7.164c-0.093,2.026-1.507,4.799-4.245,8.32C15.322,19.161,12.928,21,10.97,21c-1.214,0-2.24-1.119-3.079-3.359 c-0.56-2.053-1.119-4.106-1.68-6.159C5.588,9.243,4.921,8.122,4.206,8.122c-0.156,0-0.701,0.328-1.634,0.98L1.594,7.841 c1.027-0.902,2.04-1.805,3.037-2.708C6.001,3.95,7.03,3.327,7.715,3.264c1.619-0.156,2.616,0.951,2.99,3.321 c0.404,2.557,0.685,4.147,0.841,4.769c0.467,2.121,0.981,3.181,1.542,3.181c0.435,0,1.09-0.688,1.963-2.065 c0.871-1.376,1.338-2.422,1.401-3.142c0.125-1.187-0.343-1.782-1.401-1.782c-0.498,0-1.012,0.115-1.541,0.341 c1.023-3.35,2.977-4.977,5.862-4.884C21.511,3.066,22.52,4.453,22.396,7.164z"></path></svg>', 'vk' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22,7.1c0.2,0.4-0.4,1.5-1.6,3.1c-0.2,0.2-0.4,0.5-0.7,0.9c-0.5,0.7-0.9,1.1-0.9,1.4c-0.1,0.3-0.1,0.6,0.1,0.8 c0.1,0.1,0.4,0.4,0.8,0.9h0l0,0c1,0.9,1.6,1.7,2,2.3c0,0,0,0.1,0.1,0.1c0,0.1,0,0.1,0.1,0.3c0,0.1,0,0.2,0,0.4 c0,0.1-0.1,0.2-0.3,0.3c-0.1,0.1-0.4,0.1-0.6,0.1l-2.7,0c-0.2,0-0.4,0-0.6-0.1c-0.2-0.1-0.4-0.1-0.5-0.2l-0.2-0.1 c-0.2-0.1-0.5-0.4-0.7-0.7s-0.5-0.6-0.7-0.8c-0.2-0.2-0.4-0.4-0.6-0.6C14.8,15,14.6,15,14.4,15c0,0,0,0-0.1,0c0,0-0.1,0.1-0.2,0.2 c-0.1,0.1-0.2,0.2-0.2,0.3c-0.1,0.1-0.1,0.3-0.2,0.5c-0.1,0.2-0.1,0.5-0.1,0.8c0,0.1,0,0.2,0,0.3c0,0.1-0.1,0.2-0.1,0.2l0,0.1 c-0.1,0.1-0.3,0.2-0.6,0.2h-1.2c-0.5,0-1,0-1.5-0.2c-0.5-0.1-1-0.3-1.4-0.6s-0.7-0.5-1.1-0.7s-0.6-0.4-0.7-0.6l-0.3-0.3 c-0.1-0.1-0.2-0.2-0.3-0.3s-0.4-0.5-0.7-0.9s-0.7-1-1.1-1.6c-0.4-0.6-0.8-1.3-1.3-2.2C2.9,9.4,2.5,8.5,2.1,7.5C2,7.4,2,7.3,2,7.2 c0-0.1,0-0.1,0-0.2l0-0.1c0.1-0.1,0.3-0.2,0.6-0.2l2.9,0c0.1,0,0.2,0,0.2,0.1S5.9,6.9,5.9,7L6,7c0.1,0.1,0.2,0.2,0.3,0.3 C6.4,7.7,6.5,8,6.7,8.4C6.9,8.8,7,9,7.1,9.2l0.2,0.3c0.2,0.4,0.4,0.8,0.6,1.1c0.2,0.3,0.4,0.5,0.5,0.7s0.3,0.3,0.4,0.4 c0.1,0.1,0.3,0.1,0.4,0.1c0.1,0,0.2,0,0.3-0.1c0,0,0,0,0.1-0.1c0,0,0.1-0.1,0.1-0.2c0.1-0.1,0.1-0.3,0.1-0.5c0-0.2,0.1-0.5,0.1-0.8 c0-0.4,0-0.8,0-1.3c0-0.3,0-0.5-0.1-0.8c0-0.2-0.1-0.4-0.1-0.5L9.6,7.6C9.4,7.3,9.1,7.2,8.7,7.1C8.6,7.1,8.6,7,8.7,6.9 C8.9,6.7,9,6.6,9.1,6.5c0.4-0.2,1.2-0.3,2.5-0.3c0.6,0,1,0.1,1.4,0.1c0.1,0,0.3,0.1,0.3,0.1c0.1,0.1,0.2,0.1,0.2,0.3 c0,0.1,0.1,0.2,0.1,0.3s0,0.3,0,0.5c0,0.2,0,0.4,0,0.6c0,0.2,0,0.4,0,0.7c0,0.3,0,0.6,0,0.9c0,0.1,0,0.2,0,0.4c0,0.2,0,0.4,0,0.5 c0,0.1,0,0.3,0,0.4s0.1,0.3,0.1,0.4c0.1,0.1,0.1,0.2,0.2,0.3c0.1,0,0.1,0,0.2,0c0.1,0,0.2,0,0.3-0.1c0.1-0.1,0.2-0.2,0.4-0.4 s0.3-0.4,0.5-0.7c0.2-0.3,0.5-0.7,0.7-1.1c0.4-0.7,0.8-1.5,1.1-2.3c0-0.1,0.1-0.1,0.1-0.2c0-0.1,0.1-0.1,0.1-0.1l0,0l0.1,0 c0,0,0,0,0.1,0s0.2,0,0.2,0l3,0c0.3,0,0.5,0,0.7,0S21.9,7,21.9,7L22,7.1z"></path></svg>', 'wordpress' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.158,12.786L9.46,20.625c0.806,0.237,1.657,0.366,2.54,0.366c1.047,0,2.051-0.181,2.986-0.51 c-0.024-0.038-0.046-0.079-0.065-0.124L12.158,12.786z M3.009,12c0,3.559,2.068,6.634,5.067,8.092L3.788,8.341 C3.289,9.459,3.009,10.696,3.009,12z M18.069,11.546c0-1.112-0.399-1.881-0.741-2.48c-0.456-0.741-0.883-1.368-0.883-2.109 c0-0.826,0.627-1.596,1.51-1.596c0.04,0,0.078,0.005,0.116,0.007C16.472,3.904,14.34,3.009,12,3.009 c-3.141,0-5.904,1.612-7.512,4.052c0.211,0.007,0.41,0.011,0.579,0.011c0.94,0,2.396-0.114,2.396-0.114 C7.947,6.93,8.004,7.642,7.52,7.699c0,0-0.487,0.057-1.029,0.085l3.274,9.739l1.968-5.901l-1.401-3.838 C9.848,7.756,9.389,7.699,9.389,7.699C8.904,7.67,8.961,6.93,9.446,6.958c0,0,1.484,0.114,2.368,0.114 c0.94,0,2.397-0.114,2.397-0.114c0.485-0.028,0.542,0.684,0.057,0.741c0,0-0.488,0.057-1.029,0.085l3.249,9.665l0.897-2.996 C17.841,13.284,18.069,12.316,18.069,11.546z M19.889,7.686c0.039,0.286,0.06,0.593,0.06,0.924c0,0.912-0.171,1.938-0.684,3.22 l-2.746,7.94c2.673-1.558,4.47-4.454,4.47-7.771C20.991,10.436,20.591,8.967,19.889,7.686z M12,22C6.486,22,2,17.514,2,12 C2,6.486,6.486,2,12,2c5.514,0,10,4.486,10,10C22,17.514,17.514,22,12,22z"></path></svg>', 'yelp' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.271,16.718v1.417q-.011,3.257-.067,3.4a.707.707,0,0,1-.569.446,4.637,4.637,0,0,1-2.024-.424A4.609,4.609,0,0,1,7.8,20.565a.844.844,0,0,1-.19-.4.692.692,0,0,1,.044-.29,3.181,3.181,0,0,1,.379-.524q.335-.412,2.019-2.409.011,0,.669-.781a.757.757,0,0,1,.44-.274.965.965,0,0,1,.552.039.945.945,0,0,1,.418.324.732.732,0,0,1,.139.468Zm-1.662-2.8a.783.783,0,0,1-.58.781l-1.339.435q-3.067.981-3.257.981a.711.711,0,0,1-.6-.4,2.636,2.636,0,0,1-.19-.836,9.134,9.134,0,0,1,.011-1.857,3.559,3.559,0,0,1,.335-1.389.659.659,0,0,1,.625-.357,22.629,22.629,0,0,1,2.253.859q.781.324,1.283.524l.937.379a.771.771,0,0,1,.4.34A.982.982,0,0,1,10.609,13.917Zm9.213,3.313a4.467,4.467,0,0,1-1.021,1.8,4.559,4.559,0,0,1-1.512,1.417.671.671,0,0,1-.7-.078q-.156-.112-2.052-3.2l-.524-.859a.761.761,0,0,1-.128-.513.957.957,0,0,1,.217-.513.774.774,0,0,1,.926-.29q.011.011,1.327.446,2.264.736,2.7.887a2.082,2.082,0,0,1,.524.229.673.673,0,0,1,.245.68Zm-7.5-7.049q.056,1.137-.6,1.361-.647.19-1.272-.792L6.237,4.08a.7.7,0,0,1,.212-.691,5.788,5.788,0,0,1,2.314-1,5.928,5.928,0,0,1,2.5-.352.681.681,0,0,1,.547.5q.034.2.245,3.407T12.327,10.181Zm7.384,1.2a.679.679,0,0,1-.29.658q-.167.112-3.67.959-.747.167-1.015.257l.011-.022a.769.769,0,0,1-.513-.044.914.914,0,0,1-.413-.357.786.786,0,0,1,0-.971q.011-.011.836-1.137,1.394-1.908,1.673-2.275a2.423,2.423,0,0,1,.379-.435A.7.7,0,0,1,17.435,8a4.482,4.482,0,0,1,1.372,1.489,4.81,4.81,0,0,1,.9,1.868v.034Z"></path></svg>', 'youtube' => '<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg>', ); /** * Social Icons – domain mappings. * * By default, each Icon ID is matched against a .com TLD. To override this behavior, * specify all the domains it covers (including the .com TLD too, if applicable). * * @since 1.0.0 * * @var array */ protected static $social_icons_map = array( 'amazon' => array( 'amazon.com', 'amazon.cn', 'amazon.in', 'amazon.fr', 'amazon.de', 'amazon.it', 'amazon.nl', 'amazon.es', 'amazon.co', 'amazon.ca', ), 'behance' => array( 'behance.net', ), 'codepen' => array( 'codepen.io', ), 'facebook' => array( 'facebook.com', 'fb.me', ), 'feed' => array( 'feed', ), 'lastfm' => array( 'last.fm', ), 'mail' => array( 'mailto:', ), 'pocket' => array( 'getpocket.com', ), 'twitch' => array( 'twitch.tv', ), 'wordpress' => array( 'wordpress.com', 'wordpress.org', ), ); /** * Gets the SVG code for a given icon. * * @static * * @access public * * @since 1.0.0 * * @param string $group the icon group. * @param string $icon The icon. * @param int $size The icon-size in pixels. * * @return string */ public static function get_svg( $group, $icon, $size ) { if ( 'ui' === $group ) { $arr = self::$icons; } elseif ( 'social' === $group ) { $arr = self::$social_icons; } else { $arr = array(); } /** * Filters Twenty Twenty-Ones's array of icons. * * The dynamic portion of the hook name, `$group`, refers to * the name of the group of icons, either "ui" or "social". * * @since 1.0.0 * * @param array $arr Array of icons. */ $arr = apply_filters( "twenty_twenty_one_svg_icons_{$group}", $arr ); $svg = ''; if ( array_key_exists( $icon, $arr ) ) { $repl = sprintf( '<svg class="svg-icon" width="%d" height="%d" aria-hidden="true" role="img" focusable="false" ', $size, $size ); $svg = preg_replace( '/^<svg /', $repl, trim( $arr[ $icon ] ) ); // Add extra attributes to SVG code. } // @phpstan-ignore-next-line. return $svg; } /** * Detects the social network from a URL and returns the SVG code for its icon. * * @static * * @access public * * @since 1.0.0 * * @param string $uri Social link. * @param int $size The icon-size in pixels. * * @return string|null */ public static function get_social_link_svg( $uri, $size ) { static $regex_map; // Only compute regex map once, for performance. if ( ! isset( $regex_map ) ) { $regex_map = array(); /** * Filters Twenty Twenty-Ones's array of domain mappings for social icons. * * By default, each Icon ID is matched against a .com TLD. To override this behavior, * specify all the domains it covers (including the .com TLD too, if applicable). * * @since 1.0.0 * * @param array $social_icons_map Array of default social icons. */ $map = apply_filters( 'twenty_twenty_one_social_icons_map', self::$social_icons_map ); /** * Filters Twenty Twenty-One's array of social icons. * * @since 1.0.0 * * @param array $social_icons Array of default social icons. */ $social_icons = apply_filters( 'twenty_twenty_one_svg_icons_social', self::$social_icons ); foreach ( array_keys( $social_icons ) as $icon ) { $domains = array_key_exists( $icon, $map ) ? $map[ $icon ] : array( sprintf( '%s.com', $icon ) ); $domains = array_map( 'trim', $domains ); // Remove leading/trailing spaces, to prevent regex from failing to match. $domains = array_map( 'preg_quote', $domains ); $regex_map[ $icon ] = sprintf( '/(%s)/i', implode( '|', $domains ) ); } } foreach ( $regex_map as $icon => $regex ) { if ( preg_match( $regex, $uri ) ) { return self::get_svg( 'social', $icon, $size ) . '<span class="screen-reader-text">'; } } return null; } } class-twenty-twenty-one-custom-colors.php 0000644 00000012043 15252503401 0014625 0 ustar 00 <?php /** * Custom Colors Class * * @package WordPress * @subpackage Twenty_Twenty_One * @since 1.0.0 */ /** * This class is in charge of color customization via the Customizer. */ class Twenty_Twenty_One_Custom_Colors { /** * Instantiate the object. * * @access public * * @since 1.0.0 */ public function __construct() { // Enqueue color variables for customizer & frontend. add_action( 'wp_enqueue_scripts', array( $this, 'custom_color_variables' ) ); // Enqueue color variables for editor. add_action( 'enqueue_block_editor_assets', array( $this, 'editor_custom_color_variables' ) ); // Add body-class if needed. add_filter( 'body_class', array( $this, 'body_class' ) ); } /** * Determine the luminance of the given color and then return #fff or #000 so that the text is always readable. * * @access public * * @param string $background_color The background color. * * @since 1.0.0 * * @return string (hex color) */ public function custom_get_readable_color( $background_color ) { return ( 127 < self::get_relative_luminance_from_hex( $background_color ) ) ? '#000' : '#fff'; } /** * Generate color variables. * * Adjust the color value of the CSS variables depending on the background color theme mod. * Both text and link colors needs to be updated. * The code below needs to be updated, because the colors are no longer theme mods. * * @access public * * @since 1.0.0 * * @param string|null $context Can be "editor" or null. * * @return string */ public function generate_custom_color_variables( $context = null ) { $theme_css = 'editor' === $context ? ':root .editor-styles-wrapper{' : ':root{'; $background_color = get_theme_mod( 'background_color', 'D1E4DD' ); if ( 'd1e4dd' !== strtolower( $background_color ) ) { $theme_css .= '--global--color-background: #' . $background_color . ';'; $theme_css .= '--global--color-primary: ' . $this->custom_get_readable_color( $background_color ) . ';'; $theme_css .= '--global--color-secondary: ' . $this->custom_get_readable_color( $background_color ) . ';'; $theme_css .= '--button--color-background: ' . $this->custom_get_readable_color( $background_color ) . ';'; $theme_css .= '--button--color-text-hover: ' . $this->custom_get_readable_color( $background_color ) . ';'; if ( '#fff' === $this->custom_get_readable_color( $background_color ) ) { $theme_css .= '--table--stripes-border-color: var(--global--color-dark-gray);'; $theme_css .= '--table--stripes-background-color: var(--global--color-dark-gray);'; } } $theme_css .= '}'; return $theme_css; } /** * Customizer & frontend custom color variables. * * @access public * * @since 1.0.0 * * @return void */ public function custom_color_variables() { if ( 'd1e4dd' !== strtolower( get_theme_mod( 'background_color', 'D1E4DD' ) ) ) { wp_add_inline_style( 'twenty-twenty-one-style', $this->generate_custom_color_variables() ); } } /** * Editor custom color variables. * * @access public * * @since 1.0.0 * * @return void */ public function editor_custom_color_variables() { wp_enqueue_style( 'twenty-twenty-one-custom-color-overrides', get_theme_file_uri( 'assets/css/custom-color-overrides.css' ), array(), (string) filemtime( get_theme_file_path( 'assets/css/custom-color-overrides.css' ) ) ); $background_color = get_theme_mod( 'background_color', 'D1E4DD' ); if ( 'd1e4dd' !== strtolower( $background_color ) ) { wp_add_inline_style( 'twenty-twenty-one-custom-color-overrides', $this->generate_custom_color_variables( 'editor' ) ); } } /** * Get luminance from a HEX color. * * @static * * @access public * * @since 1.0.0 * * @param string $hex The HEX color. * * @return int Returns a number (0-255). */ public static function get_relative_luminance_from_hex( $hex ) { // Remove the "#" symbol from the beginning of the color. $hex = ltrim( $hex, '#' ); // Make sure there are 6 digits for the below calculations. if ( 3 === strlen( $hex ) ) { $hex = substr( $hex, 0, 1 ) . substr( $hex, 0, 1 ) . substr( $hex, 1, 1 ) . substr( $hex, 1, 1 ) . substr( $hex, 2, 1 ) . substr( $hex, 2, 1 ); } // Get red, green, blue. $red = hexdec( substr( $hex, 0, 2 ) ); $green = hexdec( substr( $hex, 2, 2 ) ); $blue = hexdec( substr( $hex, 4, 2 ) ); // Calculate the luminance. $lum = ( 0.2126 * $red ) + ( 0.7152 * $green ) + ( 0.0722 * $blue ); return (int) round( $lum ); } /** * Adds a class to <body> if the background-color is dark. * * @access public * * @since 1.0.0 * * @param array $classes The existing body classes. * * @return array */ public function body_class( $classes ) { $background_color = get_theme_mod( 'background_color', 'D1E4DD' ); $luminance = self::get_relative_luminance_from_hex( $background_color ); if ( 127 > $luminance ) { $classes[] = 'is-dark-theme'; } else { $classes[] = 'is-light-theme'; } if ( 225 <= $luminance ) { $classes[] = 'has-background-white'; } return $classes; } } class-twenty-twenty-one-dark-mode.php 0000644 00000027522 15252503401 0013667 0 ustar 00 <?php /** * Dark Mode Class * * @package WordPress * @subpackage Twenty_Twenty_One * @since 1.0.0 */ /** * This class is in charge of Dark Mode. */ class Twenty_Twenty_One_Dark_Mode { /** * Instantiate the object. * * @access public * * @since 1.0.0 */ public function __construct() { // Enqueue assets for the block-editor. add_action( 'enqueue_block_editor_assets', array( $this, 'editor_custom_color_variables' ) ); // Add styles for dark-mode. add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); // Add scripts for customizer controls. add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_controls_enqueue_scripts' ) ); // Add customizer controls. add_action( 'customize_register', array( $this, 'customizer_controls' ) ); // Add HTML classes. add_filter( 'twentytwentyone_html_classes', array( $this, 'html_classes' ) ); // Add classes to <body> in the dashboard. add_filter( 'admin_body_class', array( $this, 'admin_body_classes' ) ); // Add the switch on the frontend & customizer. add_action( 'wp_footer', array( $this, 'the_switch' ) ); // Add the privacy policy content. add_action( 'admin_init', array( $this, 'add_privacy_policy_content' ) ); } /** * Editor custom color variables & scripts. * * @access public * * @since 1.0.0 * * @return void */ public function editor_custom_color_variables() { if ( ! $this->switch_should_render() ) { return; } $background_color = get_theme_mod( 'background_color', 'D1E4DD' ); $should_respect_color_scheme = get_theme_mod( 'respect_user_color_preference', false ); if ( $should_respect_color_scheme && Twenty_Twenty_One_Custom_Colors::get_relative_luminance_from_hex( $background_color ) > 127 ) { // Add Dark Mode variable overrides. wp_add_inline_style( 'twenty-twenty-one-custom-color-overrides', '.is-dark-theme.is-dark-theme .editor-styles-wrapper { --global--color-background: var(--global--color-dark-gray); --global--color-primary: var(--global--color-light-gray); --global--color-secondary: var(--global--color-light-gray); --button--color-text: var(--global--color-background); --button--color-text-hover: var(--global--color-secondary); --button--color-text-active: var(--global--color-secondary); --button--color-background: var(--global--color-secondary); --button--color-background-active: var(--global--color-background); --global--color-border: #9ea1a7; }' ); } wp_enqueue_script( 'twentytwentyone-dark-mode-support-toggle', get_template_directory_uri() . '/assets/js/dark-mode-toggler.js', array(), '1.0.0', true ); wp_enqueue_script( 'twentytwentyone-editor-dark-mode-support', get_template_directory_uri() . '/assets/js/editor-dark-mode-support.js', array( 'twentytwentyone-dark-mode-support-toggle' ), '1.0.0', true ); } /** * Enqueue scripts and styles. * * @access public * * @since 1.0.0 * * @return void */ public function enqueue_scripts() { if ( ! $this->switch_should_render() ) { return; } $url = get_template_directory_uri() . '/assets/css/style-dark-mode.css'; if ( is_rtl() ) { $url = get_template_directory_uri() . '/assets/css/style-dark-mode-rtl.css'; } wp_enqueue_style( 'tt1-dark-mode', $url, array( 'twenty-twenty-one-style' ), wp_get_theme()->get( 'Version' ) ); // @phpstan-ignore-line. Version is always a string. } /** * Enqueue scripts for the customizer. * * @access public * * @since 1.0.0 * * @return void */ public function customize_controls_enqueue_scripts() { if ( ! $this->switch_should_render() ) { return; } wp_enqueue_script( 'twentytwentyone-customize-controls', get_template_directory_uri() . '/assets/js/customize.js', array( 'customize-base', 'customize-controls', 'underscore', 'jquery', 'twentytwentyone-customize-helpers' ), '1.0.0', true ); } /** * Register customizer options. * * @access public * * @since 1.0.0 * * @param WP_Customize_Manager $wp_customize Theme Customizer object. * * @return void */ public function customizer_controls( $wp_customize ) { $colors_section = $wp_customize->get_section( 'colors' ); if ( is_object( $colors_section ) ) { $colors_section->title = __( 'Colors & Dark Mode', 'twentytwentyone' ); } // Custom notice control. include_once get_theme_file_path( 'classes/class-twenty-twenty-one-customize-notice-control.php' ); // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude.FileIncludeFound $wp_customize->add_setting( 'respect_user_color_preference_notice', array( 'capability' => 'edit_theme_options', 'default' => '', 'sanitize_callback' => '__return_empty_string', ) ); $wp_customize->add_control( new Twenty_Twenty_One_Customize_Notice_Control( $wp_customize, 'respect_user_color_preference_notice', array( 'section' => 'colors', 'priority' => 100, 'active_callback' => function() { return 127 >= Twenty_Twenty_One_Custom_Colors::get_relative_luminance_from_hex( get_theme_mod( 'background_color', 'D1E4DD' ) ); }, ) ) ); $wp_customize->add_setting( 'respect_user_color_preference', array( 'capability' => 'edit_theme_options', 'default' => false, 'sanitize_callback' => function( $value ) { return (bool) $value; }, ) ); $description = '<p>'; $description .= sprintf( // translators: %s is the wordpress.org Twenty Twenty-One support article URL. __( 'Dark Mode is a device setting. If a visitor to your site requests it, your site will be shown with a dark background and light text. <a href="%s">Learn more about Dark Mode.</a>', 'twentytwentyone' ), __( 'https://wordpress.org/support/article/twenty-twenty-one/', 'twentytwentyone' ) ); $description .= '</p>'; $description .= '<p>' . __( 'Dark Mode can also be turned on and off with a button that you can find in the bottom right corner of the page.', 'twentytwentyone' ) . '</p>'; $wp_customize->add_control( 'respect_user_color_preference', array( 'type' => 'checkbox', 'section' => 'colors', 'label' => esc_html__( 'Dark Mode support', 'twentytwentyone' ), 'priority' => 110, 'description' => $description, 'active_callback' => function( $value ) { return 127 < Twenty_Twenty_One_Custom_Colors::get_relative_luminance_from_hex( get_theme_mod( 'background_color', 'D1E4DD' ) ); }, ) ); // Add partial for background_color. $wp_customize->selective_refresh->add_partial( 'background_color', array( 'selector' => '#dark-mode-toggler', 'container_inclusive' => true, 'render_callback' => function() { $attrs = ( $this->switch_should_render() ) ? array() : array( 'style' => 'display:none;' ); $this->the_html( $attrs ); }, ) ); } /** * Calculate classes for the main <html> element. * * @access public * * @since 1.0.0 * * @param string $classes The classes for <html> element. * * @return string */ public function html_classes( $classes ) { if ( ! $this->switch_should_render() ) { return $classes; } $background_color = get_theme_mod( 'background_color', 'D1E4DD' ); $should_respect_color_scheme = get_theme_mod( 'respect_user_color_preference', false ); if ( $should_respect_color_scheme && 127 <= Twenty_Twenty_One_Custom_Colors::get_relative_luminance_from_hex( $background_color ) ) { return ( $classes ) ? ' respect-color-scheme-preference' : 'respect-color-scheme-preference'; } return $classes; } /** * Adds a class to the <body> element in the editor to accommodate dark-mode. * * @access public * * @since 1.0.0 * * @param string $classes The admin body-classes. * * @return string */ public function admin_body_classes( $classes ) { if ( ! $this->switch_should_render() ) { return $classes; } global $current_screen; if ( empty( $current_screen ) ) { set_current_screen(); } if ( $current_screen->is_block_editor() ) { $should_respect_color_scheme = get_theme_mod( 'respect_user_color_preference', false ); $background_color = get_theme_mod( 'background_color', 'D1E4DD' ); if ( $should_respect_color_scheme && Twenty_Twenty_One_Custom_Colors::get_relative_luminance_from_hex( $background_color ) > 127 ) { $classes .= ' twentytwentyone-supports-dark-theme'; } } return $classes; } /** * Determine if we want to print the dark-mode switch or not. * * @access public * * @since 1.0.0 * * @return bool */ public function switch_should_render() { global $is_IE; return ( get_theme_mod( 'respect_user_color_preference', false ) && ! $is_IE && 127 <= Twenty_Twenty_One_Custom_Colors::get_relative_luminance_from_hex( get_theme_mod( 'background_color', 'D1E4DD' ) ) ); } /** * Add night/day switch. * * @access public * * @since 1.0.0 * * @return void */ public function the_switch() { if ( ! $this->switch_should_render() ) { return; } $this->the_html(); $this->the_script(); } /** * Print the dark-mode switch HTML. * * Inspired from https://codepen.io/aaroniker/pen/KGpXZo (MIT-licensed) * * @access public * * @since 1.0.0 * * @param array $attrs The attributes to add to our <button> element. * * @return void */ public function the_html( $attrs = array() ) { $attrs = wp_parse_args( $attrs, array( 'id' => 'dark-mode-toggler', 'class' => 'fixed-bottom', 'aria-pressed' => 'false', 'onClick' => 'toggleDarkMode()', ) ); echo '<button'; foreach ( $attrs as $key => $val ) { echo ' ' . esc_attr( $key ) . '="' . esc_attr( $val ) . '"'; } echo '>'; printf( /* translators: %s: On/Off */ esc_html__( 'Dark Mode: %s', 'twentytwentyone' ), '<span aria-hidden="true"></span>' ); echo '</button>'; ?> <style> #dark-mode-toggler > span { margin-<?php echo is_rtl() ? 'right' : 'left'; ?>: 5px; } #dark-mode-toggler > span::before { content: '<?php esc_attr_e( 'Off', 'twentytwentyone' ); ?>'; } #dark-mode-toggler[aria-pressed="true"] > span::before { content: '<?php esc_attr_e( 'On', 'twentytwentyone' ); ?>'; } <?php if ( is_admin() || wp_is_json_request() ) : ?> .components-editor-notices__pinned ~ .edit-post-visual-editor #dark-mode-toggler { z-index: 20; } .is-dark-theme.is-dark-theme #dark-mode-toggler:not(:hover):not(:focus) { color: var(--global--color-primary); } @media only screen and (max-width: 782px) { #dark-mode-toggler { margin-top: 32px; } } <?php endif; ?> </style> <?php } /** * Print the dark-mode switch script. * * @access public * * @since 1.0.0 * * @return void */ public function the_script() { echo '<script>'; include get_template_directory() . '/assets/js/dark-mode-toggler.js'; // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude echo '</script>'; } /** * Adds information to the privacy policy. * * @access public * * @since 1.0.0 * * @return void */ public function add_privacy_policy_content() { if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) { return; } $content = '<p class="privacy-policy-tutorial">' . __( 'Twenty Twenty-One uses LocalStorage when Dark Mode support is enabled.', 'twentytwentyone' ) . '</p>' . '<strong class="privacy-policy-tutorial">' . __( 'Suggested text:', 'twentytwentyone' ) . '</strong> ' . __( 'This website uses LocalStorage to save the setting when Dark Mode support is turned on or off.<br> LocalStorage is necessary for the setting to work and is only used when a user clicks on the Dark Mode button.<br> No data is saved in the database or transferred.', 'twentytwentyone' ); wp_add_privacy_policy_content( 'Twenty Twenty-One', wp_kses_post( wpautop( $content, false ) ) ); } } class-twenty-twenty-one-customize-color-control.php 0000644 00000002460 15252503401 0016632 0 ustar 00 <?php /** * Customize API: WP_Customize_Color_Control class * * @package WordPress * @subpackage Twenty_Twenty_One * @since 1.0.0 */ /** * Customize Color Control class. * * @since 1.0.0 * * @see WP_Customize_Control */ class Twenty_Twenty_One_Customize_Color_Control extends WP_Customize_Color_Control { /** * The control type. * * @since 1.0.0 * * @var string */ public $type = 'twenty-twenty-one-color'; /** * Colorpicker palette * * @access public * * @since 1.0.0 * * @var array */ public $palette; /** * Enqueue control related scripts/styles. * * @access public * * @since 1.0.0 * * @return void */ public function enqueue() { parent::enqueue(); // Enqueue the script. wp_enqueue_script( 'twentytwentyone-control-color', get_theme_file_uri( 'assets/js/palette-colorpicker.js' ), array( 'customize-controls', 'jquery', 'customize-base', 'wp-color-picker' ), (string) filemtime( get_theme_file_path( 'assets/js/palette-colorpicker.js' ) ), false ); } /** * Refresh the parameters passed to the JavaScript via JSON. * * @access public * * @since 1.0.0 * * @uses WP_Customize_Control::to_json() * * @return void */ public function to_json() { parent::to_json(); $this->json['palette'] = $this->palette; } } class-twenty-twenty-one-customize-notice-control.php 0000644 00000001735 15252503401 0017001 0 ustar 00 <?php /** * Customize API: Twenty_Twenty_One_Customize_Notice_Control class * * @package WordPress * @subpackage Twenty_Twenty_One * @since 1.0.0 */ /** * Customize Notice Control class. * * @since 1.0.0 * * @see WP_Customize_Control */ class Twenty_Twenty_One_Customize_Notice_Control extends WP_Customize_Control { /** * The control type. * * @since 1.0.0 * * @var string */ public $type = 'twenty-twenty-one-notice'; /** * Renders the control content. * * This simply prints the notice we need. * * @access public * * @since 1.0.0 * * @return void */ public function render_content() { ?> <div class="notice notice-warning"> <p><?php esc_html_e( 'To access the Dark Mode settings, select a light background color.', 'twentytwentyone' ); ?></p> <p><a href="https://wordpress.org/support/article/twenty-twenty-one/"> <?php esc_html_e( 'Learn more about Dark Mode.', 'twentytwentyone' ); ?> </a></p> </div> <?php } } class-astra-sites-admin.php 0000644 00000007541 15252521515 0011717 0 ustar 00 <?php /** * Admin Notices * * @since 2.3.7 * @package Astra Sites */ if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! class_exists( 'Astra_Sites_Admin' ) ) : /** * Admin */ class Astra_Sites_Admin { /** * Instance of Astra_Sites_Admin * * @since 2.3.7 * @var (Object) Astra_Sites_Admin */ private static $instance = null; /** * Instance of Astra_Sites_Admin. * * @since 2.3.7 * * @return object Class object. */ public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } /** * Constructor. * * @since 2.3.7 */ private function __construct() { add_action( 'astra_notice_before_markup', array( $this, 'notice_assets' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ) ); add_action( 'astra_sites_after_site_grid', array( $this, 'custom_upgrade_cta' ) ); add_filter( 'astra_sites_quick_links', array( $this, 'change_quick_links' ) ); } /** * Change quick links. * * @since 2.6.18 * @param array<string, array<string, mixed>> $links All quick links. * @return array<string, array<string, mixed>> */ public function change_quick_links( array $links = array() ) { if ( ! isset( $links['links']['upgrade'] ) ) { return $links; } // Change default call to action link. $links['links']['upgrade']['url'] = Astra_Sites::get_instance()->get_cta_link( 'quick-links-corner' ); return $links; } /** * Admin Assets * * @return void */ public function admin_assets() { $current_screen = get_current_screen(); if ( null !== $current_screen && 'appearance_page_starter-templates' !== $current_screen->id ) { return; } $white_label = Astra_Sites_White_Label::get_instance(); if ( $white_label instanceof Astra_Sites_White_Label && $white_label->is_white_labeled() ) { return; } wp_enqueue_style( 'astra-sites-admin-page', ASTRA_SITES_URI . 'assets/css/admin.css', array(), ASTRA_SITES_VER ); wp_enqueue_script( 'astra-sites-admin-js', ASTRA_SITES_URI . 'assets/js/admin.js', array( 'jquery' ), ASTRA_SITES_VER, true ); } /** * Add Custom CTA Infobar. * * @return void */ public function custom_upgrade_cta() { $current_screen = get_current_screen(); if ( null !== $current_screen && 'appearance_page_starter-templates' !== $current_screen->id ) { return; } $white_label = Astra_Sites_White_Label::get_instance(); if ( $white_label instanceof Astra_Sites_White_Label && $white_label->is_white_labeled() ) { return; } $custom_cta_content_data = apply_filters( 'astra_sites_custom_cta_vars', array( 'text' => __( 'Get unlimited access to all premium Starter Templates and more, at a single low cost!', 'astra-sites' ), 'button_text' => __( 'Get Essential Toolkit', 'astra-sites' ), 'cta_link' => Astra_Sites::get_instance()->get_cta_link(), ) ); $html = '<div class="astra-sites-custom-cta-wrap">'; $html .= '<span class="astra-sites-cta-title">' . esc_html( $custom_cta_content_data['text'] ) . '</span>'; $html .= '<span class="astra-sites-cta-btn">'; $html .= '<a class="astra-sites-cta-link" href="' . esc_url( $custom_cta_content_data['cta_link'] ) . '" target="_blank" >' . esc_html( $custom_cta_content_data['button_text'] ) . '</a>'; $html .= '</span>'; $html .= '</div>'; echo wp_kses_post( $html ); } /** * Enqueue Astra Notices CSS. * * @since 2.3.7 * * @return void */ public static function notice_assets() { $file = is_rtl() ? 'astra-notices-rtl.css' : 'astra-notices.css'; wp_enqueue_style( 'astra-sites-notices', ASTRA_SITES_URI . 'assets/css/' . $file, array(), ASTRA_SITES_VER ); } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Admin::get_instance(); endif; class-astra-sites.php 0000644 00000354677 15252526617 0010660 0 ustar 00 <?php /** * Astra Sites * * @since 1.0.0 * @package Astra Sites */ if ( ! defined( 'ABSPATH' ) ) { exit; } use AiBuilder\Inc\Traits\Helper; if ( ! class_exists( 'Astra_Sites' ) ) : /** * Astra_Sites */ class Astra_Sites { /** * API Domain name * * @var (String) URL */ public $api_domain; /** * API URL which is used to get the response from. * * @since 1.0.0 * @var (String) URL */ public $api_url; /** * Search API URL which is used to get the response from. * * @since 2.0.0 * @var (String) URL */ public $search_analytics_url; /** * Import Analytics API URL * * @since 3.1.4 * @var (String) URL */ public $import_analytics_url; /** * API URL which is used to get the response from Pixabay. * * @since 2.0.0 * @var (String) URL */ public $pixabay_url; /** * API Key which is used to get the response from Pixabay. * * @since 2.0.0 * @var (String) URL */ public $pixabay_api_key; /** * Instance of Astra_Sites * * @since 1.0.0 * @var (self) Astra_Sites */ private static $instance = null; /** * Localization variable * * @since 2.0.0 * @var (Array) $local_vars */ public static $local_vars = array(); /** * Localization variable * * @since 2.0.0 * @var (Array) $wp_upload_url */ public $wp_upload_url = ''; /** * Ajax * * @since 2.6.20 * @var (Array) $ajax */ private $ajax = array(); /** * Instance of Astra_Sites. * * @since 1.0.0 * * @return self Class object. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor. * * @since 1.0.0 */ private function __construct() { add_action( 'wp_php_error_message', array( $this, 'memory_error' ), 10, 2 ); if ( ! class_exists( 'XMLReader' ) ) { add_action( 'admin_notices', array( $this, 'xml_reader_notice' ) ); add_filter( 'ai_builder_load_library', '__return_false' ); return; } // Only register the placeholder blocking filter when a batch import is actively running. // This avoids unnecessary get_option() DB calls on every HTTP request. if ( 'yes' === get_option( 'astra_sites_batch_process_started', 'no' ) && 'yes' !== get_option( 'astra_sites_batch_process_complete', 'no' ) ) { add_filter( 'pre_http_request', array( $this, 'block_elementor_placeholder_requests' ), 10, 3 ); } $this->set_api_url(); $this->includes(); add_action( 'plugin_action_links_' . ASTRA_SITES_BASE, array( $this, 'action_links' ) ); add_action( 'init', array( $this, 'load_textdomain' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue' ), 99 ); add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_menu_url_updater' ), 10 ); add_action( 'elementor/editor/footer', array( $this, 'insert_templates' ) ); add_action( 'admin_footer', array( $this, 'insert_image_templates' ) ); add_action( 'customize_controls_print_footer_scripts', array( $this, 'insert_image_templates' ) ); add_action( 'wp_footer', array( $this, 'insert_image_templates_bb_and_brizy' ) ); add_action( 'elementor/editor/footer', array( $this, 'register_widget_scripts' ), 99 ); add_action( 'elementor/editor/before_enqueue_scripts', array( $this, 'popup_styles' ) ); add_action( 'elementor/preview/enqueue_styles', array( $this, 'popup_styles' ) ); add_action( 'astra_sites_after_plugin_activation', array( $this, 'disable_wp_forms_redirect' ) ); add_action( 'astra_notice_before_markup', array( $this, 'notice_assets' ) ); add_action( 'load-index.php', array( $this, 'admin_dashboard_notices' ) ); add_action( 'admin_notices', array( $this, 'check_filesystem_access_notice' ) ); add_filter( 'ai_builder_textdomain', array( $this, 'get_astra_sites_textdomain' ), 10, 1 ); add_filter( 'ai_builder_languages_directory', array( $this, 'change_languages_directory' ), 10, 1 ); add_filter( 'one_onboarding_textdomain', array( $this, 'get_astra_sites_textdomain' ) ); add_filter( 'one_onboarding_languages_directory', array( $this, 'change_languages_directory' ) ); // AJAX. $this->ajax = array( 'astra-sites-create-template' => 'create_template', 'astra-sites-create-image' => 'create_image', 'astra-sites-search-images' => 'search_images', 'astra-sites-getting-started-notice' => 'getting_started_notice', 'astra-sites-favorite' => 'add_to_favorite', 'astra-sites-api-request' => 'api_request', 'astra-sites-elementor-api-request' => 'elementor_api_request', 'astra-sites-elementor-flush-request' => 'elementor_flush_request', 'astra-page-elementor-insert-page' => 'elementor_process_import_for_page', 'astra-sites-update-subscription' => 'update_subscription', 'astra-sites-update-analytics' => 'update_analytics', 'astra-sites-generate-analytics-lead' => 'push_to_import_analytics', 'astra-sites-get-import-log-url' => 'get_import_log_url', ); foreach ( $this->ajax as $ajax_hook => $ajax_callback ) { add_action( 'wp_ajax_' . $ajax_hook, array( $this, $ajax_callback ) ); } add_action( 'delete_attachment', array( $this, 'delete_astra_images' ) ); add_filter( 'heartbeat_received', array( $this, 'search_push' ), 10, 2 ); add_filter( 'status_header', array( $this, 'status_header' ), 10, 4 ); add_filter( 'wp_php_error_message', array( $this, 'php_error_message' ), 10, 2 ); add_filter( 'wp_import_post_data_processed', array( $this, 'wp_slash_after_xml_import' ), 99, 2 ); add_filter( 'ast_block_templates_authorization_url_param', array( $this, 'add_auth_url_param' ) ); add_action( 'admin_head', array( $this, 'add_custom_admin_css' ) ); add_filter( 'zip_ai_modules', array( $this, 'enable_zip_ai_copilot' ), 20, 1 ); add_action( 'astra_sites_after_theme_activation', array( $this, 'theme_activation_utm_event' ) ); add_action( 'astra_sites_after_plugin_activation', array( $this, 'plugin_activation_utm_event' ), 10, 2 ); add_filter( 'plugins_api_args', array( $this, 'raise_memory_for_plugins_install' ), 1, 1 ); add_filter( 'wp_import_insert_term', array( $this, 'store_original_term_id' ), 10, 2 ); add_filter( 'getting_started_is_setup_wizard_showing', array( $this, 'maybe_setup_wizard_showing' ) ); add_filter( 'getting_started_logo_url', array( $this, 'starter_templates_logo_url' ) ); // Enable/disable templates force syncing. add_action( 'ast_block_templates_enable_force_sync', array( __CLASS__, 'enable_force_sync' ) ); add_filter( 'ast_block_templates_disable_force_sync', 'astra_sites_has_import_started' ); } /** * Store original term id. * * @param int $term_id Term ID. * @param array $data Term data. * @return int * @since 4.4.19 */ public function store_original_term_id( $term_id, $data ) { // Validate term_id. if ( ! is_numeric( $term_id ) || $term_id <= 0 ) { return $term_id; } // Validate data structure. if ( ! is_array( $data ) ) { return $term_id; } // Validate required data fields are not null. if ( ! isset( $data['taxonomy'], $data['id'] ) || null === $data['taxonomy'] || null === $data['id'] ) { return $term_id; } // Validate taxonomy exists. if ( ! taxonomy_exists( $data['taxonomy'] ) ) { return $term_id; } update_term_meta( $term_id, $data['taxonomy'] . '_id', $data['id'] ); return $term_id; } /** * Set textdomain as 'astra-sites'. * * @param string $textdomain Textdomain. * @return string * @since 4.4.37 */ public function get_astra_sites_textdomain( $textdomain ) { return 'astra-sites'; } /** * Change languages directory. * * @param string $lang_dir languages directory. * * @return string * @since 4.3.9 */ public function change_languages_directory( $lang_dir ) { return ASTRA_SITES_DIR . 'languages'; } /** * Display notice if XML Class Reader is not Available. * * @return void */ public function xml_reader_notice() { $plugin_name = defined( 'ASTRA_PRO_SITES_NAME' ) ? 'Premium Starter Templates' : 'Starter Templates'; ?> <div class="error"> <p> <?php /* Translators: %s Plugin Name. */ echo esc_html( sprintf( __( '%s: XMLReader extension is missing! To import templates, please get in touch with your hosting provider to enable this extension.', 'astra-sites' ), $plugin_name ) ); ?> </p> </div> <?php } /** * Set reset data * Note: This function can be deleted after a few releases since we are performing the delete operation in chunks. * * @return array<string, array> */ public function get_reset_data() { if ( wp_doing_ajax() ) { check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) ); } } Astra_Sites_Error_Handler::get_instance()->start_error_handler(); $data = array( 'reset_posts' => astra_sites_get_reset_post_data(), 'reset_wp_forms' => astra_sites_get_reset_form_data(), 'reset_terms' => astra_sites_get_reset_term_data(), ); Astra_Sites_Error_Handler::get_instance()->stop_error_handler(); if ( wp_doing_ajax() ) { wp_send_json_success( $data ); } return $data; } /** * Theme product activation utm event. * * @param string $theme_slug Theme slug. * @return void * * @since 4.4.16 */ public function theme_activation_utm_event( $theme_slug ) { if ( ! $theme_slug && ! is_string( $theme_slug ) ) { return; } if ( class_exists( 'BSF_UTM_Analytics' ) && is_callable( array( 'BSF_UTM_Analytics', 'update_referer' ) ) ) { // If the plugin is found and the update_referer function is callable, update the referer with the corresponding product slug. $page_builder = Astra_Sites_Page::get_instance()->get_setting( 'page_builder' ); // Set the referer to 'zipwp' for AI Builder and 'astra-sites' otherwise. $referer = 'ai-builder' === $page_builder ? 'zipwp' : 'astra-sites'; BSF_UTM_Analytics::update_referer( $referer, 'astra' ); } } /** * Plugin product activation utm event. * * @param string $plugin_init plugin init file. * @param mixed $data activation data. * @return void */ public function plugin_activation_utm_event( $plugin_init, $data = array() ) { if ( ! isset( $data['plugin_slug'] ) || '' === $data['plugin_slug'] ) { return; } // Update the referer only if the plugin was not active before template import. if ( ! isset( $data['was_plugin_active'] ) || ! $data['was_plugin_active'] ) { if ( class_exists( 'BSF_UTM_Analytics' ) && is_callable( array( 'BSF_UTM_Analytics', 'is_valid_bsf_product_slug' ) ) ) { // Bail early if the product slug is invalid to avoid warnings from BSF_UTM_Analytics::update_referer(). if ( ! BSF_UTM_Analytics::is_valid_bsf_product_slug( $data['plugin_slug'] ) ) { return; } } if ( class_exists( 'BSF_UTM_Analytics' ) && is_callable( array( 'BSF_UTM_Analytics', 'update_referer' ) ) ) { // If the plugin is found and the update_referer function is callable, update the referer with the corresponding product slug. $page_builder = Astra_Sites_Page::get_instance()->get_setting( 'page_builder' ); // Set the referer to 'zipwp' for AI Builder and 'astra-sites' otherwise. $referer = 'ai-builder' === $page_builder ? 'zipwp' : 'astra-sites'; BSF_UTM_Analytics::update_referer( $referer, $data['plugin_slug'] ); if ( 'sureforms' === $data['plugin_slug'] ) { $this->update_sureforms_referer(); } } } } /** * Update Sureforms referer based on the imported template. * * This function checks if the imported template is one of the top templates and updates the referer for Sureforms accordingly. * * @return void * @since 4.4.50 * @todo Remove this function after few releases after observations. */ public function update_sureforms_referer() { $template_data = Astra_Sites_File_System::get_instance()->get_demo_content(); // Top templates -- All Elementor templates. $top_templates_ids = array( 17988, // Brandstore! 58716, // Love Nature! 17534, // Digital Agency! 31992, // Organic Store! 19808, // Outdoor Adventure! 69715, // Planet Earth! 87989, // Clothing Store! 59264, // Personal Portfolio! 59455, // Construction Company! 46177, // Mountain! 71669, // Planet Earth Store! 54398, // Digital Agency! 88164, // Galatic! 58172, // Skin Cleanser Store! 83885, // Hope! ); // Bail early if template ID is not set or if it's not in the list of top templates to avoid unnecessary referer updates. if ( ! isset( $template_data['id'] ) || ! in_array( $template_data['id'], $top_templates_ids, true ) ) { return; } $referer_option = defined( 'BSF_UTM_ANALYTICS_REFERER' ) ? BSF_UTM_ANALYTICS_REFERER : 'bsf_product_referers'; $bsf_product_referers = get_option( $referer_option, array() ); if ( ! is_array( $bsf_product_referers ) ) { $bsf_product_referers = array(); } // Set referer based on template slug if available, otherwise default to 'astra-sites'. $template_slug = isset( $template_data['astra-site-url'] ) ? str_replace( array( 'https:', '//websitedemos.net/' ), '', $template_data['astra-site-url'] ) : ''; $referer = $template_slug ? 'astra-sites-' . $template_slug : 'astra-sites'; $bsf_product_referers['sureforms'] = $referer; update_option( BSF_UTM_ANALYTICS_REFERER, $bsf_product_referers ); } /** * Handle memory error share customized error message * * @since 4.4.12 * * @param string $message error message. * @param WP_ERROR $error error object. * @return mixed */ public function memory_error( $message, $error ) { if ( strpos( $message, 'critical error' ) !== false && strpos( $error['message'], 'memory size' ) !== false && get_option( 'astra_sites_import_started' ) == 'yes' ) { header( 'Content-type: application/json' ); return wp_json_encode( array( 'data' => array( 'message' => __( "Import failed due to insufficient memory. Please increase the PHP memory_limit on your server and retry. If you're unsure how to do this, contact your hosting provider for assistance.", 'astra-sites' ), ), ) ); } return $message; } /** * Raise memory limit for plugins install * * @since 4.4.12 * * @param array $args plugin array. * @return array */ public function raise_memory_for_plugins_install( $args ) { if ( 'yes' === get_option( 'astra_sites_import_started' ) ) { wp_raise_memory_limit( 'admin' ); } return $args; } /** * Enable ZipAI Copilot. * * @since 3.5.0 * * @param array $modules module array. * @return boolean */ public function enable_zip_ai_copilot( $modules ) { if ( 'active' === $this->get_plugin_status( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ) ) { return $modules; } // Ensure $modules is an array. $modules = is_array( $modules ) ? $modules : array(); // Update AI Design Copilot module status. $modules['ai_design_copilot'] = array( 'status' => 'enabled', ); $modules['ai_assistant'] = array( 'status' => 'enabled', ); return $modules; } /** * Set adding AI icon to WordPress menu. * * @return void */ public function add_custom_admin_css() { $icon = ASTRA_SITES_URI . 'inc/assets/images/vector-ai.svg'; ?> <style type="text/css"> .wp-submenu a[href*="themes.php?page=starter-templates"]::after { content: url("<?php echo esc_url( $icon ); ?>"); position: absolute; margin-left: 5px; height: 18px; width: 18px; } a[href="themes.php?page=ai-builder"] { display: none !important; } </style> <?php } /** * Set plugin param for auth URL. * * @param array $url_param url parameters. * * @since 3.5.0 */ public function add_auth_url_param( $url_param ) { $url_param['plugin'] = 'starter-templates'; return $url_param; } /** * Get plugin status * * @since 3.5.0 * * @param string $plugin_init_file Plguin init file. * @return string */ public function get_plugin_status( $plugin_init_file ) { if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $installed_plugins = get_plugins(); if ( ! isset( $installed_plugins[ $plugin_init_file ] ) ) { return 'not-installed'; } elseif ( is_plugin_active( $plugin_init_file ) ) { return 'active'; } else { return 'inactive'; } } /** * Add slashes while importing the XML with WordPress Importer v2. * * @param array $postdata Processed Post data. * @param array $data Post data. */ public function wp_slash_after_xml_import( $postdata, $data ) { if ( 'ai' === get_option( 'astra_sites_current_import_template_type' ) ) { return $postdata; } // Handle Spectra Blocks v3 content during template import. // Goal: // - If Spectra Blocks v3 is active in the demo template, we need to avoid wp_slash() on post content because it breaks block attributes. // - Also, decode any Unicode sequences (\uXXXX) to UTF-8 characters. // Get template/demo content if ST Importer is available. $template_data = class_exists( '\STImporter\Importer\ST_Importer_File_System' ) ? \STImporter\Importer\ST_Importer_File_System::get_instance()->get_demo_content() : array(); if ( ! empty( $postdata['post_content'] ) && ! empty( $template_data ) && is_array( $template_data ) ) { // Get the Spectra Blocks version info and class list. $spectra_blocks_version = isset( $template_data['spectra-blocks-ver'] ) ? $template_data['spectra-blocks-ver'] : array(); $class_list = isset( $template_data['class_list'] ) ? $template_data['class_list'] : array(); // Check if Spectra Blocks v3 is active in this template. if ( ! empty( $spectra_blocks_version ) && in_array( 'spectra-blocks-ver-v3', $class_list, true ) ) { // Define allowed symbols to decode. $allowed = array( '-', '&', '<', '>' ); $postdata['post_content'] = preg_replace_callback( '/(?:\s|\\\\)?u([0-9a-fA-F]{4})/', function ( $matches ) use ( $allowed ) { $char = mb_convert_encoding( pack( 'H*', $matches[1] ), 'UTF-8', 'UCS-2BE' ); // Return char only if in allowed list, else keep original escape. return in_array( $char, $allowed, true ) ? $char : $matches[0]; }, $postdata['post_content'] ); // Return post data without wp_slash to preserve block JSON integrity. return $postdata; } } return wp_slash( $postdata ); } /** * Check is Starter Templates AJAX request. * * @since 2.7.0 * @return boolean */ public function is_starter_templates_request() { if ( isset( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], array_keys( $this->ajax ), true ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Fetching GET parameter, no nonce associated with this action. return true; } return false; } /** * Filters the message that the default PHP error template displays. * * @since 2.7.0 * * @param string $message HTML error message to display. * @param array $error Error information retrieved from `error_get_last()`. * @return mixed */ public function php_error_message( $message, $error ) { if ( ! $this->is_starter_templates_request() ) { return $message; } if ( empty( $error ) ) { return $message; } $message = isset( $error['message'] ) ? $error['message'] : $message; return $message; } /** * Filters an HTTP status header. * * @since 2.6.20 * * @param string $status_header HTTP status header. * @param int $code HTTP status code. * @param string $description Description for the status code. * @param string $protocol Server protocol. * * @return mixed */ public function status_header( $status_header, $code, $description, $protocol ) { if ( ! $this->is_starter_templates_request() ) { return $status_header; } $error = error_get_last(); if ( empty( $error ) ) { return $status_header; } $message = isset( $error['message'] ) ? $error['message'] : $description; return "$protocol $code $message"; } /** * Update Analytics Optin/Optout */ public function update_analytics() { check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'You are not allowed to perform this action', 'astra-sites' ); } $optin_answer = isset( $_POST['data'] ) ? sanitize_text_field( $_POST['data'] ) : 'no'; $optin_answer = 'yes' === $optin_answer ? 'yes' : 'no'; update_site_option( 'astra_sites_usage_optin', $optin_answer ); wp_send_json_success(); } /** * Update Subscription */ public function update_subscription() { check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'You are not allowed to perform this action', 'astra-sites' ); } $arguments = isset( $_POST['data'] ) ? astra_sites_sanitize_recursive( json_decode( stripslashes( $_POST['data'] ), true ) ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Already sanitized using `array_map` and `sanitize_text_field`. // Page Builder mapping. $page_builder_mapping = array( 'Elementor' => 1, 'Beaver Builder' => 2, 'Brizy' => 3, 'Gutenberg' => 4, ); $arguments['PAGE_BUILDER'] = isset( $page_builder_mapping[ $arguments['PAGE_BUILDER'] ] ) ? $page_builder_mapping[ $arguments['PAGE_BUILDER'] ] : ''; $arguments['email'] = isset( $arguments['EMAIL'] ) ? $arguments['EMAIL'] : ''; $arguments['first_name'] = isset( $arguments['FIRSTNAME'] ) ? $arguments['FIRSTNAME'] : ''; $arguments['domain'] = site_url(); $arguments['source'] = 'astra-sites'; $url = apply_filters( 'astra_sites_subscription_url', self::get_metrics_api_domain() . 'wp-json/bsf-metrics-server/v1/subscribe' ); $args = array( 'timeout' => 30, 'body' => $arguments, ); $response = wp_safe_remote_post( $url, $args ); if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) { $response = json_decode( wp_remote_retrieve_body( $response ), true ); // Successfully subscribed. if ( isset( $response['success'] ) && $response['success'] ) { update_user_meta( get_current_user_ID(), 'astra-sites-subscribed', 'yes' ); } } wp_send_json_success( $response ); } /** * Push Data to Search API. * * @since 2.0.0 * @param array<string, string> $response Response data object. * @param array<string, string> $data Data object. * * @return array Search response. */ public function search_push( $response, $data ) { // If we didn't receive our data, don't send any back. if ( empty( $data['ast-sites-search-terms'] ) ) { return $response; } $args = array( 'timeout' => 3, 'blocking' => true, 'sslverify' => apply_filters( 'https_local_ssl_verify', false ), 'body' => array( 'search' => $data['ast-sites-search-terms'], 'builder' => isset( $data['ast-sites-builder'] ) ? $data['ast-sites-builder'] : 'gutenberg', 'url' => esc_url( site_url() ), 'type' => 'astra-sites', ), ); $result = wp_safe_remote_post( $this->search_analytics_url, $args ); $response['ast-sites-search-terms'] = wp_remote_retrieve_body( $result ); return $response; } /** * Push Data to Import Analytics API. * * @since 3.1.4 */ public function push_to_import_analytics() { check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'You are not allowed to perform this action', 'astra-sites' ); } // $id would be in string for AI templates and in number for classic templates. $id = isset( $_POST['id'] ) ? sanitize_text_field( $_POST['id'] ) : 0; if ( 0 === $id ) { wp_send_json_error( array( /* translators: %d is the Template ID. */ 'message' => sprintf( __( 'Invalid Template ID - %d', 'astra-sites' ), $id ), 'code' => 'Error', ) ); } $error = isset( $_POST['error'] ) ? json_decode( stripslashes( sanitize_text_field( $_POST['error'] ) ), true ) : array(); $data = array( 'id' => $id, 'import_attempts' => isset( $_POST['try-again-count'] ) ? absint( $_POST['try-again-count'] ) : 0, 'import_status' => isset( $_POST['status'] ) ? sanitize_text_field( $_POST['status'] ) : 'true', 'type' => isset( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : 'astra-sites', 'page_builder' => isset( $_POST['page_builder'] ) ? sanitize_text_field( $_POST['page_builder'] ) : 'gutenberg', 'template_type' => isset( $_POST['template_type'] ) ? sanitize_text_field( $_POST['template_type'] ) : '', 'failure_reason' => is_array( $error ) && isset( $error['primaryText'] ) ? sanitize_text_field( $error['primaryText'] ) : '', 'secondary_text' => is_array( $error ) && isset( $error['secondaryText'] ) ? sanitize_text_field( $error['secondaryText'] ) : '', 'error_text' => is_array( $error ) && isset( $error['errorText'] ) ? sanitize_text_field( $error['errorText'] ) : '', 'spectra_blocks_ver' => get_option( 'astra_sites_current_spectra_blocks_ver' ), ); $result = Astra_Sites_Reporting::get_instance()->report( $data ); if ( $result['status'] ) { delete_option( 'astra_sites_has_sent_error_report' ); delete_option( 'astra_sites_cached_import_error' ); wp_send_json_success( $result['data'] ); } wp_send_json_error( $result['data'] ); } /** * Return the URL of the most recent import log file. * * Used by the JS failure screen so the user can open the log directly. * * @since 4.6.1 * @return void */ public function get_import_log_url() { check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ), 403 ); return; } wp_send_json_success( array( 'import_log_url' => Astra_Sites_Importer_Log::get_log_file_url(), ) ); } /** * Before Astra Image delete, remove from options. * * @since 2.0.0 * @param int $id ID to deleting image. * @return void */ public function delete_astra_images( $id ) { if ( ! $id ) { return; } $saved_images = get_option( 'astra-sites-saved-images', array() ); $astra_image_flag = get_post_meta( $id, 'astra-images', true ); $astra_image_flag = (int) $astra_image_flag; if ( '' !== $astra_image_flag && is_array( $saved_images ) && ! empty( $saved_images ) && in_array( $astra_image_flag, $saved_images ) ) { $flag_arr = array( $astra_image_flag ); $saved_images = array_diff( $saved_images, $flag_arr ); update_option( 'astra-sites-saved-images', $saved_images, 'no' ); } } /** * Elementor Batch Process via AJAX * * @since 2.0.0 */ public function elementor_process_import_for_page() { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) ); } $type = isset( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : ''; $id = isset( $_POST['id'] ) ? absint( $_POST['id'] ) : ''; $demo_data = get_option( 'astra_sites_import_elementor_data_' . $id, array() ); if ( 'astra-blocks' == $type ) { $api_url = trailingslashit( self::get_instance()->get_api_domain() ) . 'wp-json/wp/v2/' . $type . '/' . $id; } else { $api_url = $demo_data['astra-page-api-url']; } if ( ! astra_sites_is_valid_url( $api_url ) ) { wp_send_json_error( __( 'Invalid API URL.', 'astra-sites' ) ); } $response = wp_safe_remote_get( $api_url ); if ( is_wp_error( $response ) ) { wp_send_json_error( wp_remote_retrieve_body( $response ) ); } $body = wp_remote_retrieve_body( $response ); $data = json_decode( $body, true ); if ( ! isset( $data['post-meta']['_elementor_data'] ) ) { wp_send_json_error( __( 'Invalid Post Meta', 'astra-sites' ) ); } $meta = json_decode( $data['post-meta']['_elementor_data'], true ); $post_id = isset( $_POST['id'] ) ? absint( sanitize_key( $_POST['id'] ) ) : ''; if ( empty( $post_id ) || empty( $meta ) ) { wp_send_json_error( __( 'Invalid Post ID or Elementor Meta', 'astra-sites' ) ); } if ( isset( $data['astra-page-options-data'] ) && isset( $data['astra-page-options-data']['elementor_load_fa4_shim'] ) ) { update_option( 'elementor_load_fa4_shim', $data['astra-page-options-data']['elementor_load_fa4_shim'] ); } // Check flexbox container, If inactive then activate it. $flexbox_container = get_option( 'elementor_experiment-container' ); // Check if the value is 'inactive'. if ( 'inactive' === $flexbox_container ) { // Delete the option to clear the cache. delete_option( 'elementor_experiment-container' ); // Update the option to 'active' to activate the flexbox container. update_option( 'elementor_experiment-container', 'active' ); } $import = new \Elementor\TemplateLibrary\Astra_Sites_Elementor_Pages(); $import_data = $import->import( $post_id, $meta ); delete_option( 'astra_sites_import_elementor_data_' . $id ); wp_send_json_success( $import_data ); } /** * API Request * * @since 2.0.0 */ public function api_request() { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error(); } $url = isset( $_POST['url'] ) ? sanitize_text_field( $_POST['url'] ) : ''; if ( empty( $url ) ) { wp_send_json_error( array( 'message' => __( 'Provided API URL is empty! Please try again!', 'astra-sites' ), 'code' => 'Error', ) ); } $api_args = apply_filters( 'astra_sites_api_params', array( 'template_status' => '', 'version' => ASTRA_SITES_VER, ) ); /** * Filter to modify the API Request URL. * * @param string $api_url The complete API request URL. * * @since 4.4.43 */ $api_url = apply_filters( 'astra_sites_api_request_' . $url, trailingslashit( self::get_instance()->get_api_domain() ) . 'wp-json/wp/v2/' . $url ); $api_url = add_query_arg( $api_args, $api_url ); if ( ! astra_sites_is_valid_url( $api_url ) ) { wp_send_json_error( array( /* Translators: %s is API URL. */ 'message' => sprintf( __( 'Invalid API Request URL - %s', 'astra-sites' ), $api_url ), 'code' => 'Error', ) ); } Astra_Sites_Error_Handler::get_instance()->start_error_handler(); $api_args = apply_filters( 'astra_sites_api_args', array( 'timeout' => 15, ) ); $request = wp_safe_remote_get( $api_url, $api_args ); Astra_Sites_Error_Handler::get_instance()->stop_error_handler(); if ( is_wp_error( $request ) ) { $wp_error_code = $request->get_error_code(); switch ( $wp_error_code ) { case 'http_request_not_executed': /* translators: %s Error Message */ $message = sprintf( __( 'API Request could not be performed - %s', 'astra-sites' ), $request->get_error_message() ); break; case 'http_request_failed': default: /* translators: %s Error Message */ $message = sprintf( __( 'API Request has failed - %s', 'astra-sites' ), $request->get_error_message() ); break; } wp_send_json_error( array( 'message' => $request->get_error_message(), 'code' => 'WP_Error', 'response_code' => $wp_error_code, ) ); } $code = (int) wp_remote_retrieve_response_code( $request ); $demo_data = json_decode( wp_remote_retrieve_body( $request ), true ); if ( 200 === $code ) { $class_list = isset( $demo_data['class_list'] ) ? $demo_data['class_list'] : array(); if ( in_array( 'astra-site-page-builder-gutenberg', $class_list, true ) ) { $spectra_blocks_version = isset( $demo_data['spectra-blocks-ver'] ) ? $demo_data['spectra-blocks-ver'] : array(); $spectra_blocks_ver = empty( $spectra_blocks_version ) || ! in_array( 'spectra-blocks-ver-v3', $class_list, true ) ? 'v2' : 'v3'; update_option( 'astra_sites_current_spectra_blocks_ver', $spectra_blocks_ver ); // For v3 templates, replace the `ultimate-addons-for-gutenberg` entry in // required-plugins with `spectra-blocks` before the data is saved and sent. // This ensures every downstream step — plugin status check, install, activate, // and verify — works with the correct plugin without additional overrides. if ( 'v3' === $spectra_blocks_ver && isset( $demo_data['required-plugins'] ) && is_array( $demo_data['required-plugins'] ) ) { $demo_data['required-plugins'] = array_map( function ( $plugin ) { if ( isset( $plugin['init'] ) && 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' === $plugin['init'] ) { $plugin['init'] = 'spectra-blocks/spectra-blocks.php'; $plugin['slug'] = 'spectra-blocks'; $plugin['name'] = 'Spectra Blocks'; } return $plugin; }, $demo_data['required-plugins'] ); } } else { delete_option( 'astra_sites_current_spectra_blocks_ver' ); } Astra_Sites_File_System::get_instance()->update_json_file( 'astra_sites_import_data.json', $demo_data ); update_option( 'astra_sites_current_import_template_type', 'classic' ); wp_send_json_success( $demo_data ); } $message = wp_remote_retrieve_body( $request ); $response_code = $code; if ( 200 !== $code && is_array( $demo_data ) && isset( $demo_data['code'] ) ) { $message = $demo_data['message']; } if ( 500 === $code ) { $message = __( 'Internal Server Error.', 'astra-sites' ); } if ( 200 !== $code && false !== strpos( $message, 'Cloudflare' ) ) { $ip = Astra_Sites_Helper::get_client_ip(); /* translators: %s IP address. */ $message = sprintf( __( 'Client IP: %1$s </br> Error code: %2$s', 'astra-sites' ), $ip, $code ); $code = 'Cloudflare'; } wp_send_json_error( array( 'message' => $message, 'code' => $code, 'response_code' => $response_code, ) ); } /** * API Request * * @since 3.2.4 */ public function elementor_api_request() { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error(); } $id = isset( $_POST['id'] ) ? absint( $_POST['id'] ) : ''; $type = isset( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : ''; if ( empty( $id ) || empty( $type ) ) { wp_send_json_error( array( 'message' => __( 'Provided API details are empty! Please try again!', 'astra-sites' ), 'code' => 'Error', ) ); } $api_args = apply_filters( 'astra_sites_api_params', array( 'url' => site_url(), 'version' => ASTRA_SITES_VER, ) ); $api_url = add_query_arg( $api_args, trailingslashit( self::get_instance()->get_api_domain() ) . 'wp-json/wp/v2/' . $type . '/' . $id ); if ( ! astra_sites_is_valid_url( $api_url ) ) { wp_send_json_error( array( /* Translators: %s is Request URL. */ 'message' => sprintf( __( 'Invalid Request URL - %s', 'astra-sites' ), $api_url ), 'code' => 'Error', ) ); } Astra_Sites_Error_Handler::get_instance()->start_error_handler(); $api_args = apply_filters( 'astra_sites_api_args', array( 'timeout' => 15, ) ); $request = wp_safe_remote_get( $api_url, $api_args ); Astra_Sites_Error_Handler::get_instance()->stop_error_handler(); if ( is_wp_error( $request ) ) { $wp_error_code = $request->get_error_code(); switch ( $wp_error_code ) { case 'http_request_not_executed': /* translators: %s Error Message */ $message = sprintf( __( 'API Request could not be performed - %s', 'astra-sites' ), $request->get_error_message() ); break; case 'http_request_failed': default: /* translators: %s Error Message */ $message = sprintf( __( 'API Request has failed - %s', 'astra-sites' ), $request->get_error_message() ); break; } wp_send_json_error( array( 'message' => $request->get_error_message(), 'code' => 'WP_Error', 'response_code' => $wp_error_code, ) ); } $code = (int) wp_remote_retrieve_response_code( $request ); $demo_data = json_decode( wp_remote_retrieve_body( $request ), true ); if ( 200 === $code ) { update_option( 'astra_sites_import_elementor_data_' . $id, $demo_data, 'no' ); wp_send_json_success( $demo_data ); } $message = wp_remote_retrieve_body( $request ); $response_code = $code; if ( 200 !== $code && is_array( $demo_data ) && isset( $demo_data['code'] ) ) { $message = $demo_data['message']; } if ( 500 === $code ) { $message = __( 'Internal Server Error.', 'astra-sites' ); } if ( 200 !== $code && false !== strpos( $message, 'Cloudflare' ) ) { $ip = Astra_Sites_Helper::get_client_ip(); /* translators: %s IP address. */ $message = sprintf( __( 'Client IP: %1$s </br> Error code: %2$s', 'astra-sites' ), $ip, $code ); $code = 'Cloudflare'; } wp_send_json_error( array( 'message' => $message, 'code' => $code, 'response_code' => $response_code, ) ); } /** * API Flush Request * * @since 3.2.4 */ public function elementor_flush_request() { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error(); } $id = isset( $_POST['id'] ) ? absint( $_POST['id'] ) : ''; delete_option( 'astra_sites_import_elementor_data_' . $id ); wp_send_json_success(); } /** * Insert Template * * @return void */ public function insert_image_templates() { ob_start(); require_once ASTRA_SITES_DIR . 'inc/includes/image-templates.php'; ob_end_flush(); } /** * Insert Template * * @return void */ public function insert_image_templates_bb_and_brizy() { if ( class_exists( 'FLBuilderModel' ) && FLBuilderModel::is_builder_active() // BB Builder is on? || ( class_exists( 'Brizy_Editor_Post' ) && // Brizy Builder is on? ( isset( $_GET['brizy-edit'] ) || isset( $_GET['brizy-edit-iframe'] ) ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Fetching GET parameter, no nonce associated with this action. ) ) { // Image Search Templates. ob_start(); require_once ASTRA_SITES_DIR . 'inc/includes/image-templates.php'; ob_end_flush(); } } /** * Insert Template * * @return void */ public function insert_templates() { ob_start(); require_once ASTRA_SITES_DIR . 'inc/includes/templates.php'; require_once ASTRA_SITES_DIR . 'inc/includes/image-templates.php'; ob_end_flush(); } /** * Add/Remove Favorite. * * @since 2.0.0 */ public function add_to_favorite() { if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'You are not allowed to perform this action', 'astra-sites' ); } // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); $new_favorites = array(); $site_id = isset( $_POST['site_id'] ) ? sanitize_key( $_POST['site_id'] ) : ''; if ( empty( $site_id ) ) { wp_send_json_error(); } $favorite_settings = get_option( 'astra-sites-favorites', array() ); if ( false !== $favorite_settings && is_array( $favorite_settings ) ) { $new_favorites = $favorite_settings; } $is_favorite = isset( $_POST['is_favorite'] ) ? sanitize_key( $_POST['is_favorite'] ) : ''; if ( 'false' === $is_favorite ) { if ( in_array( $site_id, $new_favorites, true ) ) { $key = array_search( $site_id, $new_favorites, true ); unset( $new_favorites[ $key ] ); } } else { if ( ! in_array( $site_id, $new_favorites, true ) ) { array_push( $new_favorites, $site_id ); } } update_option( 'astra-sites-favorites', $new_favorites, 'no' ); wp_send_json_success( array( 'all_favorites' => $new_favorites, ) ); } /** * Import Template. * * @since 2.0.0 */ public function create_template() { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'customize' ) ) { wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) ); } $id = isset( $_POST['id'] ) ? absint( $_POST['id'] ) : ''; $type = isset( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : ''; $demo_data = get_option( 'astra_sites_import_elementor_data_' . $id, array() ); if ( 'astra-blocks' == $type ) { $url = trailingslashit( self::get_instance()->get_api_domain() ) . 'wp-json/wp/v2/' . $type . '/' . $id; } else { $url = $demo_data['astra-page-api-url']; } $api_url = add_query_arg( array( 'site_url' => site_url(), 'version' => ASTRA_SITES_VER, ), $url ); if ( ! astra_sites_is_valid_url( $api_url ) ) { wp_send_json_error( __( 'Invalid API URL.', 'astra-sites' ) ); } $response = wp_safe_remote_get( $api_url ); if ( is_wp_error( $response ) || 200 !== $response['response']['code'] ) { wp_send_json_error( wp_remote_retrieve_body( $response ) ); } $body = wp_remote_retrieve_body( $response ); $data = json_decode( $body, true ); if ( empty( $data ) ) { wp_send_json_error( 'Empty page data.' ); } $content = isset( $data['content']['rendered'] ) ? $data['content']['rendered'] : ''; $page_id = isset( $data['id'] ) ? sanitize_text_field( $data['id'] ) : ''; $title = ''; $rendered_title = isset( $data['title']['rendered'] ) ? sanitize_text_field( $data['title']['rendered'] ) : ''; if ( isset( $rendered_title ) ) { $title = ( isset( $_POST['title'] ) && '' !== $_POST['title'] ) ? sanitize_text_field( $_POST['title'] ) . ' - ' . $rendered_title : $rendered_title; } $excerpt = isset( $data['excerpt']['rendered'] ) ? sanitize_text_field( $data['excerpt']['rendered'] ) : ''; $post_args = array( 'post_type' => 'elementor_library', 'post_status' => 'publish', 'post_title' => $title, 'post_content' => $content, 'post_excerpt' => $excerpt, ); $new_page_id = wp_insert_post( $post_args ); update_post_meta( $new_page_id, '_astra_sites_enable_for_batch', true ); $post_meta = isset( $data['post-meta'] ) ? $data['post-meta'] : array(); if ( ! empty( $post_meta ) ) { $this->import_template_meta( $new_page_id, $post_meta ); } $term_value = ( 'pages' === $type ) ? 'page' : 'section'; update_post_meta( $new_page_id, '_elementor_template_type', $term_value ); wp_set_object_terms( $new_page_id, $term_value, 'elementor_library_type' ); update_post_meta( $new_page_id, '_wp_page_template', 'elementor_header_footer' ); do_action( 'astra_sites_process_single', $new_page_id ); // Flush the object when import is successful. delete_option( 'astra_sites_import_elementor_data_' . $id ); wp_send_json_success( array( 'remove-page-id' => $page_id, 'id' => $new_page_id, 'link' => get_permalink( $new_page_id ), ) ); } /** * Search Images. * * @since 2.7.3. */ public function search_images() { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'upload_files' ) ) { wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) ); } $params = isset( $_POST['params'] ) ? array_map( 'sanitize_text_field', $_POST['params'] ) : array(); if ( empty( $this->pixabay_api_key ) ) { wp_send_json_error( __( 'Pixabay API key is not configured. Set it via the astra_sites_pixabay_api_key filter or option.', 'astra-sites' ) ); } $params['key'] = $this->pixabay_api_key; $api_url = add_query_arg( $params, $this->pixabay_url ); $response = wp_safe_remote_get( $api_url ); if ( is_wp_error( $response ) ) { wp_send_json_error( wp_remote_retrieve_body( $response ) ); } $body = wp_remote_retrieve_body( $response ); $data = json_decode( $body, true ); wp_send_json_success( $data ); } /** * Download and save the image in the media library. * * @since 2.0.0 */ public function create_image() { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'upload_files' ) ) { wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) ); } $url = isset( $_POST['url'] ) ? sanitize_url( $_POST['url'] ) : false; // phpcs:ignore -- We need to remove this ignore once the WPCS has released this issue fix - https://github.com/WordPress/WordPress-Coding-Standards/issues/2189. $name = isset( $_POST['name'] ) ? sanitize_text_field( $_POST['name'] ) : false; $photo_id = isset( $_POST['id'] ) ? absint( sanitize_key( $_POST['id'] ) ) : 0; if ( false === $url ) { wp_send_json_error( __( 'Need to send URL of the image to be downloaded', 'astra-sites' ) ); } $image = ''; $result = array(); $name = pathinfo( $name, PATHINFO_FILENAME ) . '-' . $photo_id . '.jpg'; $image = $this->create_image_from_url( $url, $name, $photo_id ); if ( is_wp_error( $image ) ) { wp_send_json_error( $image ); } if ( 0 !== $image ) { $result['attachmentData'] = wp_prepare_attachment_for_js( $image ); if ( did_action( 'elementor/loaded' ) ) { $result['data'] = Astra_Sites_Elementor_Images::get_instance()->get_attachment_data( $image ); } if ( 0 === $photo_id ) { /** * This flag ensures these files are deleted in the Reset Process. */ update_post_meta( $image, '_astra_sites_imported_post', true ); } } else { wp_send_json_error( __( 'Failed to download the image. Please verify the URL and your network connection, then try again.', 'astra-sites' ) ); } // Save downloaded image reference to an option. if ( 0 !== $photo_id ) { $saved_images = get_option( 'astra-sites-saved-images', array() ); if ( empty( $saved_images ) || false === $saved_images ) { $saved_images = array(); } $saved_images[] = $photo_id; update_option( 'astra-sites-saved-images', $saved_images, 'no' ); } $result['updated-saved-images'] = get_option( 'astra-sites-saved-images', array() ); wp_send_json_success( $result ); } /** * Set the upload directory */ public function get_wp_upload_url() { $wp_upload_dir = wp_upload_dir(); return isset( $wp_upload_dir['url'] ) ? $wp_upload_dir['url'] : false; } /** * Create the image and return the new media upload id. * * @param String $url URL to pixabay image. * @param String $name Name to pixabay image. * @param String $photo_id Photo ID to pixabay image. * @param String $description Description to pixabay image. * @see http://codex.wordpress.org/Function_Reference/wp_insert_attachment#Example */ public function create_image_from_url( $url, $name, $photo_id, $description = '' ) { require_once ABSPATH . 'wp-admin/includes/media.php'; require_once ABSPATH . 'wp-admin/includes/file.php'; require_once ABSPATH . 'wp-admin/includes/image.php'; $file_array = array(); $file_array['name'] = wp_basename( $name ); // Download file to temp location. $file_array['tmp_name'] = download_url( $url ); // If error storing temporarily, return the error. if ( is_wp_error( $file_array['tmp_name'] ) ) { return $file_array; } // Do the validation and storage stuff. $id = media_handle_sideload( $file_array, 0, null ); // If error storing permanently, unlink. if ( is_wp_error( $id ) ) { @unlink( $file_array['tmp_name'] ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_unlink -- Deleting the file from temp location. return $id; } $alt = ( '' === $description ) ? $name : $description; // Store the original attachment source in meta. add_post_meta( $id, '_source_url', $url ); update_post_meta( $id, 'astra-images', $photo_id ); update_post_meta( $id, '_wp_attachment_image_alt', $alt ); update_post_meta( $id, '_astra_sites_imported_post', true ); return $id; } /** * Import Post Meta * * @since 2.0.0 * * @param integer $post_id Post ID. * @param array $metadata Post meta. * @return void */ public function import_post_meta( $post_id, $metadata ) { $metadata = (array) $metadata; foreach ( $metadata as $meta_key => $meta_value ) { if ( $meta_value ) { if ( '_elementor_data' === $meta_key ) { $raw_data = json_decode( stripslashes( $meta_value ), true ); if ( is_array( $raw_data ) ) { $raw_data = wp_slash( wp_json_encode( $raw_data ) ); } else { $raw_data = wp_slash( $raw_data ); } } else { if ( is_serialized( $meta_value, true ) ) { $raw_data = maybe_unserialize( stripslashes( $meta_value ) ); } elseif ( is_array( $meta_value ) ) { $raw_data = json_decode( stripslashes( $meta_value ), true ); } else { $raw_data = $meta_value; } } update_post_meta( $post_id, $meta_key, $raw_data ); } } } /** * Import Post Meta * * @since 2.0.0 * * @param integer $post_id Post ID. * @param array $metadata Post meta. * @return void */ public function import_template_meta( $post_id, $metadata ) { $metadata = (array) $metadata; foreach ( $metadata as $meta_key => $meta_value ) { if ( $meta_value ) { if ( '_elementor_data' === $meta_key ) { $raw_data = json_decode( stripslashes( $meta_value ), true ); if ( is_array( $raw_data ) ) { $raw_data = wp_slash( wp_json_encode( $raw_data ) ); } else { $raw_data = wp_slash( $raw_data ); } } else { if ( is_serialized( $meta_value, true ) ) { $raw_data = maybe_unserialize( stripslashes( $meta_value ) ); } elseif ( is_array( $meta_value ) ) { $raw_data = json_decode( stripslashes( $meta_value ), true ); } else { $raw_data = $meta_value; } } update_post_meta( $post_id, $meta_key, $raw_data ); } } } /** * Close getting started notice for current user * * @since 1.3.5 * @return void */ public function getting_started_notice() { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'customize' ) ) { wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) ); } update_option( '_astra_sites_gettings_started', 'yes', 'no' ); wp_send_json_success(); } /** * Get theme install, active or inactive status. * * @since 1.3.2 * * @return string Theme status */ public function get_theme_status() { $theme = wp_get_theme(); // Theme installed and activate. if ( 'Astra' === $theme->name || 'Astra' === $theme->parent_theme ) { return 'installed-and-active'; } // Theme installed but not activate. foreach ( (array) wp_get_themes() as $theme_dir => $theme ) { if ( 'Astra' === $theme->name || 'Astra' === $theme->parent_theme ) { return 'installed-but-inactive'; } } return 'not-installed'; } /** * Loads textdomain for the plugin. * * @since 1.0.1 */ public function load_textdomain() { // Default languages directory. $lang_dir = ASTRA_SITES_DIR . 'languages/'; // Traditional WordPress plugin locale filter. global $wp_version; $get_locale = get_locale(); if ( $wp_version >= 4.7 ) { $get_locale = get_user_locale(); } /** * Language Locale for plugin * * @var $get_locale The locale to use. * Uses get_user_locale()` in WordPress 4.7 or greater, * otherwise uses `get_locale()`. */ $locale = apply_filters( 'plugin_locale', $get_locale, 'astra-sites' ); $mofile = sprintf( '%1$s-%2$s.mo', 'astra-sites', $locale ); // Setup paths to current locale file. $mofile_global = WP_LANG_DIR . '/plugins/' . $mofile; $mofile_local = $lang_dir . $mofile; if ( file_exists( $mofile_global ) ) { // Look in global /wp-content/languages/astra-sites/ folder. load_textdomain( 'astra-sites', $mofile_global ); } elseif ( file_exists( $mofile_local ) ) { // Look in local /wp-content/plugins/astra-sites/languages/ folder. load_textdomain( 'astra-sites', $mofile_local ); } else { // Load the default language files. load_plugin_textdomain( 'astra-sites', false, $lang_dir ); } } /** * Show action links on the plugin screen. * * @param mixed $links Plugin Action links. * @return array */ public function action_links( $links ) { $astra_site_pro = 'https://wpastra.com/essential-toolkit-pricing/'; // Get the starter templates URL. $url = esc_url( self::get_starter_templates_url() ); $action_links = array( 'settings' => '<a href="' . esc_url( $url ) . '" aria-label="' . esc_attr__( 'Get Started', 'astra-sites' ) . '">' . esc_html__( 'Get Started', 'astra-sites' ) . '</a>', ); // Check if Premium Starter Templates plugin is not active. if ( ! is_plugin_active( 'astra-pro-sites/astra-pro-sites.php' ) && ! file_exists( ASTRA_SITES_DIR . '../astra-pro-sites/astra-pro-sites.php' ) ) { $action_links['pro-link'] = sprintf( '<a href="%1$s" target="_blank" rel="noreferrer" class="astra-sites-plugins-go-pro" style="color: #dd4f93; text-shadow: 1px 1px 1px #eee; font-weight: bold;">%2$s</a>', esc_url( $astra_site_pro ), esc_html__( 'Get Premium Templates', 'astra-sites' ) ); } return array_merge( $action_links, $links ); } /** * Get the API URL. * * @since 1.0.0 * * @return string */ public static function get_api_domain() { return defined( 'STARTER_TEMPLATES_REMOTE_URL' ) ? STARTER_TEMPLATES_REMOTE_URL : apply_filters( 'astra_sites_api_domain', 'https://websitedemos.net/' ); } /** * Get the Metrics API URL. * * @since 4.4.37 * * @return string */ public static function get_metrics_api_domain() { return trailingslashit( defined( 'BSF_METRICS_REMOTE_URL' ) ? BSF_METRICS_REMOTE_URL : apply_filters( 'nps_survey_api_domain', 'https://metrics.brainstormforce.com/' ) ); } /** * Setter for $api_url * * @since 1.0.0 */ public function set_api_url() { $this->api_domain = trailingslashit( self::get_api_domain() ); $this->api_url = apply_filters( 'astra_sites_api_url', $this->api_domain . 'wp-json/wp/v2/' ); $this->search_analytics_url = apply_filters( 'astra_sites_search_api_url', $this->api_domain . 'wp-json/analytics/v2/search/' ); $this->import_analytics_url = apply_filters( 'astra_sites_import_analytics_api_url', $this->api_domain . 'wp-json/analytics/v2/import/' ); $this->pixabay_url = 'https://pixabay.com/api/'; $this->pixabay_api_key = apply_filters( 'astra_sites_pixabay_api_key', get_option( 'astra_sites_pixabay_api_key', '' ) ); } /** * Getter for $api_url * * @since 1.0.0 * * @return string */ public function get_api_url() { return $this->api_url; } /** * Enqueue admin scripts. * * @since 1.0.0 * * @param string $hook Current hook name. * @return void */ public function admin_enqueue( $hook = '' ) { // Avoid scripts for customizer preview and if it's not starter templates page. if ( is_customize_preview() || 'appearance_page_starter-templates' !== $hook ) { return; } global $is_IE, $is_edge; if ( $is_IE || $is_edge ) { wp_enqueue_script( 'astra-sites-eventsource', ASTRA_SITES_URI . 'inc/assets/js/eventsource.min.js', array( 'jquery', 'wp-util', 'updates' ), ASTRA_SITES_VER, true ); } // Admin Page. wp_enqueue_style( 'astra-sites-admin', ASTRA_SITES_URI . 'inc/assets/css/admin.css', ASTRA_SITES_VER, true ); wp_style_add_data( 'astra-sites-admin', 'rtl', 'replace' ); } /** * Get CTA link * * @param string $source The source of the link. * @param string $medium The medium of the link. * @param string $campaign The campaign of the link. * @return array */ public function get_cta_link( $source = '', $medium = '', $campaign = '' ) { $default_page_builder = Astra_Sites_Page::get_instance()->get_setting( 'page_builder' ); $cta_links = $this->get_cta_links( $source, $medium, $campaign ); return isset( $cta_links[ $default_page_builder ] ) ? $cta_links[ $default_page_builder ] : 'https://wpastra.com/starter-templates-plans/?utm_source=StarterTemplatesPlugin&utm_campaign=WPAdmin'; } /** * Get CTA Links * * @since 2.6.18 * * @param string $source The source of the link. * @param string $medium The medium of the link. * @param string $campaign The campaign of the link. * @return array */ public function get_cta_links( $source = '', $medium = '', $campaign = '' ) { return array( 'elementor' => add_query_arg( array( 'utm_source' => ! empty( $source ) ? $source : 'elementor-templates', 'utm_medium' => 'dashboard', 'utm_campaign' => 'Starter-Template-Backend', ), 'https://wpastra.com/essential-toolkit-pricing/' ), 'beaver-builder' => add_query_arg( array( 'utm_source' => ! empty( $source ) ? $source : 'beaver-templates', 'utm_medium' => 'dashboard', 'utm_campaign' => 'Starter-Template-Backend', ), 'https://wpastra.com/beaver-builder-starter-templates/' ), 'gutenberg' => add_query_arg( array( 'utm_source' => ! empty( $source ) ? $source : 'gutenberg-templates', 'utm_medium' => 'dashboard', 'utm_campaign' => 'Starter-Template-Backend', ), 'https://wpastra.com/essential-toolkit-pricing/' ), 'brizy' => add_query_arg( array( 'utm_source' => ! empty( $source ) ? $source : 'brizy-templates', 'utm_medium' => 'dashboard', 'utm_campaign' => 'Starter-Template-Backend', ), 'https://wpastra.com/essential-toolkit-pricing/' ), ); } /** * Returns Localization Variables. * * @since 2.0.0 */ public function get_local_vars() { $stored_data = array( 'astra-sites-site-category' => array(), 'astra-site-page-builder' => array(), 'astra-sites' => array(), 'site-pages-category' => array(), 'site-pages-page-builder' => array(), 'site-pages-parent-category' => array(), 'site-pages' => array(), 'favorites' => get_option( 'astra-sites-favorites' ), ); $favorite_data = get_option( 'astra-sites-favorites' ); $license_status = false; if ( is_callable( 'BSF_License_Manager::bsf_is_active_license' ) ) { $license_status = BSF_License_Manager::bsf_is_active_license( 'astra-pro-sites' ); } $spectra_theme = 'not-installed'; // Theme installed and activate. if ( 'spectra-one' === get_option( 'stylesheet', 'astra' ) ) { $spectra_theme = 'installed-and-active'; } $enable_block_builder = apply_filters( 'st_enable_block_page_builder', false ); $saved_page_builder = Astra_Sites_Page::get_instance()->get_setting( 'page_builder' ); if ( 'beaver-builder' === $saved_page_builder && get_option( 'st-beaver-builder-flag' ) === '1' ) { $saved_page_builder = 'gutenberg'; } if ( 'elementor' === $saved_page_builder && get_option( 'st-elementor-builder-flag' ) === '1' ) { $saved_page_builder = 'gutenberg'; } $default_page_builder = ( 'installed-and-active' === $spectra_theme ) ? 'fse' : $saved_page_builder; $default_page_builder = ( $enable_block_builder && empty( $default_page_builder ) ) ? 'gutenberg' : $default_page_builder; $remove_parameters = array( 'credit_token', 'token', 'email', 'ast_action', 'nonce' ); $credit_request_params = array( 'success_url' => isset( $_SERVER['REQUEST_URI'] ) ? urlencode( $this->remove_query_params( network_home_url() . esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), $remove_parameters ) . '&ast_action=credits' ) : '', ); $credit_purchase_url = defined( 'ZIP_AI_CREDIT_TOPUP_URL' ) ? ZIP_AI_CREDIT_TOPUP_URL : 'https://app.zipwp.com/credits-pricing'; $credit_purchase_url = add_query_arg( $credit_request_params, $credit_purchase_url ); if ( is_callable( '\SureCart\Models\ApiToken::get()' ) ) { $surecart_store_exist = \SureCart\Models\ApiToken::get(); } $plans = Astra_Sites_ZipWP_Integration::get_instance()->get_zip_plans(); $data = apply_filters( 'astra_sites_localize_vars', array( 'subscribed' => get_user_meta( get_current_user_ID(), 'astra-sites-subscribed', true ), 'debug' => defined( 'WP_DEBUG' ) ? true : false, 'isPro' => defined( 'ASTRA_PRO_SITES_NAME' ) ? true : false, 'isWhiteLabeled' => Astra_Sites_White_Label::get_instance()->is_white_labeled(), 'whiteLabelName' => Astra_Sites_White_Label::get_instance()->get_white_label_name(), 'whiteLabelUrl' => Astra_Sites_White_Label::get_instance()->get_white_label_link( '#' ), 'ajaxurl' => esc_url( admin_url( 'admin-ajax.php' ) ), 'siteURL' => site_url(), 'adminURL' => esc_url( admin_url() ), 'getProText' => __( 'Get Access!', 'astra-sites' ), 'getProURL' => esc_url( 'https://wpastra.com/starter-templates-plans/?utm_source=demo-import-panel&utm_campaign=astra-sites&utm_medium=wp-dashboard' ), 'getUpgradeText' => __( 'Upgrade', 'astra-sites' ), 'getUpgradeURL' => esc_url( 'https://wpastra.com/starter-templates-plans/?utm_source=demo-import-panel&utm_campaign=astra-sites&utm_medium=wp-dashboard' ), '_ajax_nonce' => current_user_can( 'edit_posts' ) ? wp_create_nonce( 'astra-sites' ) : '', 'requiredPlugins' => array(), 'syncLibraryStart' => '<span class="message">' . esc_html__( 'Syncing template library in the background. The process can take anywhere between 2 to 3 minutes. We will notify you once done.', 'astra-sites' ) . '</span>', 'xmlRequiredFilesMissing' => __( 'Some of the files required during the import process are missing.<br/><br/>Please try again after some time.', 'astra-sites' ), 'importFailedMessageDueToDebug' => __( '<p>The import process was interrupted as Debug mode is currently enabled on your site.</p><p>Kindly disable debug mode and try importing Starter Template again.</p><p>You can add the following code into the wp-config.php file to disable debug mode.</p><p><code>define(\'WP_DEBUG\', false);</code></p>', 'astra-sites' ), /* translators: %s is a documentation link. */ 'importFailedMessage' => sprintf( __( '<p>Template import was interrupted due to a temporary error.</p><p>Read <a href="%s" target="_blank">article</a> to resolve the issue and continue importing template.</p>', 'astra-sites' ), esc_url( 'https://wpastra.com/docs/fix-starter-template-importing-issues/' ) ), /* translators: %s is a documentation link. */ 'importFailedRequiredPluginsMessage' => sprintf( __( '<p>Failed to install one or more required plugins.</p><p>Read <a href="%s" target="_blank">article</a> to resolve the issue and continue importing template.</p>', 'astra-sites' ), esc_url( 'https://wpastra.com/docs/plugin-installation-failed-multisite/' ) ), 'strings' => array( /* translators: %s are white label strings. */ 'warningBeforeCloseWindow' => sprintf( __( 'Warning! %1$s Closing this window will cancel the process. Do you still want to leave?', 'astra-sites' ), Astra_Sites_White_Label::get_instance()->get_white_label_name() ), 'viewSite' => __( 'Done! View Site', 'astra-sites' ), 'syncCompleteMessage' => self::get_instance()->get_sync_complete_message(), /* translators: %s is a template name */ 'importSingleTemplate' => __( 'Import "%s" Template', 'astra-sites' ), ), 'log' => array( 'bulkInstall' => __( 'Installing Required Plugins..', 'astra-sites' ), /* translators: %s are white label strings. */ 'themeInstall' => sprintf( __( 'Installing %1$s Theme..', 'astra-sites' ), Astra_Sites_White_Label::get_instance()->get_option( 'astra', 'name', 'Astra' ) ), ), 'default_page_builder' => $default_page_builder, 'default_page_builder_data' => Astra_Sites_Page::get_instance()->get_default_page_builder(), 'default_page_builder_sites' => Astra_Sites_Page::get_instance()->get_sites_by_page_builder( $default_page_builder ), 'sites' => astra_sites_get_api_params(), 'categories' => array(), 'page-builders' => array(), 'all_sites' => $this->get_all_sites(), 'all_site_categories' => Astra_Sites_File_System::get_instance()->get_json_file_content( 'astra-sites-all-site-categories.json' ), 'all_site_categories_and_tags' => Astra_Sites_File_System::get_instance()->get_json_file_content( 'astra-sites-all-site-categories-and-tags.json' ), 'license_status' => $license_status, 'license_page_builder' => get_option( 'astra-sites-license-page-builder', '' ), 'ApiDomain' => $this->api_domain, 'ApiURL' => $this->api_url, 'stored_data' => $stored_data, 'favorite_data' => $favorite_data, 'category_slug' => 'astra-sites-site-category', 'page_builder' => 'astra-site-page-builder', 'cpt_slug' => 'astra-sites', 'parent_category' => '', 'compatibilities' => $this->get_compatibilities(), 'compatibilities_data' => $this->get_compatibilities_data(), 'dismiss' => __( 'Dismiss this notice.', 'astra-sites' ), 'headings' => array( 'subscription' => esc_html__( 'One Last Step..', 'astra-sites' ), 'site_import' => esc_html__( 'Your Selected Website is Being Imported.', 'astra-sites' ), 'page_import' => esc_html__( 'Your Selected Template is Being Imported.', 'astra-sites' ), ), 'subscriptionSuccessMessage' => esc_html__( 'We have sent you a surprise gift on your email address! Please check your inbox!', 'astra-sites' ), 'first_import_complete' => get_option( 'astra_sites_import_complete' ), 'server_import_primary_error' => __( 'Looks like the template you are importing is temporarily not available.', 'astra-sites' ), 'client_import_primary_error' => __( "Couldn't start import process. WordPress returned:", 'astra-sites' ), 'cloudflare_import_primary_error' => __( 'There was an error connecting to the Starter Templates API.', 'astra-sites' ), 'xml_import_interrupted_primary' => __( 'There was an error while importing the content.', 'astra-sites' ), 'xml_import_interrupted_secondary' => __( 'To import content, WordPress needs to store XML file in /wp-content/ folder. Please get in touch with your hosting provider.', 'astra-sites' ), 'xml_import_interrupted_error' => __( 'Looks like your host probably could not store XML file in /wp-content/ folder.', 'astra-sites' ), /* translators: %s HTML tags */ 'ajax_request_failed_primary' => sprintf( __( '%1$sAJAX request failed. WordPress returned:%2$s', 'astra-sites' ), '<p>', '</p>' ), /* translators: %s URL to document. */ 'ajax_request_failed_secondary' => sprintf( __( '%1$sRead <a href="%2$s" target="_blank">article</a> to resolve the issue and continue importing template.%3$s', 'astra-sites' ), '<p>', esc_url( 'https://wpastra.com/docs/internal-server-error-starter-templates/' ), '</p>' ), 'cta_links' => $this->get_cta_links(), 'cta_quick_corner_links' => $this->get_cta_links( 'quick-links-corner' ), 'cta_premium_popup_links' => $this->get_cta_links( 'get-premium-access-popup' ), 'cta_link' => $this->get_cta_link(), 'cta_quick_corner_link' => $this->get_cta_link( 'quick-links-corner' ), 'cta_premium_popup_link' => $this->get_cta_link( 'get-premium-access-popup' ), /* translators: %s URL to document. */ 'process_failed_primary' => sprintf( __( '%1$sImport process interrupted due to an AJAX error:%2$s', 'astra-sites' ), '<p>', '</p>' ), /* translators: %s URL to document. */ 'process_failed_secondary' => sprintf( __( '%1$sPlease report this <a href="%2$s" target="_blank">here</a>.%3$s', 'astra-sites' ), '<p>', esc_url( 'https://wpastra.com/starter-templates-support/?url=#DEMO_URL#&subject=#SUBJECT#' ), '</p>' ), 'st_page_url' => esc_url( self::get_starter_templates_url() ), 'staging_connected' => apply_filters( 'astra_sites_staging_connected', '' ), 'isRTLEnabled' => is_rtl(), /* translators: %s Anchor link to support URL. */ 'support_text' => sprintf( __( 'Please report this error%1$s here %2$s, so we can fix it.', 'astra-sites' ), '<a href="https://wpastra.com/support/open-a-ticket/" target="_blank">', '</a>' ), 'surecart_store_exists' => isset( $surecart_store_exist ) ? $surecart_store_exist : false, 'default_ai_categories' => $this->get_default_ai_categories(), 'block_color_palette' => $this->get_block_palette_colors(), 'page_color_palette' => $this->get_page_palette_colors(), 'rest_api_nonce' => ( current_user_can( 'manage_options' ) ) ? wp_create_nonce( 'wp_rest' ) : '', 'zip_token_exists' => Astra_Sites_ZipWP_Helper::get_token() !== '' ? true : false, 'zip_plans' => ( $plans && isset( $plans['data'] ) ) ? $plans['data'] : array(), 'dashboard_url' => admin_url(), 'finish_setup_url' => admin_url( 'admin.php?page=getting-started' ), 'placeholder_images' => Helper::get_image_placeholders(), 'get_more_credits_url' => $credit_purchase_url, 'dismiss_ai_notice' => Astra_Sites_Page::get_instance()->get_setting( 'dismiss_ai_promotion' ), 'showClassicTemplates' => apply_filters( 'astra_sites_show_classic_templates', true ), 'showAiBuilder' => self::should_show_ai_builder(), 'customTemplateData' => self::get_custom_template_data(), 'bgSyncInProgress' => self::is_sync_in_progress(), 'userDetails' => array( 'first_name' => get_user_meta( get_current_user_ID(), 'first_name', true ), 'last_name' => get_user_meta( get_current_user_ID(), 'last_name', true ), 'email' => wp_get_current_user()->user_email, ), // Spectra Blocks Vars. 'spectraBlocks' => apply_filters( 'astra_sites_spectra_blocks_vars', array( 'selectorEnabled' => self::should_display_spectra_blocks_version_selector(), 'version' => self::get_spectra_blocks_version(), ) ), 'isWPFreshSite' => $this->is_wp_fresh_site(), 'priorityTemplates' => $this->get_priority_templates_config(), ) ); return $data; } /** * Check if the site is a fresh WordPress installation. * Detects if only default WordPress content exists (Hello World post, Sample Page, etc.). * * @since 4.4.46 * @return bool True if site is fresh, false otherwise. */ public function is_wp_fresh_site() { // Check if first import has already been completed. if ( get_option( 'astra_sites_import_complete', false ) ) { return false; } // Count published posts (excluding auto-drafts). $post_count = wp_count_posts( 'post' ); $published_posts = isset( $post_count->publish ) ? $post_count->publish : 0; // Count published pages. $page_count = wp_count_posts( 'page' ); $published_pages = isset( $page_count->publish ) ? $page_count->publish : 0; // Check if there are only default posts/pages (1 post "Hello World", 1-2 pages like "Sample Page", "Privacy Policy"). $has_default_content_only = $published_posts <= 1 && $published_pages <= 2; // Check for media attachments (fresh site typically has 0-1 media items). $media_count = wp_count_posts( 'attachment' ); $total_media = isset( $media_count->inherit ) ? $media_count->inherit : 0; $has_minimal_media = $total_media <= 1; // Check if any custom post types exist (excluding built-in ones). $args = array( 'public' => true, '_builtin' => false, ); $custom_post_types = get_post_types( $args, 'names' ); $has_no_custom_content = true; foreach ( $custom_post_types as $post_type ) { $cpt_count = wp_count_posts( $post_type ); if ( isset( $cpt_count->publish ) && $cpt_count->publish > 0 ) { $has_no_custom_content = false; break; } } // Site is considered fresh if it has default content, minimal media, and no custom content. return $has_default_content_only && $has_minimal_media && $has_no_custom_content; } /** * Get palette colors * * @since 4.0.0 * * @return mixed */ public function get_page_palette_colors() { $default_palette_color = array( '#046bd2', '#045cb4', '#1e293b', '#334155', '#f9fafb', '#FFFFFF', '#e2e8f0', '#cbd5e1', '#94a3b8', ); if ( class_exists( 'Astra_Global_Palette' ) ) { $astra_palette_colors = astra_get_palette_colors(); $default_palette_color = $astra_palette_colors['palettes'][ $astra_palette_colors['currentPalette'] ]; } $palette_one = $default_palette_color; $palette_two = array( $default_palette_color[0], $default_palette_color[1], $default_palette_color[5], $default_palette_color[4], $default_palette_color[3], $default_palette_color[2], $default_palette_color[6], $default_palette_color[7], $default_palette_color[8], ); $color_palettes = array( 'style-1' => array( 'slug' => 'style-1', 'title' => 'Light', 'default_color' => $default_palette_color[4], 'colors' => $palette_one, ), 'style-2' => array( 'slug' => 'style-2', 'title' => 'Dark', 'default_color' => '#1E293B', 'colors' => $palette_two, ), ); return $color_palettes; } /** * Get default AI categories. * * @since 2.0.0 * * @return array */ public function get_default_ai_categories() { return array( 'business' => 'Business', 'person' => 'Person', 'organisation' => 'Organisation', 'restaurant' => 'Restaurant', 'product' => 'Product', 'event' => 'Event', 'landing-page' => 'Landing Page', 'medical' => 'Medical', ); } /** * Get palette colors * * @since 4.0.0 * * @return mixed */ public function get_block_palette_colors() { $default_palette_color = array( '#046bd2', '#045cb4', '#1e293b', '#334155', '#f9fafb', '#FFFFFF', '#e2e8f0', '#cbd5e1', '#94a3b8', ); if ( class_exists( 'Astra_Global_Palette' ) ) { $astra_palette_colors = astra_get_palette_colors(); $default_palette_color = $astra_palette_colors['palettes'][ $astra_palette_colors['currentPalette'] ]; } $palette_one = array( $default_palette_color[0], $default_palette_color[1], $default_palette_color[2], $default_palette_color[3], $default_palette_color[5], $default_palette_color[5], $default_palette_color[6], $default_palette_color[7], $default_palette_color[8], ); $palette_two = $default_palette_color; $palette_three = array( $default_palette_color[3], $default_palette_color[2], $default_palette_color[5], $default_palette_color[4], $default_palette_color[0], $default_palette_color[1], $default_palette_color[6], $default_palette_color[7], $default_palette_color[8], ); $color_palettes = array( 'style-1' => array( 'slug' => 'style-1', 'title' => 'Light', 'default_color' => $default_palette_color[5], 'colors' => $palette_one, ), 'style-2' => array( 'slug' => 'style-2', 'title' => 'Dark', 'default_color' => $default_palette_color[4], 'colors' => $palette_two, ), 'style-3' => array( 'slug' => 'style-3', 'title' => 'Highlight', 'default_color' => $default_palette_color[0], 'colors' => $palette_three, ), ); return $color_palettes; } /** * Display subscription form * * @since 2.6.1 * * @return boolean */ public function should_display_subscription_form() { $subscription = apply_filters( 'astra_sites_should_display_subscription_form', null ); if ( null !== $subscription ) { return $subscription; } // Is WhiteLabel enabled? if ( Astra_Sites_White_Label::get_instance()->is_white_labeled() ) { return false; } // Is Premium Starter Templates pluign? if ( defined( 'ASTRA_PRO_SITES_NAME' ) ) { return false; } // User already subscribed? $subscribed = get_user_meta( get_current_user_ID(), 'astra-sites-subscribed', true ); if ( $subscribed ) { return false; } return true; } /** * Import Compatibility Errors * * @since 2.0.0 * @return mixed */ public function get_compatibilities_data() { return array( 'xmlreader' => array( 'title' => esc_html__( 'XMLReader Support Missing', 'astra-sites' ), /* translators: %s doc link. */ 'tooltip' => '<p>' . esc_html__( 'You\'re close to importing the template. To complete the process, enable XMLReader support on your website..', 'astra-sites' ) . '</p><p>' . sprintf( __( 'Read an article <a href="%s" target="_blank">here</a> to resolve the issue.', 'astra-sites' ), 'https://wpastra.com/docs/xmlreader-missing/' ) . '</p>', ), 'curl' => array( 'title' => esc_html__( 'cURL Support Missing', 'astra-sites' ), /* translators: %s doc link. */ 'tooltip' => '<p>' . esc_html__( 'To run a smooth import, kindly enable cURL support on your website.', 'astra-sites' ) . '</p><p>' . sprintf( __( 'Read an article <a href="%s" target="_blank">here</a> to resolve the issue.', 'astra-sites' ), 'https://wpastra.com/docs/curl-support-missing/' ) . '</p>', ), 'wp-debug' => array( 'title' => esc_html__( 'Disable Debug Mode', 'astra-sites' ), /* translators: %s doc link. */ 'tooltip' => '<p>' . esc_html__( 'WordPress debug mode is currently enabled on your website. With this, any errors from third-party plugins might affect the import process.', 'astra-sites' ) . '</p><p>' . esc_html__( 'Kindly disable it to continue importing the Starter Template. To do so, you can add the following code into the wp-config.php file.', 'astra-sites' ) . '</p><p><code>define(\'WP_DEBUG\', false);</code></p><p>' . sprintf( __( 'Read an article <a href="%s" target="_blank">here</a> to resolve the issue.', 'astra-sites' ), 'https://wpastra.com/docs/disable-debug-mode/' ) . '</p>', ), 'update-available' => array( 'title' => esc_html__( 'Update Plugin', 'astra-sites' ), /* translators: %s update page link. */ 'tooltip' => '<p>' . esc_html__( 'Updates are available for one or more plugins used by this starter template.', 'astra-sites' ) . '</p>##LIST##<p>' . sprintf( __( 'Kindly <a href="%s" target="_blank">update</a> them for a successful import. Skipping this step might break the template design/feature.', 'astra-sites' ), esc_url( network_admin_url( 'update-core.php' ) ) ) . '</p>', ), 'third-party-required' => array( 'title' => esc_html__( 'Required Plugins Missing', 'astra-sites' ), 'tooltip' => '<p>' . esc_html__( 'This starter template requires premium plugins. As these are third party premium plugins, you\'ll need to purchase, install and activate them first.', 'astra-sites' ) . '</p>', ), 'dynamic-page' => array( 'title' => esc_html__( 'Dynamic Page', 'astra-sites' ), 'tooltip' => '<p>' . esc_html__( 'The page template you are about to import contains a dynamic widget/module. Please note this dynamic data will not be available with the imported page.', 'astra-sites' ) . '</p><p>' . esc_html__( 'You will need to add it manually on the page.', 'astra-sites' ) . '</p><p>' . esc_html__( 'This dynamic content will be available when you import the entire site.', 'astra-sites' ) . '</p>', ), 'flexbox-container' => array( 'title' => esc_html__( 'Enable Flexbox Container from Elementor', 'astra-sites' ), /* translators: %s doc link. */ 'tooltip' => '<p>' . esc_html__( 'The Flexbox Container widget is disabled on your website. With this disabled, the import process will be affected. Kindly enable it to continue importing the Starter Template.', 'astra-sites' ) . '</p><p>' . sprintf( __( 'Read an article <a href="%s" target="_blank">here</a> to resolve the issue.', 'astra-sites' ), 'https://wpastra.com/docs/enable-flexbox-container-from-elementor' ) . '</p>', ), 'install-plugin-permission' => array( 'title' => esc_html__( 'Missing plugin installation permission', 'astra-sites' ), /* translators: %s doc link. */ 'tooltip' => '<p>' . esc_html__( 'You do not have permission to install the required plugin. You must have install permissions to proceed with the required plugin.', 'astra-sites' ) . '</p>', ), 'activate-plugin-permission' => array( 'title' => esc_html__( 'Missing plugin activation permission', 'astra-sites' ), /* translators: %s doc link. */ 'tooltip' => '<p>' . esc_html__( 'You do not have permission to activate the required plugin. You must have activate permissions to proceed with the required plugin.', 'astra-sites' ) . '</p>', ), 'wp-memory-limit' => array( 'title' => esc_html__( 'Insufficient Memory Limit', 'astra-sites' ), /* translators: %s doc link. */ 'tooltip' => '<p>' . esc_html__( 'The memory limit of your site is below the recommended 256MB. While you can proceed, increasing the memory limit is advised for a seamless import experience.', 'astra-sites' ) . '</p>', ), 'max-execution-time' => array( 'title' => esc_html__( 'Low Max Execution Time', 'astra-sites' ), 'tooltip' => '<p>' . esc_html__( "Your server's max_execution_time is below the recommended 300 seconds. This may cause import timeouts. Please contact your hosting provider to increase it.", 'astra-sites' ) . '</p>', ), 'mysql-version' => array( 'title' => esc_html__( 'MySQL Version Too Old', 'astra-sites' ), 'tooltip' => '<p>' . esc_html__( 'Your MySQL version is below 5.7. Some templates require MySQL 5.7 or higher for full utf8mb4 collation support. Please upgrade your database server.', 'astra-sites' ) . '</p>', ), ); } /** * Get all compatibilities * * @since 2.0.0 * * @return array */ public function get_compatibilities() { $data = $this->get_compatibilities_data(); $compatibilities = array( 'errors' => array(), 'warnings' => array(), ); if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { $compatibilities['warnings']['wp-debug'] = $data['wp-debug']; } if ( ! class_exists( 'XMLReader' ) ) { $compatibilities['errors']['xmlreader'] = $data['xmlreader']; } if ( ! function_exists( 'curl_version' ) ) { $compatibilities['errors']['curl'] = $data['curl']; } $flexbox_container = get_option( 'elementor_experiment-container' ); // Check if the value is 'inactive'. if ( 'inactive' === $flexbox_container ) { $compatibilities['warnings']['flexbox-container'] = $data['flexbox-container']; } $memory_limit = $this->get_original_memory_limit(); // Convert memory limit to bytes for comparison. $memory_limit_in_bytes = wp_convert_hr_to_bytes( $memory_limit ); // 256MB in bytes. $required_memory_limit = 256 * 1024 * 1024; if ( $memory_limit_in_bytes < $required_memory_limit ) { $compatibilities['warnings']['wp-memory-limit'] = $data['wp-memory-limit']; } $max_execution_time = (int) ini_get( 'max_execution_time' ); // 0 means unlimited — no warning needed. if ( $max_execution_time > 0 && $max_execution_time < 300 ) { $compatibilities['warnings']['max-execution-time'] = $data['max-execution-time']; } $mysql_version = get_transient( 'astra_sites_mysql_version' ); if ( false === $mysql_version ) { global $wpdb; $mysql_version = $wpdb->db_version(); set_transient( 'astra_sites_mysql_version', $mysql_version, WEEK_IN_SECONDS ); } if ( version_compare( $mysql_version, '5.7', '<' ) ) { $compatibilities['warnings']['mysql-version'] = $data['mysql-version']; } if ( ! current_user_can( 'install_plugins' ) ) { $compatibilities['errors']['install-plugin-permission'] = $data['install-plugin-permission']; } if ( ! current_user_can( 'activate_plugins' ) ) { $compatibilities['errors']['activate-plugin-permission'] = $data['activate-plugin-permission']; } return $compatibilities; } /** * Retrieves the original memory limit from the PHP configuration (php.ini) file. * * This is necessary because WordPress automatically increases the memory limit for admin requests, * so we need to fetch the original value from the PHP configuration file to check if it's sufficient. * * @since 4.4.16 */ public function get_original_memory_limit() { // This will fetch the original memory_limit from the server (php.ini). $memory_limit = false; if ( function_exists( 'get_cfg_var' ) ) { $memory_limit = get_cfg_var( 'memory_limit' ); } // If get_cfg_var() fails, try accessing PHP configuration directly. if ( ! $memory_limit ) { $memory_limit = ini_get( 'memory_limit' ); } return $memory_limit; } /** * Register module required js on elementor's action. * * @since 2.0.0 */ public function register_widget_scripts() { $page_builders = self::get_instance()->get_page_builders(); $has_elementor = false; // Use this filter to remove the Starter Templates button from Elementor Editor. $elementor_add_ast_site_button = apply_filters( 'starter_templates_hide_elementor_button', false ); foreach ( $page_builders as $page_builder ) { if ( 'elementor' === $page_builder['slug'] ) { $has_elementor = true; } } if ( ! $has_elementor ) { return; } if ( $elementor_add_ast_site_button ) { return; } wp_enqueue_script( 'astra-sites-helper', ASTRA_SITES_URI . 'inc/assets/js/helper.js', array( 'jquery' ), ASTRA_SITES_VER, true ); wp_enqueue_script( 'masonry' ); wp_enqueue_script( 'imagesloaded' ); wp_enqueue_script( 'astra-sites-elementor-admin-page', ASTRA_SITES_URI . 'inc/assets/js/elementor-admin-page.js', array( 'jquery', 'wp-util', 'updates', 'masonry', 'imagesloaded' ), ASTRA_SITES_VER, true ); wp_add_inline_script( 'astra-sites-elementor-admin-page', sprintf( 'var pagenow = "%s";', ASTRA_SITES_NAME ), 'after' ); wp_enqueue_style( 'astra-sites-admin', ASTRA_SITES_URI . 'inc/assets/css/admin.css', ASTRA_SITES_VER, true ); wp_style_add_data( 'astra-sites-admin', 'rtl', 'replace' ); $license_status = false; if ( is_callable( 'BSF_License_Manager::bsf_is_active_license' ) ) { $license_status = BSF_License_Manager::bsf_is_active_license( 'astra-pro-sites' ); } /* translators: %s are link. */ $license_msg = sprintf( __( 'This is a premium template available with Essential and Business Toolkits. you can purchase it from <a href="%s" target="_blank">here</a>.', 'astra-sites' ), 'https://wpastra.com/starter-templates-plans/' ); if ( defined( 'ASTRA_PRO_SITES_NAME' ) ) { /* translators: %s are link. */ $license_msg = sprintf( __( 'This is a premium template available with Essential and Business Toolkits. <a href="%s" target="_blank">Validate Your License</a> Key to import this template.', 'astra-sites' ), esc_url( admin_url( 'plugins.php?bsf-inline-license-form=astra-pro-sites' ) ) ); } $last_viewed_block_data = array(); // Retrieve the value of the 'blockID' parameter using filter_input(). $id = filter_input( INPUT_GET, 'blockID', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); if ( ! empty( $id ) ) { $last_viewed_block_data = get_option( 'astra_sites_import_elementor_data_' . $id ) !== false ? get_option( 'astra_sites_import_elementor_data_' . $id ) : array(); } $all_blocks = $this->get_all_blocks(); // Collect category IDs that have at least one block. $used_category_ids = array(); foreach ( $all_blocks as $block ) { if ( ! empty( $block['category'] ) ) { $used_category_ids[ (int) $block['category'] ] = true; } } // Filter block categories to only include those with available blocks. $all_categories = Astra_Sites_File_System::get_instance()->get_json_file_content( 'astra-blocks-categories.json' ); $filtered_categories = array(); if ( is_array( $all_categories ) ) { foreach ( $all_categories as $cat_id => $cat_data ) { if ( isset( $cat_data['id'] ) && isset( $used_category_ids[ (int) $cat_data['id'] ] ) ) { $filtered_categories[ $cat_id ] = $cat_data; } } } $data = apply_filters( 'astra_sites_render_localize_vars', array( 'plugin_name' => Astra_Sites_White_Label::get_instance()->get_white_label_name(), 'sites' => astra_sites_get_api_params(), 'version' => ASTRA_SITES_VER, 'settings' => array(), 'page-builders' => array(), 'categories' => array(), 'default_page_builder' => 'elementor', 'astra_blocks' => $all_blocks, 'license_status' => $license_status, 'ajaxurl' => esc_url( admin_url( 'admin-ajax.php' ) ), 'default_page_builder_sites' => Astra_Sites_Page::get_instance()->get_sites_by_page_builder( 'elementor' ), 'ApiURL' => $this->api_url, '_ajax_nonce' => current_user_can( 'edit_posts' ) ? wp_create_nonce( 'astra-sites' ) : '', 'isPro' => defined( 'ASTRA_PRO_SITES_NAME' ) ? true : false, 'license_msg' => $license_msg, 'isWhiteLabeled' => Astra_Sites_White_Label::get_instance()->is_white_labeled(), 'getProText' => __( 'Get Access!', 'astra-sites' ), 'getProURL' => esc_url( 'https://wpastra.com/starter-templates-plans/?utm_source=demo-import-panel&utm_campaign=astra-sites&utm_medium=wp-dashboard' ), 'astra_block_categories' => $filtered_categories, 'siteURL' => site_url(), 'template' => esc_html__( 'Template', 'astra-sites' ), 'block' => esc_html__( 'Block', 'astra-sites' ), 'dismiss_text' => esc_html__( 'Dismiss', 'astra-sites' ), 'install_plugin_text' => esc_html__( 'Install Required Plugins', 'astra-sites' ), 'syncCompleteMessage' => self::get_instance()->get_sync_complete_message(), /* translators: %s are link. */ 'page_settings' => array( 'message' => __( 'You can locate <strong>Starter Templates Settings</strong> under the <strong>Page Settings</strong> of the Style Tab.', 'astra-sites' ), 'url' => '#', 'url_text' => __( 'Read More →', 'astra-sites' ), ), 'last_viewed_block_data' => $last_viewed_block_data, ) ); wp_localize_script( 'astra-sites-elementor-admin-page', 'astraElementorSites', $data ); } /** * Register module required js on elementor's action. * * @since 2.0.0 */ public function popup_styles() { wp_enqueue_style( 'astra-sites-elementor-admin-page', ASTRA_SITES_URI . 'inc/assets/css/elementor-admin.css', ASTRA_SITES_VER, true ); wp_enqueue_style( 'astra-sites-elementor-admin-page-dark', ASTRA_SITES_URI . 'inc/assets/css/elementor-admin-dark.css', ASTRA_SITES_VER, true ); wp_style_add_data( 'astra-sites-elementor-admin-page', 'rtl', 'replace' ); } /** * Get all sites * * @since 2.0.0 * @return array All sites. */ public function get_all_sites() { $sites_and_pages = array(); $total_requests = (int) Astra_Sites_File_System::get_instance()->get_json_file_content( 'astra-sites-requests.json' ); for ( $page = 1; $page <= $total_requests; $page++ ) { $current_page_data = Astra_Sites_File_System::get_instance()->get_json_file_content( 'astra-sites-and-pages-page-' . $page . '.json' ); if ( ! empty( $current_page_data ) ) { foreach ( $current_page_data as $page_id => $page_data ) { $sites_and_pages[ $page_id ] = $page_data; } } } /** * Filter to modify all sites and pages data. * * @param array $sites_and_pages Array of all sites and pages. * * @since 4.4.43 */ return apply_filters( 'astra_sites_get_all_sites', $sites_and_pages ); } /** * Get priority templates configuration for category-based pinning. * * Scans all sites for templates that use SureCart (detected via required-plugins) * and belong to the ecommerce category. These template IDs are shipped to the * frontend so they can be pinned to the top of search results when the user * searches for ecommerce-related keywords. * * Gated by the {@see 'astra_sites_priority_templates_enabled'} filter (default true). * * @since 4.6.2 * @return array { * @type array $priorityTemplatesByCategory Category slug => array of template IDs. * @type array $priorityCategoryKeywords Category slug => array of trigger keywords. * } */ private function get_priority_templates_config() { /** * Master switch for priority template pinning. * * @since 4.6.2 * @param bool $enabled Whether priority pinning is enabled. Default true. */ $enabled = apply_filters( 'astra_sites_priority_templates_enabled', true ); if ( ! $enabled ) { return array( 'priorityTemplatesByCategory' => array(), 'priorityCategoryKeywords' => array(), ); } $all_sites = $this->get_all_sites(); $priority_ids = array(); foreach ( $all_sites as $site_id => $site ) { $required_plugins = isset( $site['required-plugins'] ) ? $site['required-plugins'] : array(); $plugin_slugs = wp_list_pluck( $required_plugins, 'slug' ); if ( ! in_array( 'surecart', $plugin_slugs, true ) ) { continue; } $categories = isset( $site['categories'] ) ? $site['categories'] : array(); if ( ! in_array( 'ecommerce', array_values( $categories ), true ) ) { continue; } $priority_ids[] = str_replace( 'id-', '', $site_id ); } $priority_by_category = array( 'ecommerce' => array_map( 'intval', $priority_ids ), ); /** * Filter the priority templates map (category slug => template IDs). * * @since 4.6.2 * @param array $priority_by_category Associative array of category slug to template ID arrays. */ $priority_by_category = apply_filters( 'astra_sites_priority_templates_by_category', $priority_by_category ); $keywords = array( 'ecommerce' => array( 'ecommerce', 'e-commerce', 'shop', 'store', 'online shopping', 'woocommerce', 'shopping' ), ); /** * Filter the keywords that trigger priority pinning for each category. * * @since 4.6.2 * @param array $keywords Associative array of category slug to keyword arrays. */ $keywords = apply_filters( 'astra_sites_priority_category_keywords', $keywords ); return array( 'priorityTemplatesByCategory' => $priority_by_category, 'priorityCategoryKeywords' => $keywords, ); } /** * Get all sites * * @since 2.2.4 * @param string $option Site options name. * @return mixed Site Option value. */ public function get_api_option( $option ) { return get_site_option( $option, array() ); } /** * Get all blocks * * @since 2.0.0 * @return array All Elementor Blocks. */ public function get_all_blocks() { $blocks = array(); $total_requests = (int) Astra_Sites_File_System::get_instance()->get_json_file_content( 'astra-blocks-requests.json' ); for ( $page = 1; $page <= $total_requests; $page++ ) { $current_page_data = Astra_Sites_File_System::get_instance()->get_json_file_content( 'astra-blocks-' . $page . '.json' ); if ( ! empty( $current_page_data ) ) { foreach ( $current_page_data as $page_id => $page_data ) { $blocks[ $page_id ] = $page_data; } } } return $blocks; } /** * Load all the required files in the importer. * * @since 1.0.0 */ private function includes() { require_once ASTRA_SITES_DIR . 'inc/classes/functions.php'; require_once ASTRA_SITES_DIR . 'inc/classes/compatibility/class-astra-sites-compatibility.php'; // classes 'inc/classes/class-astra-sites-'. require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-utils.php'; require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-error-handler.php'; require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-white-label.php'; require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-page.php'; require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-elementor-pages.php'; require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-elementor-images.php'; require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-importer.php'; require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-wp-cli.php'; require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-file-system.php'; require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-nps-notice.php'; require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-analytics.php'; require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-update.php'; // Astra Onboarding Integration. require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-astra-onboarding.php'; // libraries 'inc/lib/class-astra-sites-'. require_once ASTRA_SITES_DIR . 'inc/lib/onboarding/class-onboarding.php'; require_once ASTRA_SITES_DIR . 'inc/lib/class-astra-sites-ast-block-templates.php'; require_once ASTRA_SITES_DIR . 'inc/lib/class-astra-sites-zip-ai.php'; require_once ASTRA_SITES_DIR . 'inc/lib/class-astra-sites-zipwp-images.php'; require_once ASTRA_SITES_DIR . 'inc/lib/class-astra-sites-nps-survey.php'; } /** * After Plugin Activate * * @since 2.0.0 * * @param string $plugin_init Plugin Init File. * @param array<string, mixed> $options Site Options. * @param array<string, mixed> $enabled_extensions Enabled Extensions. * @param string $plugin_slug Plugin slug. * @param bool $was_plugin_active Flag indicating if the plugin was already active. * @return void */ public function after_plugin_activate( $plugin_init = '', $options = array(), $enabled_extensions = array(), $plugin_slug = '', $was_plugin_active = false ) { $data = array( 'astra_site_options' => $options, 'enabled_extensions' => $enabled_extensions, 'plugin_slug' => $plugin_slug, 'was_plugin_active' => $was_plugin_active, ); do_action( 'astra_sites_after_plugin_activation', $plugin_init, $data ); } /** * Has Pro Version Support? * And * Is Pro Version Installed? * * Check Pro plugin version exist of requested plugin lite version. * * Eg. If plugin 'BB Lite Version' required to import demo. Then we check the 'BB Agency Version' is exist? * If yes then we only 'Activate' Agency Version. [We couldn't install agency version.] * Else we 'Activate' or 'Install' Lite Version. * * @since 1.0.1 * * @param string $lite_version Lite version init file. * @return mixed Return false if not installed or not supported by us * else return 'Pro' version details. */ public function pro_plugin_exist( $lite_version = '' ) { // Lite init => Pro init. $plugins = apply_filters( 'astra_sites_pro_plugin_exist', array( 'beaver-builder-lite-version/fl-builder.php' => array( 'slug' => 'bb-plugin', 'init' => 'bb-plugin/fl-builder.php', 'name' => 'Beaver Builder Plugin', ), 'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php' => array( 'slug' => 'bb-ultimate-addon', 'init' => 'bb-ultimate-addon/bb-ultimate-addon.php', 'name' => 'Ultimate Addon for Beaver Builder', ), 'wpforms-lite/wpforms.php' => array( 'slug' => 'wpforms', 'init' => 'wpforms/wpforms.php', 'name' => 'WPForms', ), ), $lite_version ); if ( isset( $plugins[ $lite_version ] ) ) { // Pro plugin directory exist? if ( file_exists( WP_PLUGIN_DIR . '/' . $plugins[ $lite_version ]['init'] ) ) { return $plugins[ $lite_version ]; } } return false; } /** * Get Default Page Builders * * @since 2.0.0 * @return array */ public function get_default_page_builders() { return array( array( 'id' => 42, 'slug' => 'gutenberg', 'name' => 'Gutenberg', ), array( 'id' => 33, 'slug' => 'elementor', 'name' => 'Elementor', ), array( 'id' => 34, 'slug' => 'beaver-builder', 'name' => 'Beaver Builder', ), array( 'id' => 41, 'slug' => 'brizy', 'name' => 'Brizy', ), ); } /** * Get Page Builders * * @since 2.0.0 * @return array */ public function get_page_builders() { return $this->get_default_page_builders(); } /** * Get Page Builder Filed * * @since 2.0.0 * @param string $page_builder Page Bulider. * @param string $field Field name. * @return mixed */ public function get_page_builder_field( $page_builder = '', $field = '' ) { if ( empty( $page_builder ) ) { return ''; } $page_builders = self::get_instance()->get_page_builders(); if ( empty( $page_builders ) ) { return ''; } foreach ( $page_builders as $key => $current_page_builder ) { if ( $page_builder === $current_page_builder['slug'] ) { if ( isset( $current_page_builder[ $field ] ) ) { return $current_page_builder[ $field ]; } } } return ''; } /** * Get License Key * * @since 2.0.0 * @return string */ public function get_license_key() { if ( class_exists( 'BSF_License_Manager' ) ) { if ( BSF_License_Manager::bsf_is_active_license( 'astra-pro-sites' ) ) { return BSF_License_Manager::instance()->bsf_get_product_info( 'astra-pro-sites', 'purchase_key' ); } } return ''; } /** * Get Sync Complete Message * * @since 2.0.0 * @param boolean $echo Echo the message. * @return mixed */ public function get_sync_complete_message( $echo = false ) { $message = __( 'Template library refreshed!', 'astra-sites' ); if ( $echo ) { echo esc_html( $message ); } else { return esc_html( $message ); } } /** * Get an instance of WP_Filesystem. * * Returns null when WP_Filesystem() fails to initialise (e.g. FTP method * selected without valid credentials), preventing fatal errors when callers * invoke filesystem methods on a partially initialised global. * * @since 2.0.0 * @return \WP_Filesystem_Base|null Filesystem instance, or null on failure. */ public static function get_filesystem() { global $wp_filesystem; require_once ABSPATH . '/wp-admin/includes/file.php'; if ( ! WP_Filesystem() ) { return null; } return $wp_filesystem; } /** * Disable WP-Forms redirect. * * @return void. */ public function disable_wp_forms_redirect() { $wp_forms_redirect = get_transient( 'wpforms_activation_redirect' ); if ( ! empty( $wp_forms_redirect ) && '' !== $wp_forms_redirect ) { delete_transient( 'wpforms_activation_redirect' ); } } /** * Admin Dashboard Notices. * * @since 3.1.17 * @return void */ public function admin_dashboard_notices() { if ( defined( 'ASTRA_SITES_VER' ) ) { add_action( 'admin_notices', array( $this, 'admin_welcome_notices' ) ); } elseif ( defined( 'ASTRA_PRO_SITES_VER' ) ) { add_action( 'admin_notices', array( $this, 'admin_welcome_notices' ) ); } } /** * Admin Welcome Notice. * * @since 3.1.17 * @return void */ public function admin_welcome_notices() { $first_import_status = get_option( 'astra_sites_import_complete', false ); BSF_Admin_Notices::add_notice( array( 'id' => 'astra-sites-welcome-notice', 'type' => 'notice', 'class' => 'astra-sites-welcome', 'show_if' => ( false === Astra_Sites_White_Label::get_instance()->is_white_labeled() && empty( $first_import_status ) ), /* translators: %1$s white label plugin name and %2$s deactivation link */ 'message' => sprintf( '<div class="notice-welcome-container"> <div class="text-section"> <div class="logo-section"> <img src="' . esc_url( ASTRA_SITES_URI . 'inc/lib/onboarding/assets/images/logo.svg' ) . '" /> <h3>' . __( 'Starter Templates', 'astra-sites' ) . '</h3> </div> <h1 class="text-heading">' . __( 'Build Your Dream Site in Minutes With AI', 'astra-sites' ) . '</h1> <p>' . __( 'Say goodbye to the days of spending weeks designing and building your website.<br/> You can now create professional-grade websites in minutes.', 'astra-sites' ) . '</p> <div class="button-section"> <a href="' . esc_url( self::get_starter_templates_url() ) . '" class="text-button">' . __( 'Let’s Get Started', 'astra-sites' ) . '</a> <a href="javascript:void(0);" class="scratch-link astra-notice-close">' . __( 'I want to build this website from scratch', 'astra-sites' ) . '</a> </div> </div> <div class="showcase-section"> <img src="' . esc_url( ASTRA_SITES_URI . 'inc/assets/images/templates-showcase.png' ) . '" /> </div> </div>' ), 'display-with-other-notices' => false, ) ); } /** * Enqueue Astra Notices CSS. * * @since 3.1.17 * * @return void */ public static function notice_assets() { $file = 'astra-notices.css'; wp_enqueue_style( 'astra-sites-notices', ASTRA_SITES_URI . 'inc/assets/css/' . $file, array(), ASTRA_SITES_VER ); } /** * Display notice on dashboard if WP_Filesystem() false. * * @return void */ public function check_filesystem_access_notice() { // Check if WP_Filesystem() returns false. if ( ! WP_Filesystem() ) { // Display a notice on the dashboard. echo '<div class="error"><p>' . esc_html__( 'Required WP_Filesystem Permissions to import the templates from Starter Templates are missing.', 'astra-sites' ) . '</p></div>'; } } /** * Remove query parameters from the URL. * * @param String $url URL. * @param String[] $params Query parameters. * * @return string URL. */ public function remove_query_params( $url, $params ) { $parts = wp_parse_url( $url ); $query = array(); if ( isset( $parts['query'] ) ) { $query = wp_parse_args( $parts['query'] ); } foreach ( $params as $param ) { unset( $query[ $param ] ); } $query = http_build_query( $query ); if ( ! empty( $query ) ) { $query = '?' . $query; } if ( ! isset( $parts['host'] ) ) { return $url; } $parts['scheme'] = isset( $parts['scheme'] ) ? $parts['scheme'] : 'https'; $parts['path'] = isset( $parts['path'] ) ? $parts['path'] : '/'; $parts['port'] = isset( $parts['port'] ) ? ':' . $parts['port'] : ''; return $parts['scheme'] . '://' . $parts['host'] . $parts['port'] . $parts['path'] . $query; } /** * Block HTTP requests for Elementor placeholder images during import * * @since 1.0.14 * @param false|array|WP_Error $preempt A preemptive return value of an HTTP request. * @param array $args HTTP request arguments. * @param string $url The request URL. * @return false|array|WP_Error */ public function block_elementor_placeholder_requests( $preempt, $args, $url ) { // Only block during import processes. if ( ! $this->is_import_process_active() ) { return $preempt; } // Check if this is a request for an Elementor placeholder image. if ( $this->is_elementor_placeholder_url( $url ) ) { astra_sites_error_log( 'Blocking Elementor placeholder image request during import: ' . $url ); // Return a WP_Error to prevent the download and import. return new WP_Error( 'blocked_placeholder', 'Elementor placeholder image blocked from import', array( 'url' => $url ) ); } // Allow other requests to proceed normally. return $preempt; } /** * Check if import process is currently active * * @since 1.0.14 * @return bool True if import is active. */ private function is_import_process_active() { // Check if visible import is complete but batch processing is not yet complete. $import_complete = get_option( 'astra_sites_import_complete', 'no' ); $batch_process_started = get_option( 'astra_sites_batch_process_started', 'no' ); $batch_process_complete = get_option( 'astra_sites_batch_process_complete', 'no' ); // Hook should be active when: // 1. Import is complete (visible import finished) // 2. Batch process has started // 3. Batch process is not yet complete. if ( 'yes' === $import_complete && 'yes' === $batch_process_started && 'yes' !== $batch_process_complete ) { // Safety: treat as inactive if batch flags are stale. // No timestamp = flag predates the timestamp feature, guaranteed stale. // Timestamp older than 6 hours = failed/interrupted import. $started_time = (int) get_option( 'astra_sites_batch_process_started_time', 0 ); if ( 0 === $started_time || ( time() - $started_time ) > 6 * HOUR_IN_SECONDS ) { delete_option( 'astra_sites_batch_process_started' ); delete_option( 'astra_sites_batch_process_started_time' ); return false; } return true; } return false; } /** * Check if URL is an Elementor placeholder image * * @since 1.0.14 * @param string $url Image URL to check. * @return bool True if it's a placeholder image. */ private function is_elementor_placeholder_url( $url ) { if ( empty( $url ) ) { return false; } // Check for Elementor placeholder patterns. $placeholder_patterns = array( '/elementor/assets/images/placeholder.png', '/elementor/assets/images/placeholder.jpg', '/elementor/assets/images/placeholder.jpeg', '/elementor/assets/images/placeholder.gif', '/elementor/assets/images/placeholder.svg', ); foreach ( $placeholder_patterns as $pattern ) { if ( strpos( $url, $pattern ) !== false ) { return true; } } // Check for generic placeholder in Elementor context. if ( strpos( $url, 'placeholder' ) !== false && strpos( $url, 'elementor' ) !== false ) { return true; } return false; } /** * Maybe Setup Wizard Showing * * @param bool $showing Whether the wizard is showing. * @since 4.4.28 * * @return bool */ public function maybe_setup_wizard_showing( $showing = false ) { if ( $showing && 'yes' === get_option( 'astra_sites_import_complete', false ) ) { return true; } return $showing; } /** * Get the logo URL for Finish Setup page. * * @since 4.4.31 * * @return string */ public function starter_templates_logo_url() { return ASTRA_SITES_URI . 'inc/lib/onboarding/assets/images/logo.svg'; } /** * Check if sync is in progress. * * @since 4.4.33 * * @return bool */ public static function is_sync_in_progress() { // Early return if sync is explicitly marked in-progress. if ( 'in-process' === get_site_option( 'astra-sites-batch-status', '' ) ) { return true; } // If either batch or manual sync is completed, no sync in progress. if ( 'yes' === get_site_option( 'astra-sites-batch-is-complete', 'no' ) || 'yes' === get_site_option( 'astra-sites-manual-sync-complete', 'no' ) ) { return false; } // If current page is set, assume sync is in progress. return (bool) get_site_option( 'astra-sites-current-page' ); } /** * Check if AI Builder step should be shown. * * @since 4.4.36 * @return bool True if AI Builder step should be shown, false otherwise. */ public static function should_show_ai_builder() { /** * Filter to show/hide AI Builder step. * * @since 4.4.36 * @param bool $show_ai_builder Whether to show the AI Builder step. Default true. * @return bool */ return apply_filters( 'astra_sites_show_ai_builder', true ); } /** * Get custom template data for Custom Templates step. * * @since 4.4.43 * @return array Custom template data. */ public static function get_custom_template_data() { /** * Filter to provide custom template data for Custom Templates step. * * @param array $custom_templates Array of custom template data. * * @since 4.4.43 * @param array $custom_templates Array of custom template data. */ return apply_filters( 'astra_sites_show_custom_templates', array() ); } /** * Determine the appropriate current index (ci) parameter based on page builder flags. * * Mirrors the step-skipping logic used in the site-type/index.js (JavaScript). * * @since 4.4.36 * @return int The calculated ci value for the stepper. */ public static function get_onboarding_page_index() { // Show AI Builder step if enabled. if ( self::should_show_ai_builder() ) { return 0; // Site Type Step. } // Check if builders are disabled. $is_beaver_builder_disabled = get_option( 'st-beaver-builder-flag' ) || ! Intelligent_Starter_Templates_Loader::is_legacy_beaver_builder_enabled(); $is_elementor_disabled = get_option( 'st-elementor-builder-flag' ); // Skip to templates if both builders are also disabled. if ( $is_beaver_builder_disabled && $is_elementor_disabled ) { return 2; // Skip to template list. } // Skip to the page builder selection. return 1; } /** * Get starter templates URL with appropriate current index (ci) parameter * * @since 4.4.36 * @return string The URL with appropriate ci parameter */ public static function get_starter_templates_url() { $base_url = admin_url( 'themes.php?page=starter-templates' ); $ci = self::get_onboarding_page_index(); if ( 0 === $ci ) { return $base_url; } return add_query_arg( 'ci', $ci, $base_url ); } /** * Enqueue admin menu URL updater script. * * @since 4.4.36 * * @param string $hook Current hook name. * @return void */ public function enqueue_menu_url_updater( $hook = '' ) { // Bail if not in admin area. if ( ! is_admin() ) { return; } // Bail if user lacks admin privileges. if ( ! current_user_can( 'manage_options' ) ) { return; } // Bail if in customizer preview mode. if ( is_customize_preview() ) { return; } // Bail if handling AJAX request. if ( wp_doing_ajax() ) { return; } $dynamic_url = self::get_starter_templates_url(); // Bail if ci parameter is not present. if ( strpos( $dynamic_url, 'ci=' ) === false ) { return; } $script = <<<JS // Safely update starter templates menu link after page load. window.addEventListener( 'load', function() { // Locate the starter templates menu item. const menuItem = document.querySelector( '.wp-submenu a[href*="themes.php?page=starter-templates"]' ); // Verify element exists before modifying. if ( menuItem ) { menuItem.href = "$dynamic_url"; } } ); JS; wp_add_inline_script( 'common', $script ); } /** * Check if Spectra Legacy (UAG) plugin is installed. * * @since 4.6.3 * * @return bool */ public static function is_spectra_legacy_installed() { $plugin_file = 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php'; if ( is_plugin_active( $plugin_file ) ) { return true; } if ( ! function_exists( 'get_plugins' ) ) { if ( ! defined( 'ABSPATH' ) ) { return false; } require_once ABSPATH . '/wp-admin/includes/plugin.php'; } $all_plugins = get_plugins(); return isset( $all_plugins[ $plugin_file ] ); } /** * Should display Spectra Blocks version selector * * Display the selector when Spectra Legacy (UAG) is installed, regardless of * whether Spectra Blocks is also installed. Hide the selector when only * Spectra Blocks is installed or when neither plugin is installed. * * @since 4.4.41 * * @return bool */ public static function should_display_spectra_blocks_version_selector() { // Show selector only when spectra legacy is installed. $flag = self::is_spectra_legacy_installed(); /** * Filter to modify the display of Spectra Blocks version selector. * * @param bool $flag Whether to display the version selector. * * @since 4.4.41 */ return apply_filters( 'astra_sites_display_spectra_blocks_version_selector', $flag ); } /** * Get Spectra Blocks Version * * Always returns 'v3'. The version selector (shown when Spectra Legacy is * installed) lets the user switch to v2 at runtime via the store. * * @since 4.4.41 * * @return string 'v3'. */ public static function get_spectra_blocks_version() { /** * Filter the Spectra Blocks version. * * @param string $version The Spectra Blocks version. Default 'v3'. * * @since 4.6.3 */ return apply_filters( 'astra_sites_spectra_blocks_version', 'v3' ); } /** * Get spectra blocks version for API requests. * * @since 4.4.41 * @return string */ public static function get_rest_spectra_blocks_version() { // Get spectra blocks version. if ( self::should_display_spectra_blocks_version_selector() ) { return 'v2,v3'; } return self::get_spectra_blocks_version(); } /** * Enable force sync * * Sets the site option to force sync templates. * * @since 4.4.44 * @return void */ public static function enable_force_sync() { update_site_option( 'astra-sites-force-sync', 'yes' ); } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites::get_instance(); endif; class-astra-sites-error-handler.php 0000644 00000007161 15252526617 0013401 0 ustar 00 <?php /** * Astra Sites * * @since 3.0.23 * @package Astra Sites */ if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Astra_Sites_Error_Handler */ class Astra_Sites_Error_Handler { /** * Instance of Astra_Sites_Error_Handler * * @since 3.0.23 * @var (Object) Astra_Sites_Error_Handler */ private static $instance = null; /** * Instance of Astra_Sites_Error_Handler. * * @since 3.0.23 * * @return object Class object. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor */ public function __construct() { require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-importer-log.php'; if ( true === astra_sites_has_import_started() ) { $this->start_error_handler(); } add_action( 'shutdown', array( $this, 'stop_handler' ) ); } /** * Stop the shutdown handlers. * * @return void */ public function stop_handler() { if ( true === astra_sites_has_import_started() ) { $this->stop_error_handler(); } } /** * Start the error handling. */ public function start_error_handler() { if ( ! interface_exists( 'Throwable' ) ) { // Fatal error handler for PHP < 7. register_shutdown_function( array( $this, 'shutdown_handler' ) ); } // Fatal error handler for PHP >= 7, and uncaught exception handler for all PHP versions. set_exception_handler( array( $this, 'exception_handler' ) ); } /** * Stop and restore the error handlers. */ public function stop_error_handler() { // Restore the error handlers. restore_error_handler(); restore_exception_handler(); } /** * Uncaught exception handler. * * In PHP >= 7 this will receive a Throwable object. * In PHP < 7 it will receive an Exception object. * * @throws Exception Exception that is catched. * @param Throwable|Exception $e The error or exception. */ public function exception_handler( $e ) { if ( is_a( $e, 'Exception' ) ) { $error = 'Uncaught Exception'; } else { $error = 'Uncaught Error'; } Astra_Sites_Importer_Log::add( 'There was an error on website: ' . $error ); Astra_Sites_Importer_Log::add( $e ); if ( wp_doing_ajax() ) { $error_data = array( 'message' => __( 'There was an error on your website.', 'astra-sites' ), ); // Only expose stack trace details when WP_DEBUG is enabled. if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { $error_data['stack'] = array( 'error-message' => sprintf( '%s: %s', $error, $e->getMessage() ), 'file' => $e->getFile(), 'line' => $e->getLine(), 'trace' => $e->getTrace(), ); } wp_send_json_error( $error_data ); } throw $e; } /** * Displays fatal error output for sites running PHP < 7. */ public function shutdown_handler() { $e = error_get_last(); if ( empty( $e ) || ! ( $e['type'] & ST_ERROR_FATALS ) ) { return; } if ( $e['type'] & E_RECOVERABLE_ERROR ) { $error = 'Catchable fatal error'; } else { $error = 'Fatal error'; } Astra_Sites_Importer_Log::add( 'There was an error on website: ' . $error ); Astra_Sites_Importer_Log::add( $e ); if ( wp_doing_ajax() ) { $error_data = array( 'message' => __( 'There was an error on your website.', 'astra-sites' ), ); // Only expose error details when WP_DEBUG is enabled. if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { $error_data['stack'] = array( 'error-message' => $error, 'error' => $e, ); } wp_send_json_error( $error_data ); } } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Error_Handler::get_instance(); class-astra-sites-utils.php 0000644 00000012325 15252526617 0011773 0 ustar 00 <?php /** * Astra Sites Utlis * * @since 1.0.0 * @package Astra Sites */ if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! class_exists( 'Astra_Sites_Utils' ) ) : /** * Astra_Sites_Utils */ class Astra_Sites_Utils { /** * Instance. * * @since 4.4.48 * @var null $instance */ private static $instance; /** * Initiator * * @since 4.4.48 * @return object initialized object of class. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor. * * @since 4.4.48 */ private function __construct() { add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue' ) ); } /** * Enqueue admin scripts. * * @since 1.0.0 * * @param string $hook Current hook name. * @return void */ public function admin_enqueue( $hook = '' ) { global $wp_version; if ( version_compare( $wp_version, '6.3', '>' ) ) { wp_enqueue_script( 'astra-sites-command-palette', ASTRA_SITES_URI . 'inc/assets/js/command-palette.js', array( 'wp-data', 'wp-element', 'wp-commands', 'wp-dom-ready' ), ASTRA_SITES_VER, true ); wp_localize_script( 'astra-sites-command-palette', 'stCommandsPalette', array( 'imageDir' => INTELLIGENT_TEMPLATES_URI . 'assets/images/', 'onboardingUrl' => admin_url( '/themes.php' ) . '?page=starter-templates', 'customCommands' => $this->get_custom_commands(), ) ); } } /** * Get custom commands. * * @since 4.4.48 * * @return array */ public function get_custom_commands() { $common_search_labels = __( 'Starter, Starter Templates, Templates, Themes, Astra, Onboarding, Import, Export, AI builder', 'astra-sites' ); $commands = array( array( 'name' => 'starter-templates', 'label' => __( 'Starter Templates', 'astra-sites' ), 'searchLabel' => $common_search_labels, 'url' => admin_url( '/themes.php' ) . '?page=starter-templates', ), array( 'name' => 'starter-templates-page-builder', 'label' => __( 'Starter Templates: Choose Page Builder', 'astra-sites' ), 'searchLabel' => $common_search_labels . ', ' . __( 'Page Builder', 'astra-sites' ), 'url' => admin_url( '/themes.php' ) . '?page=starter-templates&ci=1', ), array( 'name' => 'starter-templates-gutenberg', 'label' => __( 'Starter Templates: Gutenberg Templates', 'astra-sites' ), 'searchLabel' => $common_search_labels . ' ' . __( 'Block, Block Editor, Spectra, Gutenberg', 'astra-sites' ), 'url' => admin_url( '/themes.php' ) . '?page=starter-templates&builder=gutenberg', ), ); if ( Astra_Sites::should_show_ai_builder() ) { $commands[] = array( 'name' => 'starter-templates-ai-builder', 'label' => __( 'Starter Templates: AI Builder', 'astra-sites' ), 'searchLabel' => $common_search_labels . ', ' . __( 'AI Template', 'astra-sites' ), 'url' => admin_url( '/themes.php' ) . '?page=ai-builder', ); } $is_beaver_builder_disabled = get_option( 'st-beaver-builder-flag' ) || ! Intelligent_Starter_Templates_Loader::is_legacy_beaver_builder_enabled(); $is_elementor_disabled = get_option( 'st-elementor-builder-flag' ); if ( ! $is_beaver_builder_disabled ) { $commands[] = array( 'name' => 'starter-templates-beaver-builder', 'label' => __( 'Starter Templates: Beaver Builder Templates', 'astra-sites' ), 'searchLabel' => $common_search_labels . ', ' . __( 'Beaver Builder', 'astra-sites' ), 'url' => admin_url( '/themes.php' ) . '?page=starter-templates&builder=beaver-builder', ); } if ( ! $is_elementor_disabled ) { $commands[] = array( 'name' => 'starter-templates-elementor', 'label' => __( 'Starter Templates: Elementor Templates', 'astra-sites' ), 'searchLabel' => $common_search_labels . ', ' . __( 'Elementor', 'astra-sites' ), 'url' => admin_url( '/themes.php' ) . '?page=starter-templates&builder=elementor', ); } return $commands; } /** * Third party cache plugin clear cache. * * @since 4.0.0 * @return void */ public static function third_party_cache_plugins_clear_cache() { // Clear LiteSpeed cache. if ( class_exists( '\LiteSpeed\Purge' ) ) { \LiteSpeed\Purge::purge_all(); } // Clear cloudways cache. self::clear_cloudways_cache(); } /** * This function helps to purge all cache in clodways envirnoment. * In presence of Breeze plugin (https://wordpress.org/plugins/breeze/) * * @since 4.0.0 * @return void */ public static function clear_cloudways_cache() { if ( ! class_exists( 'Breeze_Configuration' ) || ! class_exists( 'Breeze_CloudFlare_Helper' ) || ! class_exists( 'Breeze_Admin' ) ) { return; } // clear varnish cache. $admin = new Breeze_Admin(); $admin->breeze_clear_varnish(); // clear static cache. Breeze_Configuration::breeze_clean_cache(); Breeze_CloudFlare_Helper::reset_all_cache(); } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Utils::get_instance(); endif; functions.php 0000644 00000010136 15252526617 0007301 0 ustar 00 <?php /** * Functions * * @since 2.0.0 * @package Astra Sites */ if ( ! function_exists( 'astra_sites_error_log' ) ) : /** * Error Log * * A wrapper function for the error_log() function. * * @since 2.0.0 * * @param mixed $message Error message. * @return void */ function astra_sites_error_log( $message = '' ) { if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) { if ( is_array( $message ) ) { $message = wp_json_encode( $message ); } if ( apply_filters( 'astra_sites_debug_logs', false ) ) { error_log( $message ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- This is for the debug logs while importing. This is conditional and will not be logged in the debug.log file for normal users. } } } endif; if ( ! function_exists( 'astra_sites_get_suggestion_link' ) ) : /** * * Get suggestion link. * * @since 2.6.1 * * @return suggestion link. */ function astra_sites_get_suggestion_link() { $white_label_link = Astra_Sites_White_Label::get_option( 'astra-agency', 'licence' ); if ( empty( $white_label_link ) ) { $white_label_link = 'https://wpastra.com/sites-suggestions/?utm_source=demo-import-panel&utm_campaign=astra-sites&utm_medium=suggestions'; } return apply_filters( 'astra_sites_suggestion_link', $white_label_link ); } endif; if ( ! function_exists( 'astra_sites_is_valid_image' ) ) : /** * Check for the valid image * * @param string $link The Image link. * * @since 2.6.2 * @return boolean */ function astra_sites_is_valid_image( $link = '' ) { return preg_match( '/^((https?:\/\/)|(www\.))([a-z0-9-].?)+(:[0-9]+)?(\/[\w\-\@]+)+\.(jpg|png|gif|jpeg|svg|webp)\/?$/i', $link ); } endif; if ( ! function_exists( 'astra_get_site_data' ) ) : /** * Returns the value of the index for the Site Data * * @param string $index The index value of the data. * * @since 2.6.14 * @return mixed */ function astra_get_site_data( $index = '' ) { $demo_data = Astra_Sites_File_System::get_instance()->get_demo_content(); if ( ! empty( $demo_data ) && isset( $demo_data[ $index ] ) ) { return $demo_data[ $index ]; } return ''; } endif; if ( ! function_exists( 'astra_sites_get_reset_form_data' ) ) : /** * Get all the forms to be reset. * * @since 3.0.3 * @return array */ function astra_sites_get_reset_form_data() { global $wpdb; $form_ids = $wpdb->get_col( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='_astra_sites_imported_wp_forms'" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need this to get all the WP forms. Traditional WP_Query would have been expensive here. return $form_ids; } endif; if ( ! function_exists( 'astra_sites_get_reset_term_data' ) ) : /** * Get all the terms to be reset. * * @since 3.0.3 * @return array */ function astra_sites_get_reset_term_data() { global $wpdb; $term_ids = $wpdb->get_col( "SELECT term_id FROM {$wpdb->termmeta} WHERE meta_key='_astra_sites_imported_term'" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need this to get all the terms and taxonomy. Traditional WP_Query would have been expensive here. return $term_ids; } endif; if ( ! function_exists( 'astra_sites_empty_post_excerpt' ) ) : /** * Remove the post excerpt * * @param int $post_id The post ID. * @since 3.1.0 */ function astra_sites_empty_post_excerpt( $post_id = 0 ) { if ( ! $post_id ) { return; } wp_update_post( array( 'ID' => $post_id, 'post_excerpt' => '', ) ); } endif; if ( ! function_exists( 'astra_sites_sanitize_recursive' ) ) : /** * Recursively sanitize an array in single dimension or string using sanitize_text_field. * * @param mixed $data The data to sanitize. Can be a string or an array. * @since 4.4.21 * @return mixed The sanitized data. */ function astra_sites_sanitize_recursive( $data ) { if ( is_array( $data ) ) { return array_map( 'astra_sites_sanitize_recursive', $data ); } return sanitize_text_field( $data ); } endif; class-astra-sites-elementor-pages.php 0000644 00000006253 15252526617 0013725 0 ustar 00 <?php /** * Elementor Importer * * @package Astra Sites */ namespace Elementor\TemplateLibrary; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } // If plugin - 'Elementor' not exist then return. if ( ! class_exists( '\Elementor\Plugin' ) ) { return; } use Elementor\Core\Base\Document; use Elementor\DB; use Elementor\Core\Settings\Page\Manager as PageSettingsManager; use Elementor\Core\Settings\Manager as SettingsManager; use Elementor\Core\Settings\Page\Model; use Elementor\Editor; use Elementor\Plugin; use Elementor\Settings; use Elementor\Utils; /** * Elementor template library local source. * * Elementor template library local source handler class is responsible for * handling local Elementor templates saved by the user locally on his site. * * @since 2.0.0 Added compatibility for Elemetnor v2.5.0 */ class Astra_Sites_Elementor_Pages extends Source_Local { /** * Update post meta. * * @since 2.0.0 * @param integer $post_id Post ID. * @param array $data Elementor Data. * @return array $data Elementor Imported Data. */ public function import( $post_id = 0, $data = array() ) { if ( ! empty( $post_id ) && ! empty( $data ) ) { \Astra_Sites_Importer_Log::add( 'Starting Elementor page import for post ID: ' . $post_id ); $data = wp_json_encode( $data ); // Update WP form IDs. $ids_mapping = get_option( 'astra_sites_wpforms_ids_mapping', array() ); if ( $ids_mapping ) { \Astra_Sites_Importer_Log::add( 'Updating WPForms IDs in Elementor page - Total mappings: ' . count( $ids_mapping ) ); foreach ( $ids_mapping as $old_id => $new_id ) { $data = str_replace( '[wpforms id=\"' . $old_id, '[wpforms id=\"' . $new_id, $data ); $data = str_replace( '"select_form":"' . $old_id, '"select_form":"' . $new_id, $data ); } } $data = json_decode( $data, true ); // Import the data. $data = $this->process_export_import_content( $data, 'on_import' ); // Replace the site urls. $demo_data = \Astra_Sites_File_System::get_instance()->get_demo_content(); if ( isset( $demo_data['astra-site-url'] ) ) { $site_url = get_site_url(); $site_url = str_replace( '/', '\/', $site_url ); $demo_site_url = 'https:' . $demo_data['astra-site-url']; $demo_site_url = str_replace( '/', '\/', $demo_site_url ); \Astra_Sites_Importer_Log::add( 'Replacing template demo URLs with site URLs in Elementor data' ); if ( ! is_array( $data ) ) { $data = str_replace( $demo_site_url, $site_url, $data ); } else { $data = wp_json_encode( $data ); if ( ! empty( $data ) ) { $data = str_replace( $demo_site_url, $site_url, $data ); $data = json_decode( $data, true ); } } } // Update processed meta. update_metadata( 'post', $post_id, '_elementor_data', $data ); // !important, Clear the cache after images import. Plugin::$instance->posts_css_manager->clear_cache(); \Astra_Sites_Importer_Log::add( 'Elementor page imported successfully for post ID: ' . $post_id, 'success' ); return $data; } \Astra_Sites_Importer_Log::add( 'Elementor page import skipped - Empty post ID or data', 'warning' ); return array(); } } class-astra-sites-wp-cli.php 0000644 00000121331 15252526617 0012024 0 ustar 00 <?php /** * Astra Sites WP CLI * * 1. Run `wp astra-sites list` List of all astra sites. * 2. Run `wp astra-sites import <id>` Import site. * * @package Astra Sites * @since 1.4.0 */ use STImporter\Importer\WXR_Importer\ST_WXR_Importer; use STImporter\Importer\Batch\ST_Batch_Processing; use AiBuilder\Inc\Traits\Helper; // Include theme functions. if ( ! function_exists( 'switch_theme' ) ) { require_once ABSPATH . 'wp-admin/includes/theme.php'; } if ( class_exists( 'WP_CLI_Command' ) && ! class_exists( 'Astra_Sites_WP_CLI' ) ) : /** * WP-Cli commands to manage Astra Starter Sites. * * @since 1.4.0 */ class Astra_Sites_WP_CLI extends WP_CLI_Command { /** * Site Data * * @var array */ protected $current_site_data; /** * Process Batch * * ## EXAMPLES * * $ wp astra-sites batch * Processing Site: http://example.com/ * Batch Process Started.. * .. * * @since 2.1.0 * @param array $args Arguments. * @param array $assoc_args Associated Arguments. */ public function batch( $args, $assoc_args ) { WP_CLI::line( 'Processing Site: ' . site_url() ); ST_Batch_Processing::get_instance()->start_process(); } /** * Generates the list of all Astra Sites. * * ## OPTIONS * * [--per-page=<number>] * : No of sites to show in the list. Default its showing 10 sites. * * [--search=<text>] * : Show the sites from particular search term. * * [--category=<text>] * : Show the site from the specific category. * * [--page-builder=<text>] * : List the sites from the particular page builder. * * [--type=<text>] * : List the sites from the particular site type. * * ## EXAMPLES * * # List all the sites. * $ wp astra-sites list * +-------+-------------------+-----------------------------------------+---------+----------------+--------------+ * | id | title | url | type | categories | page-builder | * +-------+-------------------+-----------------------------------------+---------+----------------+--------------+ * | 34184 | Nutritionist | //websitedemos.net/nutritionist-01 | free | Business, Free | Elementor | * | 34055 | Law Firm | //websitedemos.net/law-firm-03 | premium | Business | Elementor | * +-------+-------------------+-----------------------------------------+---------+----------------+--------------+ * * @since 1.4.0 * @param array $args Arguments. * @param array $assoc_args Associated Arguments. * * @alias list */ public function list_sites( $args, $assoc_args ) { $per_page = isset( $assoc_args['per-page'] ) ? $assoc_args['per-page'] : 10; $search = isset( $assoc_args['search'] ) ? $assoc_args['search'] : ''; $rest_args = array( '_fields' => 'id,title,slug,astra-sites-site-category,astra-site-page-builder,astra-site-type,astra-site-url', 'per_page' => $per_page, ); if ( ! empty( $search ) ) { $rest_args['search'] = $search; } $list = (array) $this->get_sites( 'astra-sites', $rest_args, true, $assoc_args ); // Modify the output. foreach ( $list as $key => $item ) { $list[ $key ]['categories'] = implode( ', ', $list[ $key ]['categories'] ); $list[ $key ]['page-builder'] = implode( ', ', $list[ $key ]['page_builders'] ); } if ( ! empty( $list ) ) { $display_fields = array( 'id', 'title', 'url', 'type', 'categories', 'page-builder', ); $formatter = $this->get_formatter( $assoc_args, $display_fields ); $formatter->display_items( $list ); } else { WP_CLI::error( __( 'No sites found! Try another query.', 'astra-sites' ) ); } } /** * Import the site by site ID. * * ## OPTIONS * * <id> * : Site id of the import site. * * [--reset] * : Reset the recently imported site data. Including post, pages, customizer settings, widgets etc. * * [--yes] * : Forcefully import the site without asking any prompt message. * * * ## EXAMPLES * * # Import demo site. * $ wp astra-sites import 34184 --reset --yes --license_key={{YOUR_KEY}} * Activating Plugins.. * Reseting Posts.. * .. * * @since 1.4.0 * @param array $args Arguments. * @param array $assoc_args Associated Arguments. */ public function import( $args, $assoc_args ) { // Force import. $yes = isset( $assoc_args['yes'] ) ? true : false; if ( ! $yes ) { WP_CLI::confirm( __( 'Are you sure you want to import the site?', 'astra-sites' ) ); } // Valid site ID? $id = isset( $args[0] ) ? absint( $args[0] ) : 0; if ( ! $id ) { WP_CLI::error( __( 'Invalid Site ID,', 'astra-sites' ) ); } $reset = isset( $assoc_args['reset'] ) ? true : false; $site_url = get_site_url(); $demo_data = $this->get_site_data( $id ); // Invalid Site ID. if ( is_wp_error( $demo_data ) ) { /** * Handle WP_Error response when demo data fetch fails. * * @var WP_Error $demo_data Error object containing failure details. */ /* Translators: %s is the error message. */ WP_CLI::error( sprintf( __( 'Site Import failed due to error: %s', 'astra-sites' ), $demo_data->get_error_message() ) ); } // License Status. $license_status = false; if ( is_callable( 'BSF_License_Manager::bsf_is_active_license' ) ) { $license_status = BSF_License_Manager::bsf_is_active_license( 'astra-pro-sites' ); } if ( 'free' !== $demo_data['site-type'] && 'upgrade' === $demo_data['license-status'] && ! $license_status ) { if ( ! defined( 'ASTRA_PRO_SITES_NAME' ) ) { WP_CLI::line( __( 'This is Premium site. Please activate the "Starter Templates" license!', 'astra-sites' ) ); WP_CLI::line( __( 'Use `wp plugin deactivate astra-sites` and then `wp plugin activate astra-pro-sites`', 'astra-sites' ) ); } /* translators: %s is the activate plugin license link. */ WP_CLI::error( __( 'Use CLI command `wp brainstormforce license activate astra-pro-sites {YOUR_LICENSE_KEY}`', 'astra-sites' ) ); } /** * Install & Activate Astra Theme. */ $this->install_and_activate_astra_theme(); /** * Check File System permissions. */ Helper::filesystem_permission(); /** * Install & Activate Required Plugins. */ if ( isset( $demo_data['required-plugins'] ) ) { $plugins = (array) $demo_data['required-plugins']; if ( ! empty( $plugins ) ) { $plugin_status = Helper::required_plugins( $plugins, $demo_data['astra-site-options-data'], $demo_data['astra-enabled-extensions'] ); // Handle plugin dependencies and install/activate in correct order. $this->handle_plugin_dependencies( $plugin_status, $demo_data ); } } /** * Backup Customizer Settings. */ Helper::backup_settings(); /** * Reset Site Data. */ if ( $reset ) { WP_CLI::runcommand( 'astra-sites reset --yes' ); } /** * Import Flows & Steps for CartFlows. */ if ( isset( $demo_data['astra-site-cartflows-path'] ) && ! empty( $demo_data['astra-site-cartflows-path'] ) ) { // Check if CartFlows plugin is in required plugins list before importing. if ( $this->is_plugin_required( $demo_data, 'cartflows' ) ) { Astra_Sites_Importer::get_instance()->import_cartflows( $demo_data['astra-site-cartflows-path'] ); } else { WP_CLI::line( __( 'Skipping CartFlows import - plugin not in required list.', 'astra-sites' ) ); } } /** * Import Cart Abandonment Recovery data. */ if ( isset( $demo_data['astra-site-cart-abandonment-recovery-path'] ) && ! empty( $demo_data['astra-site-cart-abandonment-recovery-path'] ) ) { // Check if Cart Abandonment Recovery plugin is in required plugins list before importing. if ( $this->is_plugin_required( $demo_data, 'cart-abandonment-recovery' ) ) { Astra_Sites_Importer::get_instance()->import_cart_abandonment_recovery( $demo_data['astra-site-cart-abandonment-recovery-path'] ); } else { WP_CLI::line( __( 'Skipping Cart Abandonment Recovery import - plugin not in required list.', 'astra-sites' ) ); } } /** * Import WPForms. */ if ( isset( $demo_data['astra-site-wpforms-path'] ) && ! empty( $demo_data['astra-site-wpforms-path'] ) ) { // Check if WPForms plugin is in required plugins list before importing. if ( $this->is_plugin_required( $demo_data, 'wpforms' ) ) { Astra_Sites_Importer::get_instance()->import_wpforms( $demo_data['astra-site-wpforms-path'] ); } else { WP_CLI::line( __( 'Skipping WPForms import - plugin not in required list.', 'astra-sites' ) ); } } /** * Import LatePoint. */ if ( isset( $demo_data['astra-site-latepoint-path'] ) && ! empty( $demo_data['astra-site-latepoint-path'] ) ) { // Check if LatePoint plugin is in required plugins list before importing. if ( $this->is_plugin_required( $demo_data, 'latepoint' ) ) { Astra_Sites_Importer::get_instance()->import_latepoint( $demo_data['astra-site-latepoint-path'] ); } else { WP_CLI::line( __( 'Skipping LatePoint import - plugin not in required list.', 'astra-sites' ) ); } } /** * Import Customizer Settings. */ WP_CLI::runcommand( 'astra-sites import_customizer_settings ' . $id ); /** * Import Content from XML/WXR. */ if ( isset( $demo_data['astra-site-wxr-path'] ) && ! empty( $demo_data['astra-site-wxr-path'] ) ) { WP_CLI::runcommand( 'astra-sites import_wxr ' . $demo_data['astra-site-wxr-path'] ); } /** * Import SureCart Settings. */ if ( isset( $demo_data['astra-site-surecart-settings'] ) && ! empty( $demo_data['astra-site-surecart-settings']['id'] ) ) { // Check if LatePoint plugin is in required plugins list before importing. if ( ! $this->is_plugin_required( $demo_data, 'latepoint' ) ) { WP_CLI::line( __( 'Skipping LatePoint import - plugin not in required list.', 'astra-sites' ) ); } if ( ! class_exists( 'STImporter\Importer\ST_Importer' ) ) { WP_CLI::line( __( 'SureCart import failed: ST_Importer class not found. Please ensure the importer is properly loaded.', 'astra-sites' ) ); return; } $result = \STImporter\Importer\ST_Importer::import_surecart_settings( $demo_data['astra-site-surecart-settings']['id'] ); if ( isset( $result['status'] ) && ! $result['status'] ) { // translators: %s: Error message. WP_CLI::line( sprintf( __( 'SureCart import failed: %s', 'astra-sites' ), isset( $result['error'] ) ? $result['error'] : __( 'Unknown error', 'astra-sites' ) ) ); return; } WP_CLI::line( __( 'SureCart Settings imported.', 'astra-sites' ) ); } /** * Import Site Options. */ if ( isset( $demo_data['astra-site-options-data'] ) && ! empty( $demo_data['astra-site-options-data'] ) ) { WP_CLI::line( __( 'Importing Site Options..', 'astra-sites' ) ); Helper::import_options( $demo_data['astra-site-options-data'] ); } /** * Import Widgets. */ if ( isset( $demo_data['astra-site-widgets-data'] ) && ! empty( $demo_data['astra-site-widgets-data'] ) ) { WP_CLI::line( __( 'Importing Widgets..', 'astra-sites' ) ); if ( file_exists( ABSPATH . 'wp-content/themes/astra/functions.php' ) ) { require_once ABSPATH . 'wp-content/themes/astra/functions.php'; } // Initialize Astra Builder Widget Controller. try { if ( class_exists( 'Astra_Builder_Widget_Controller' ) && class_exists( 'Astra_Builder_Helper' ) ) { $widget_controller = \Astra_Builder_Widget_Controller::get_instance(); if ( method_exists( $widget_controller, 'widget_init' ) ) { // Check if header/footer builder is active. $is_builder_active = property_exists( 'Astra_Builder_Helper', 'is_header_footer_builder_active' ) ? Astra_Builder_Helper::$is_header_footer_builder_active : true; if ( false !== $is_builder_active ) { // Use fallback values to reduce dependency on Astra_Builder_Helper. $num_of_footer_widgets = property_exists( 'Astra_Builder_Helper', 'num_of_footer_widgets' ) ? Astra_Builder_Helper::$num_of_footer_widgets : 4; $num_of_header_widgets = property_exists( 'Astra_Builder_Helper', 'num_of_header_widgets' ) ? Astra_Builder_Helper::$num_of_header_widgets : 2; $pro_exist = defined( 'ASTRA_EXT_VER' ); $component_limit = $pro_exist && property_exists( 'Astra_Builder_Helper', 'component_limit' ) ? Astra_Builder_Helper::$component_limit : max( $num_of_footer_widgets, $num_of_header_widgets ); for ( $index = 1; $index <= ( $pro_exist ? $component_limit : $num_of_footer_widgets ); $index++ ) { $widget_controller->register_sidebar( $index, 'footer' ); } for ( $index = 1; $index <= ( $pro_exist ? $component_limit : $num_of_header_widgets ); $index++ ) { $widget_controller->register_sidebar( $index, 'header' ); } } } } } catch ( \Exception $e ) { // translators: %s is the error. WP_CLI::line( sprintf( __( 'Warning: Failed to initialize Astra Builder Widget Controller. Error: %s', 'astra-sites' ), $e->getMessage() ) ); } catch ( \Error $e ) { // translators: %s is the error. WP_CLI::line( sprintf( __( 'Warning: Fatal error encountered while initializing Astra Builder Widget Controller. Error: %s', 'astra-sites' ), $e->getMessage() ) ); } // Ensure the widgets_init action is fired. if ( function_exists( 'wp_widgets_init' ) ) { wp_widgets_init(); } Helper::import_widgets( $demo_data['astra-site-widgets-data'] ); } /** * Import End. */ WP_CLI::runcommand( 'astra-sites import_end' ); /* translators: %s is the site URL. */ WP_CLI::line( sprintf( __( "Site Imported Successfully!\nVisit: %s", 'astra-sites' ), $site_url ) ); } /** * Import End * * @since 1.4.3 * @return void */ public function import_end() { Helper::import_end(); } /** * Import form XML. * * ## OPTIONS * * <url> * : XML/WXR file URL. * * ## EXAMPLES * * $ wp astra-sites import_wxr <url> * * @since 1.4.3 * @param array $args Arguments. * @param array $assoc_args Associated Arguments. * @return void. */ public function import_wxr( $args = array(), $assoc_args = array() ) { // Valid site ID? $url = isset( $args[0] ) ? esc_url_raw( $args[0] ) : ''; if ( empty( $url ) ) { WP_CLI::error( esc_html__( 'Invalid XML URL.', 'astra-sites' ) ); } // Download XML file. /* translators: %s is the XML file URL. */ WP_CLI::line( sprintf( esc_html__( 'Downloading %s', 'astra-sites' ), $url ) ); $xml_path = ST_WXR_Importer::download_file( $url ); if ( $xml_path['success'] && isset( $xml_path['data']['file'] ) ) { WP_CLI::line( esc_html__( 'Importing WXR..', 'astra-sites' ) ); ST_WXR_Importer::get_instance()->sse_import( $xml_path['data']['file'] ); } else { /* translators: %s is error message. */ WP_CLI::line( printf( esc_html__( 'WXR file Download Failed. Error %s', 'astra-sites' ), esc_html( $xml_path['data'] ) ) ); } } /** * Reset * * Delete all pages, post, custom post type, customizer settings and site options. * * ## OPTIONS * * [--yes] * : Reset previously imported site data without asking the prompt message. * * ## EXAMPLES * * $ wp astra-sites reset * * @since 1.4.0 * @param array $args Arguments. * @param array $assoc_args Associated Arguments. * @return void. */ public function reset( $args = array(), $assoc_args = array() ) { $yes = isset( $assoc_args['yes'] ) ? true : false; if ( ! $yes ) { WP_CLI::confirm( __( 'Are you sure you want to delete imported site data?', 'astra-sites' ) ); } // Get tracked data. $reset_data = Astra_Sites::get_instance()->get_reset_data(); // Delete tracked posts. if ( isset( $reset_data['reset_posts'] ) && ! empty( $reset_data['reset_posts'] ) ) { WP_CLI::line( __( 'Reseting Posts..', 'astra-sites' ) ); foreach ( $reset_data['reset_posts'] as $key => $post_id ) { Astra_Sites_Importer::get_instance()->delete_imported_posts( $post_id ); } } // Delete tracked terms. if ( isset( $reset_data['reset_terms'] ) && ! empty( $reset_data['reset_terms'] ) ) { WP_CLI::line( __( 'Reseting Terms..', 'astra-sites' ) ); foreach ( $reset_data['reset_terms'] as $key => $post_id ) { Astra_Sites_Importer::get_instance()->delete_imported_terms( $post_id ); } } // Delete tracked WP forms. if ( isset( $reset_data['reset_wp_forms'] ) && ! empty( $reset_data['reset_wp_forms'] ) ) { WP_CLI::line( __( 'Resting WP Forms...', 'astra-sites' ) ); foreach ( $reset_data['reset_wp_forms'] as $key => $post_id ) { Astra_Sites_Importer::get_instance()->delete_imported_terms( $post_id ); } } // Delete Customizer Data. Helper::reset_customizer_data(); // Delete Site Options. Helper::reset_site_options(); // Delete Widgets Data. Helper::reset_widgets_data(); } /** * Import Customizer Settings * * ## OPTIONS * * <id> * : Site ID. * * ## EXAMPLES * * $ wp astra-sites import_customizer_settings <id> * * @since 1.4.0 * * @param array $args Arguments. * @param array $assoc_args Associated Arguments. * @return void */ public function import_customizer_settings( $args, $assoc_args ) { // Valid site ID? $id = isset( $args[0] ) ? absint( $args[0] ) : 0; if ( ! $id ) { WP_CLI::error( __( 'Invalid Site ID,', 'astra-sites' ) ); } $demo_data = $this->get_site_data( $id ); WP_CLI::line( __( 'Importing customizer settings..', 'astra-sites' ) ); Helper::import_customizer_settings( $demo_data['astra-site-customizer-data'] ); } /** * Page Builders * * ### OPTIONS * * [<list>] * : List all page builders. * * OR * * [<set>] * : Set the current page builder with given page builder slug. * * [<slug>] * : Page builder slug. * * ### EXAMPLES * * # List all the page builders. * λ wp astra-sites page_builder list * +----------------+----------------+ * | slug | name | * +----------------+----------------+ * | gutenberg | Gutenberg | * | elementor | Elementor | * | beaver-builder | Beaver Builder | * | brizy | Brizy | * +----------------+----------------+ * * # Set `Elementor` as default page builder. * λ wp astra-sites page_builder set elementor * "Elementor" is set as default page builder. * * # Set `Beaver Builder` as default page builder. * λ wp astra-sites page_builder set beaver-builder * "Beaver Builder" is set as default page builder. * * @since 1.4.0 * @param array $args Arguments. * @param array $assoc_args Associated Arguments. */ public function page_builder( $args, $assoc_args ) { $action = isset( $args[0] ) ? $args[0] : ''; if ( empty( $action ) ) { WP_CLI::error( __( 'Please add valid parameter.', 'astra-sites' ) ); } $page_builders = Astra_Sites_Page::get_instance()->get_page_builders(); if ( 'list' === $action ) { $display_fields = array( 'slug', 'name', ); $formatter = $this->get_formatter( $assoc_args, $display_fields ); $formatter->display_items( $page_builders ); $default_page_builder = isset( $page_builders[ Astra_Sites_Page::get_instance()->get_setting( 'page_builder' ) ] ) ? $page_builders[ Astra_Sites_Page::get_instance()->get_setting( 'page_builder' ) ]['name'] : ''; if ( ! empty( $default_page_builder ) ) { /* translators: %s is the current page builder name. */ WP_CLI::line( sprintf( __( 'Default page builder is "%s".', 'astra-sites' ), $default_page_builder ) ); } } elseif ( 'set' === $action ) { $page_builder_slugs = array_keys( $page_builders ); $page_builder_slug = isset( $args[1] ) ? $args[1] : ''; if ( in_array( $page_builder_slug, $page_builder_slugs, true ) ) { Astra_Sites_Page::get_instance()->save_page_builder_on_submit( $page_builder_slug ); /* translators: %s is the page builder name. */ WP_CLI::line( sprintf( __( '"%s" is set as default page builder.', 'astra-sites' ), $page_builders[ $page_builder_slug ]['name'] ) ); } else { WP_CLI::error( __( "Invalid page builder slug. \nCheck all page builder slugs with command `wp astra-sites page_builder list`", 'astra-sites' ) ); } } else { WP_CLI::error( __( "Invalid parameter! \nPlease use `list` or `set` parameter.", 'astra-sites' ) ); } } /** * Get Formatter * * @since 1.4.0 * @param array $assoc_args Associate arguments. * @param string $fields Fields. * @param string $prefix Prefix. * @return object Class object. */ protected function get_formatter( &$assoc_args, $fields = '', $prefix = '' ) { return new \WP_CLI\Formatter( $assoc_args, $fields, $prefix ); } /** * Get Site Data by Site ID * * @since 1.4.0 * * @param int $id Site ID. * @return array */ private function get_site_data( $id ) { if ( empty( $this->current_site_data ) ) { // @todo Use Astra_Sites::get_instance()->api_request() instead of below function. $this->current_site_data = Astra_Sites_Importer::get_instance()->get_single_demo( $id ); Astra_Sites_File_System::get_instance()->update_demo_data( $this->current_site_data ); } return $this->current_site_data; } /** * Get Sites * * @since 1.4.0 * * @param string $post_slug Post slug. * @param array $args Post query arguments. * @param boolean $force Force import. * @param array $assoc_args Associate arguments. * @return array */ private function get_sites( $post_slug = '', $args = array(), $force = false, $assoc_args = array() ) { // Add page builders. $page_builder = isset( $assoc_args['page-builder'] ) ? $assoc_args['page-builder'] : Astra_Sites_Page::get_instance()->get_setting( 'page_builder' ); $response = $this->get_term_ids( 'astra-site-page-builder', $page_builder, $args ); $args = $response['args']; $page_builders = $response['terms']; if ( empty( $page_builders['data'] ) ) { WP_CLI::error( __( 'This page builder plugin is not installed. Please try a different page builder.', 'astra-sites' ) ); } // Add type. $type = isset( $assoc_args['type'] ) ? $assoc_args['type'] : ''; $response = $this->get_term_ids( 'astra-sites-type', $type, $args ); $args = $response['args']; $types = $response['terms']; if ( empty( $types['data'] ) ) { WP_CLI::error( __( 'This site type does not exist. Please try a different site type.', 'astra-sites' ) ); } // Add categories. $category = isset( $assoc_args['category'] ) ? $assoc_args['category'] : ''; $response = $this->get_term_ids( 'astra-sites-site-category', $category, $args ); $args = $response['args']; $categories = $response['terms']; if ( empty( $categories['data'] ) ) { WP_CLI::error( __( 'This site category does not exist. Please try a different site category.', 'astra-sites' ) ); } // Site list. $sites = (array) $this->get_posts( 'astra-sites', $args, $force ); $list = array(); if ( $sites['success'] ) { foreach ( $sites['data'] as $key => $site ) { $single_site = array( 'id' => $site['id'], 'slug' => $site['slug'], 'title' => $site['title']['rendered'], 'url' => $site['astra-site-url'], 'type' => ( 'premium' === $site['astra-site-type'] ) ? 'Premium' : ucwords( $site['astra-site-type'] ), 'categories' => array(), 'page_builders' => array(), ); if ( isset( $site['astra-sites-site-category'] ) && ! empty( $categories['data'] ) ) { foreach ( $site['astra-sites-site-category'] as $category_key => $category_id ) { if ( isset( $categories['data'][ $category_id ] ) ) { $single_site['categories'][ $category_id ] = $categories['data'][ $category_id ]; } } } if ( isset( $site['astra-site-page-builder'] ) && ! empty( $page_builders['data'] ) ) { foreach ( $site['astra-site-page-builder'] as $page_builder_key => $page_builder_id ) { if ( isset( $page_builders['data'][ $page_builder_id ] ) ) { $single_site['page_builders'][ $page_builder_id ] = $page_builders['data'][ $page_builder_id ]; } } } $list[] = $single_site; } } return $list; } /** * Get Term IDs * * @since 1.4.0 * * @param string $term_slug Term slug. * @param string $search_term Search term. * @param array $args Term query arguments. * @return array Term response. */ private function get_term_ids( $term_slug = '', $search_term = '', $args = array() ) { $term_args = array(); if ( ! empty( $search_term ) ) { $term_args = array( 'search' => $search_term, ); } $term_response = (array) $this->get_terms( $term_slug, $term_args, true ); if ( ! empty( $search_term ) ) { if ( ! empty( $term_response ) && is_array( $term_response['data'] ) ) { $args[ $term_slug ] = implode( ',', array_keys( $term_response['data'] ) ); } } return array( 'args' => $args, 'terms' => $term_response, ); } /** * Get Terms * * @since 1.0.0 * * @param array $term_slug Term Slug. * @param array $args For selecting the demos (Search terms, pagination etc). * @param string $force Force import. * @return $array Term response. */ private function get_terms( $term_slug = '', $args = array(), $force = false ) { $defaults = array( '_fields' => 'id,name,slug,count', ); $args = wp_parse_args( (array) $args, $defaults ); $success = false; $terms_data = get_transient( 'astra-sites-term-' . $term_slug ); if ( empty( $terms_data ) || $force ) { $url = add_query_arg( $args, Astra_Sites::get_instance()->get_api_url() . $term_slug ); $api_args = array( 'timeout' => 60, ); $response = wp_safe_remote_get( $url, $api_args ); if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) { $request_term_data = json_decode( wp_remote_retrieve_body( $response ), true ); if ( ! isset( $request_term_data['code'] ) ) { $success = true; $new_terms_data = array(); foreach ( $request_term_data as $key => $request_term ) { $new_terms_data[ $request_term['id'] ] = $request_term['name']; } if ( set_transient( 'astra-sites-term-' . $term_slug, $new_terms_data, WEEK_IN_SECONDS ) ) { return array( 'success' => $success, 'data' => $new_terms_data, ); } } } } return array( 'success' => $success, 'data' => $terms_data, ); } /** * Get Posts * * @since 1.4.0 * * @param string $post_slug Post slug. * @param array $args Post query arguments. * @param boolean $force Force import. * @return array */ private function get_posts( $post_slug = '', $args = array(), $force = false ) { $args = wp_parse_args( (array) $args, array() ); $all_posts = get_transient( 'astra-sites-post-' . $post_slug ); if ( empty( $all_posts ) || $force ) { $url = add_query_arg( $args, Astra_Sites::get_instance()->get_api_url() . $post_slug ); $api_args = array( 'timeout' => 60, ); $success = false; $response = wp_safe_remote_get( $url, $api_args ); if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) { $all_posts = json_decode( wp_remote_retrieve_body( $response ), true ); if ( ! isset( $all_posts['code'] ) ) { $success = true; set_transient( 'astra-sites-post-' . $post_slug, $all_posts, WEEK_IN_SECONDS ); } } } else { $success = true; } return array( 'success' => $success, 'data' => $all_posts, ); } /** * Sync Library. * * Sync the library and create the .json files. * * Use: `wp astra-sites sync` * * @since 2.0.0 * @param array $args Arguments. * @param array $assoc_args Associated Arguments. * @return void. */ public function sync( $args = array(), $assoc_args = array() ) { Astra_Sites_Batch_Processing::get_instance()->process_batch(); } /** * Init. */ public static function init() { add_filter( 'wp_check_filetype_and_ext', array( 'Astra_Sites_WP_CLI', 'real_mime_types' ), 10, 5 ); } /** * Different MIME type of different PHP version * * Filters the "real" file type of the given file. * * @since 1.2.9 * * @param array $defaults File data array containing 'ext', 'type', and * 'proper_filename' keys. * @param string $file Full path to the file. * @param string $filename The name of the file (may differ from $file due to * $file being in a tmp directory). * @param array<string, string> $mimes Key is the file extension with value as the mime type. * @param string $real_mime Real MIME type of the uploaded file. */ public static function real_mime_types( $defaults, $file, $filename, $mimes, $real_mime ) { return ST_WXR_Importer::get_instance()->real_mime_types_5_1_0( $defaults, $file, $filename, $mimes, $real_mime ); } /** * Install and Activate Astra Theme * * @since 4.4.43 * @return void */ private function install_and_activate_astra_theme() { // Check if Astra theme is installed. $astra_theme = wp_get_theme( 'astra' ); if ( ! $astra_theme->exists() ) { WP_CLI::line( __( 'Installing Astra Theme..', 'astra-sites' ) ); // Install Astra theme. $result = WP_CLI::runcommand( 'theme install astra', array( 'return' => 'all' ) ); if ( 0 !== $result->return_code ) { WP_CLI::error( __( 'Failed to install Astra theme.', 'astra-sites' ) ); } WP_CLI::line( __( 'Astra Theme installed successfully.', 'astra-sites' ) ); } // Activate Astra theme. WP_CLI::line( __( 'Activating Astra Theme..', 'astra-sites' ) ); // Use WordPress function to activate theme. switch_theme( 'astra' ); WP_CLI::line( __( 'Astra Theme activated successfully.', 'astra-sites' ) ); } /** * Handle plugin dependencies by installing and activating plugins using a deferred list approach. * * @since 4.4.43 * @param array $plugin_status Plugin status array. * @param array $demo_data Demo data. * @return void */ private function handle_plugin_dependencies( $plugin_status, $demo_data ) { // Get all plugins that need to be processed. $all_plugins = array(); // Combine all plugin types into a single array. if ( ! empty( $plugin_status['required_plugins']['notinstalled'] ) ) { foreach ( $plugin_status['required_plugins']['notinstalled'] as $plugin ) { $all_plugins[ $plugin['slug'] ] = array( 'slug' => $plugin['slug'], 'init' => isset( $plugin['init'] ) ? $plugin['init'] : $plugin['slug'] . '/' . $plugin['slug'] . '.php', 'name' => isset( $plugin['name'] ) ? $plugin['name'] : $plugin['slug'], 'status' => 'notinstalled', ); } } if ( ! empty( $plugin_status['required_plugins']['inactive'] ) ) { foreach ( $plugin_status['required_plugins']['inactive'] as $plugin ) { $all_plugins[ $plugin['slug'] ] = array( 'slug' => $plugin['slug'], 'init' => isset( $plugin['init'] ) ? $plugin['init'] : $plugin['slug'] . '/' . $plugin['slug'] . '.php', 'name' => isset( $plugin['name'] ) ? $plugin['name'] : $plugin['slug'], 'status' => 'inactive', ); } } if ( ! empty( $plugin_status['required_plugins']['active'] ) ) { foreach ( $plugin_status['required_plugins']['active'] as $plugin ) { $all_plugins[ $plugin['slug'] ] = array( 'slug' => $plugin['slug'], 'init' => isset( $plugin['init'] ) ? $plugin['init'] : $plugin['slug'] . '/' . $plugin['slug'] . '.php', 'name' => isset( $plugin['name'] ) ? $plugin['name'] : $plugin['slug'], 'status' => 'active', ); } } // Install all plugins first. WP_CLI::line( __( 'Installing Plugins..', 'astra-sites' ) ); $plugins_to_activate = array(); // 👉 Sort priority before installation. $priority_order = array( 'woocommerce', 'elementor', 'spectra-blocks', 'ultimate-addons-for-gutenberg' ); uksort( $all_plugins, function ( $a, $b ) use ( $priority_order ) { $a_priority = array_search( $a, $priority_order ); $b_priority = array_search( $b, $priority_order ); if ( false === $a_priority ) { $a_priority = PHP_INT_MAX; } if ( false === $b_priority ) { $b_priority = PHP_INT_MAX; } return $a_priority - $b_priority; } ); foreach ( $all_plugins as $plugin ) { if ( 'notinstalled' === $plugin['status'] ) { /* translators: %s is the plugin name. */ WP_CLI::line( sprintf( __( 'Installing plugin: %s', 'astra-sites' ), $plugin['name'] ) ); // Install plugin. $install_result = WP_CLI::runcommand( 'plugin install ' . $plugin['slug'], array( 'return' => 'all' ) ); if ( 0 !== $install_result->return_code ) { /* translators: %1$s is the plugin name, %2$s is the error message. */ WP_CLI::warning( sprintf( __( 'Failed to install plugin %1$s. Error: %2$s', 'astra-sites' ), $plugin['name'], $install_result->stderr ) ); continue; } /* translators: %s is the plugin name. */ WP_CLI::line( sprintf( __( 'Plugin %s installed successfully.', 'astra-sites' ), $plugin['name'] ) ); // translators: %s is the plugin name. WP_CLI::line( sprintf( __( 'Activating plugin: %s', 'astra-sites' ), $plugin['name'] ) ); // Activate plugin. $activate_result = WP_CLI::runcommand( 'plugin activate ' . $plugin['slug'], array( 'return' => 'all' ) ); if ( 0 !== $activate_result->return_code ) { /* translators: %1$s is the plugin name, %2$s is the error message. */ WP_CLI::warning( sprintf( __( 'Failed to activate plugin %1$s. Error: %2$s', 'astra-sites' ), $plugin['name'], $activate_result->stderr ) ); // Mark plugin as inactive. $plugin['status'] = 'inactive'; $plugins_to_activate[] = $plugin; continue; } // translators: %s is the plugin name. WP_CLI::line( sprintf( __( 'Plugin %s activated successfully.', 'astra-sites' ), $plugin['name'] ) ); // Mark plugin as active. $plugin['status'] = 'active'; } elseif ( 'inactive' === $plugin['status'] && in_array( $plugin['slug'], $priority_order, true ) ) { $result = $this->attempt_plugin_activation( $plugin, $demo_data ); if ( $result['success'] ) { // translators: %s is the plugin name. WP_CLI::line( sprintf( __( 'Plugin %s activated successfully.', 'astra-sites' ), $plugin['name'] ) ); } else { // translators: %1$s is the plugin name, %2$s is the error message. WP_CLI::warning( sprintf( __( 'Failed to activate plugin %1$s: %2$s', 'astra-sites' ), $plugin['name'], $result['message'] ) ); } $plugin['status'] = 'active'; } elseif ( 'inactive' === $plugin['status'] ) { $plugins_to_activate[] = $plugin; } // Active plugins don't need to be processed. } // Activate plugins using deferred list approach. WP_CLI::line( __( 'Activating Plugins..', 'astra-sites' ) ); $this->activate_plugins_with_deferred_list( $plugins_to_activate, $demo_data ); } /** * Activate plugins using a deferred list approach to handle dependencies. * * @since 4.4.43 * @param array $plugins Plugins to activate. * @param array $demo_data Demo data. * @return void */ private function activate_plugins_with_deferred_list( $plugins, $demo_data ) { $main_list = $plugins; $deferred_list = array(); $max_iterations = count( $plugins ) * 2; // Prevent infinite loops. $iteration = 0; while ( ( ! empty( $main_list ) || ! empty( $deferred_list ) ) && $iteration < $max_iterations ) { $iteration++; $processed_in_this_iteration = false; // Process main list. foreach ( $main_list as $index => $plugin ) { $result = $this->attempt_plugin_activation( $plugin, $demo_data ); if ( $result['success'] ) { /* translators: %s is the plugin name. */ WP_CLI::line( sprintf( __( 'Plugin %s activated successfully.', 'astra-sites' ), $plugin['name'] ) ); unset( $main_list[ $index ] ); $processed_in_this_iteration = true; } elseif ( $result['defer'] ) { // Add to deferred list. $deferred_list[] = $plugin; unset( $main_list[ $index ] ); /* translators: %s is the plugin name. */ WP_CLI::line( sprintf( __( 'Deferring plugin %s due to dependency issues.', 'astra-sites' ), $plugin['name'] ) ); } else { // Actual error, not dependency related. /* translators: %1$s is the plugin name, %2$s is the error message. */ WP_CLI::warning( sprintf( __( 'Failed to activate plugin %1$s: %2$s', 'astra-sites' ), $plugin['name'], $result['message'] ) ); unset( $main_list[ $index ] ); } } // If main list is empty, move deferred list to main list. if ( empty( $main_list ) && ! empty( $deferred_list ) ) { $main_list = $deferred_list; $deferred_list = array(); WP_CLI::line( __( 'Processing deferred plugins...', 'astra-sites' ) ); } // If we didn't process anything in this iteration, break to prevent infinite loop. if ( ! $processed_in_this_iteration && empty( $main_list ) && ! empty( $deferred_list ) ) { WP_CLI::warning( __( 'Could not resolve all plugin dependencies. Some plugins may not be activated.', 'astra-sites' ) ); break; } } // Report any remaining plugins that couldn't be activated. if ( ! empty( $deferred_list ) ) { $plugin_names = array(); foreach ( $deferred_list as $plugin ) { $plugin_names[] = $plugin['name']; } /* translators: %s is a list of plugin names. */ WP_CLI::warning( sprintf( __( 'The following plugins could not be activated due to dependency issues: %s', 'astra-sites' ), implode( ', ', $plugin_names ) ) ); } } /** * Attempt to activate a plugin and handle dependency errors. * * @since 4.4.43 * @param array $plugin Plugin to activate. * @param array $demo_data Demo data. * @return array Result with success, defer, and message keys. */ private function attempt_plugin_activation( $plugin, $demo_data ) { /* translators: %s is the plugin name. */ WP_CLI::line( sprintf( __( 'Activating plugin: %s', 'astra-sites' ), $plugin['name'] ) ); // Capture output to check for dependency errors. ob_start(); Helper::required_plugin_activate( $plugin['init'], $demo_data['astra-site-options-data'], $demo_data['astra-enabled-extensions'] ); $output = ob_get_clean(); // Check if there was a dependency error. if ( strpos( $output, 'requires' ) !== false && ( strpos( $output, 'to be installed and activated' ) !== false || strpos( $output, 'must be activated first' ) !== false ) ) { return array( 'success' => false, 'defer' => true, 'message' => $output, ); } // Check if there was any other error. if ( strpos( $output, 'Error:' ) !== false || strpos( $output, 'error' ) !== false ) { return array( 'success' => false, 'defer' => false, 'message' => $output, ); } // Success. return array( 'success' => true, 'defer' => false, 'message' => 'Plugin activated successfully.', ); } /** * Check if required plugins exist in the demo data. * * @since 4.4.43 * @param array $demo_data Demo data containing required-plugins list. * @param string $plugin_slug Plugin slug to check for. * @return bool True if plugin exists in required list, false otherwise. */ private function is_plugin_required( $demo_data, $plugin_slug ) { // Check if required-plugins data exists. if ( ! isset( $demo_data['required-plugins'] ) || ! is_array( $demo_data['required-plugins'] ) ) { return false; } // Loop through required plugins to find the specified plugin. foreach ( $demo_data['required-plugins'] as $plugin ) { if ( isset( $plugin['slug'] ) && $plugin['slug'] === $plugin_slug ) { return true; } } return false; } } /** * Add Command */ WP_CLI::add_command( 'starter-templates', 'Astra_Sites_WP_CLI' ); WP_CLI::add_command( 'astra-sites', 'Astra_Sites_WP_CLI' ); Astra_Sites_WP_CLI::init(); endif; class-astra-sites-nps-notice.php 0000644 00000010443 15252526617 0012711 0 ustar 00 <?php /** * Init * * @since 1.0.0 * @package NPS Survey */ if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! class_exists( 'Astra_Sites_Nps_Notice' ) ) : /** * Admin */ class Astra_Sites_Nps_Notice { /** * Instance * * @since 1.0.0 * @var (Object) Astra_Sites_Nps_Notice */ private static $instance = null; /** * Get Instance * * @since 1.0.0 * * @return object Class object. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor. * * @since 1.0.0 */ private function __construct() { add_action( 'admin_footer', array( $this, 'render_nps_survey' ), 999 ); // Additional data passing via nps survey. add_filter( 'nps_survey_post_data', array( $this, 'nps_survey_post_data' ) ); } /** * Add import data to the post survey. * * @since 4.4.46 * @param mixed $post_data Post data. * * @return mixed */ public function nps_survey_post_data( $post_data ) { if ( isset( $post_data['plugin_slug'] ) && 'astra-sites' !== $post_data['plugin_slug'] ) { return $post_data; } $import_type = get_option( 'astra_sites_current_import_template_type' ); $post_data['import_type'] = ! empty( $import_type ) ? $import_type : ''; // Normalize AI import type to ai-builder. if ( 'ai' === $post_data['import_type'] ) { $post_data['import_type'] = 'ai-builder'; } // Add UUID for AI builder imports if available. if ( 'ai-builder' === $post_data['import_type'] ) { $zip_import_data = get_option( 'zipwp_import_site_details' ); if ( is_array( $zip_import_data ) && isset( $zip_import_data['uuid'] ) ) { $post_data['uuid'] = sanitize_text_field( $zip_import_data['uuid'] ); } } // Add the Starter Templates plugin version and premium status. if ( defined( 'ASTRA_SITES_VER' ) ) { $post_data['plugin_version'] = ASTRA_SITES_VER; } $post_data['is_premium'] = defined( 'ASTRA_PRO_SITES_NAME' ); return $post_data; } /** * Render NPS Survey * * @return void */ public function render_nps_survey() { if ( ! class_exists( 'Nps_Survey' ) ) { return; } if ( class_exists( 'Astra_Sites_White_Label' ) && is_callable( 'Astra_Sites_White_Label::get_instance' ) && Astra_Sites_White_Label::get_instance()->is_white_labeled() ) { return; } $allowed_screens = array( 'appearance_page_starter-templates', 'appearance_page_ai-builder' ); Nps_Survey::show_nps_notice( 'nps-survey-astra-sites', array( 'show_if' => get_option( 'astra_sites_import_complete', false ), 'dismiss_timespan' => 2 * WEEK_IN_SECONDS, 'display_after' => 0, 'plugin_slug' => 'astra-sites', 'show_on_screens' => $allowed_screens, 'message' => array( // Step 1 i.e rating input. 'logo' => esc_url( INTELLIGENT_TEMPLATES_URI . 'assets/images/logo.svg' ), 'plugin_name' => __( 'Starter Templates', 'astra-sites' ), 'nps_rating_title' => __( 'Quick Question!', 'astra-sites' ), 'nps_rating_message' => sprintf( /* translators: %s is the plugin name */ __( "How would you rate %s? Love it, hate it, or somewhere in between? Your honest answer helps us understand how we're doing.", 'astra-sites' ), '#pluginname' ), 'rating_min_label' => __( 'Hate it', 'astra-sites' ), 'rating_max_label' => __( 'Love it', 'astra-sites' ), // Step 2A i.e. for rating 8 and above. 'feedback_title' => __( 'Thanks a lot for your feedback! 😍', 'astra-sites' ), 'feedback_content' => __( "Thanks for being part of the Starter Templates community! Got feedback or suggestions? We'd love to hear it.", 'astra-sites' ), // Step 2B i.e. for rating 7 and below. 'plugin_rating_title' => __( 'Thank you for your feedback', 'astra-sites' ), 'plugin_rating_content' => __( 'We value your input. How can we improve your experience?', 'astra-sites' ), ), 'privacy_policy' => array( 'disable' => true, // Enable when we have a privacy policy url. ), ) ); } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Nps_Notice::get_instance(); endif; class-astra-sites-astra-onboarding.php 0000644 00000046061 15252526617 0014071 0 ustar 00 <?php /** * Astra Onboarding * * @since 4.4.37 * @package Astra Sites */ if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! class_exists( 'Astra_Sites_Astra_Onboarding' ) ) { /** * Astra Sites Astra Onboarding */ class Astra_Sites_Astra_Onboarding { /** * Instance of Astra_Sites_Astra_Onboarding * * @since 4.4.37 * @var self Astra_Sites_Astra_Onboarding */ private static $instance = null; /** * Get Instance * * @since 4.4.37 * * @return self Class object. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor * * @since 4.4.37 */ private function __construct() { add_action( 'init', array( $this, 'init' ), 15 ); } /** * Initialize * * @since 4.4.37 */ public function init() { // Only load onboarding if Astra theme is active. if ( ! self::is_astra_theme_active() ) { return; } // Bail early if Astra white labeling is enabled. if ( function_exists( 'astra_is_white_labelled' ) && astra_is_white_labelled() ) { return; } // Check if One Onboarding class exists. if ( ! class_exists( '\One_Onboarding\Core\Register' ) ) { return; } $this->register_astra_onboarding(); } /** * Check if Astra theme is active * * @since 4.4.37 * @return bool */ private static function is_astra_theme_active() { $current_theme = get_template(); return 'astra' === $current_theme; } /** * Get feature list * * @since 4.4.37 * @return array */ public static function get_feature_list() { return array( array( 'title' => __( 'Global Color & Typography Controls', 'astra-sites' ), 'description' => __( 'Set global fonts and colors to save time and keep your website looking polished.', 'astra-sites' ), ), array( 'title' => __( 'Flexible Layout Options', 'astra-sites' ), 'description' => __( 'Customize headers, footers, sidebars, blogs, and archive layouts effortlessly.', 'astra-sites' ), ), array( 'title' => __( 'Transparent Header', 'astra-sites' ), 'description' => __( 'Create a transparent header for a modern look that keeps the focus on your content.', 'astra-sites' ), ), array( 'id' => 'advanced-hooks', 'title' => __( 'Site Builder', 'astra-sites' ), 'description' => __( 'Build fully custom websites with more control over design and layout.', 'astra-sites' ), 'isPro' => true, ), array( 'id' => 'header-footer-builder', 'title' => __( 'Header & Footer Builder', 'astra-sites' ), 'description' => __( 'Build headers and footers that give your website a polished, professional look.', 'astra-sites' ), 'isPro' => true, ), array( 'id' => 'woocommerce', 'title' => __( 'Modern WooCommerce Stores', 'astra-sites' ), 'description' => __( 'Easily create beautiful WooCommerce stores that boost sales and grow your business.', 'astra-sites' ), 'isPro' => true, ), ); } /** * Get addon list * * @since 4.4.37 * @return array */ public static function get_addon_list() { $icons = array( 'spectra' => '<svg xmlns="http://www.w3.org/2000/svg" width="51" height="51" viewBox="0 0 51 51" fill="none"> <path fill-rule="evenodd" clip-rule="evenodd" d="M50.0197 25.0099C50.0197 38.8224 38.8224 50.0197 25.0099 50.0197C11.1973 50.0197 0 38.8224 0 25.0099C0 11.1973 11.1973 0 25.0099 0C38.8224 0 50.0197 11.1973 50.0197 25.0099ZM18.9358 26.4388C14.434 25.2955 13.5051 19.0787 17.4352 16.7921L31.3693 8.57458L30.5833 16.0061L23.4376 20.222C22.8659 20.5793 22.9374 21.4368 23.5805 21.5797L31.012 23.5805C35.5138 24.7238 36.4427 30.9406 32.5126 33.2272L18.5785 41.4447L19.3645 34.0132L26.5102 29.7973C27.0819 29.44 27.0104 28.5825 26.3673 28.4396L18.9358 26.4388Z" fill="#5733FF"/> </svg>', 'surerank' => '<svg xmlns="http://www.w3.org/2000/svg" width="102" height="115" viewBox="0 0 102 115" fill="none"> <path d="M101.177 42.6533C101.177 19.2953 82.3389 0.365723 59.094 0.365723H0.189453V114.516H10.088C27.2714 114.516 41.4519 101.621 43.5789 84.9269H43.6067L43.6762 67.2128H42.1887C30.2882 67.2128 20.6121 57.6852 20.2785 45.8106H20.2646V40.1666H25.895C33.7638 40.1666 40.7289 44.0783 44.9831 50.0575C49.0426 35.5984 62.2777 24.9951 77.9596 24.9951V30.639V38.2248C77.9596 54.1647 66.0174 67.101 50.1826 67.1988V84.9269C52.2401 101.663 66.4484 114.627 83.6735 114.627H101.204V80.694H77.4869C91.5284 73.8347 101.204 59.3756 101.204 42.6393L101.177 42.6533Z" fill="#4338CA"/> </svg>', 'sureforms' => '<svg xmlns="http://www.w3.org/2000/svg" width="150" height="150" viewBox="0 0 150 150" fill="none"> <g clip-path="url(#clip0_7471_122)"> <mask id="mask0_7471_122" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="150" height="150"> <path d="M150 0H0V150H150V0Z" fill="white"/> </mask> <g mask="url(#mask0_7471_122)"> <path d="M150 0H0V150H150V0Z" fill="#D54407"/> <path d="M42.8579 32.1396H107.144V53.5683H53.5723L42.8579 64.2825V53.5683V32.1396Z" fill="white"/> <path d="M42.8579 32.1396H107.144V53.5683H53.5723L42.8579 64.2825V53.5683V32.1396Z" fill="white"/> <path d="M42.8579 64.2839H96.4291V85.7124H53.5723L42.8579 96.4266V85.7124V64.2839Z" fill="white"/> <path d="M42.8579 64.2839H96.4291V85.7124H53.5723L42.8579 96.4266V85.7124V64.2839Z" fill="white"/> <path d="M42.8579 96.428H75.0007V117.856H42.8579V96.428Z" fill="white"/> <path d="M42.8579 96.428H75.0007V117.856H42.8579V96.428Z" fill="white"/> </g> </g> <defs> <clipPath id="clip0_7471_122"> <rect width="150" height="150" fill="white"/> </clipPath> </defs> </svg>', 'suremails' => '<svg xmlns="http://www.w3.org/2000/svg" width="33" height="33" viewBox="0 0 33 33" fill="none"> <path fill-rule="evenodd" clip-rule="evenodd" d="M1.45898 0.183594H31.459C32.0113 0.183594 32.459 0.631309 32.459 1.18359V31.1836C32.459 31.7359 32.0113 32.1836 31.459 32.1836H1.45898C0.9067 32.1836 0.458984 31.7359 0.458984 31.1836V1.18359C0.458984 0.631309 0.9067 0.183594 1.45898 0.183594ZM8.99654 15.7372C9.27484 15.9385 9.66999 15.8724 9.85204 15.6016C10.0533 15.3233 9.98719 14.9281 9.71644 14.7461L7.03639 12.8261C6.94114 12.7526 6.94944 12.6607 6.95359 12.6147C6.95779 12.5688 6.99284 12.4886 7.10814 12.4434L24.9405 7.89698C25.0441 7.87858 25.1051 7.92118 25.1469 7.97128C25.1887 8.0214 25.2305 8.0716 25.1837 8.17848L18.4273 25.2741C18.3874 25.3652 18.3203 25.3866 18.2776 25.4002C18.2701 25.4026 18.2634 25.4047 18.2577 25.407C18.2117 25.4028 18.1198 25.3945 18.063 25.306L16.0207 21.5627C15.9885 21.5088 15.9593 21.4482 15.93 21.3877C15.9008 21.3271 15.8715 21.2666 15.8393 21.2127C15.04 19.3982 14.8382 18.0594 16.3384 16.7405L20.2007 13.1663C20.4629 12.9306 20.4887 12.5437 20.2605 12.3007C20.0249 12.0384 19.638 12.0126 19.3949 12.2408L15.3384 15.7372C13.2944 17.535 13.6348 19.7713 14.9281 22.1679L16.9703 25.9112C17.2312 26.4074 17.7618 26.6871 18.3291 26.6644C18.4786 26.6502 18.6399 26.6092 18.7744 26.5565C19.1394 26.4135 19.4251 26.1243 19.5887 25.75L26.3452 8.65438C26.5481 8.15383 26.4527 7.57068 26.0916 7.15808C25.7305 6.74543 25.1799 6.58433 24.6502 6.70313L6.79864 11.2571C6.25729 11.4026 5.84799 11.8289 5.73289 12.3837C5.61774 12.9385 5.85519 13.4882 6.31649 13.8172L8.99654 15.7372ZM8.15163 20.8842C8.20183 20.8645 8.26218 20.8216 8.30583 20.7852L11.0051 18.4161C11.2334 18.2109 11.2559 17.8741 11.0572 17.6625C10.852 17.4342 10.5153 17.4117 10.3037 17.6104L7.60438 19.9795C7.37608 20.1847 7.35363 20.5215 7.55223 20.7331C7.70433 20.9243 7.93418 20.9693 8.15163 20.8842ZM7.80747 24.6731C7.85772 24.6536 7.91822 24.6109 7.96192 24.5746L12.5494 20.5572C12.7783 20.3527 12.8017 20.016 12.6036 19.8038C12.3991 19.5749 12.0624 19.5515 11.8502 19.7495L7.26277 23.7669C7.03387 23.9715 7.01047 24.3082 7.20852 24.5203C7.35357 24.6953 7.60652 24.7512 7.80747 24.6731Z" fill="#0E7EE8"/> </svg>', ); return array( array( 'slug' => 'spectra-blocks', 'title' => 'Spectra Blocks', 'logoSvg' => $icons['spectra'], 'description' => __( 'Powerful visual website builder made for WordPress. Just click, drag, and create anything, no code, no limits.', 'astra-sites' ), ), array( 'slug' => 'surerank', 'title' => 'SureRank', 'logoSvg' => $icons['surerank'], 'description' => __( 'Just a simple, lightweight SEO assistant that helps your site rise in the rankings.', 'astra-sites' ), ), array( 'slug' => 'sureforms', 'title' => 'SureForms', 'logoSvg' => $icons['sureforms'], 'description' => __( 'Create forms that feel like a chat. One question at a time keeps users engaged.', 'astra-sites' ), ), array( 'slug' => 'suremails', 'title' => 'SureMails', 'logoSvg' => $icons['suremails'], 'description' => __( 'Send emails that get delivered. SureMails is a simple, lightweight email delivery service.', 'astra-sites' ), ), ); } /** * Register Astra onboarding page * * @since 4.4.37 */ private function register_astra_onboarding() { \One_Onboarding\Core\Register::register_product( 'astra', array( 'title' => __( 'Astra Onboarding', 'astra-sites' ), 'product' => array( 'id' => 'astra', 'name' => __( 'Astra', 'astra-sites' ), ), 'logo' => ASTRA_SITES_URI . 'inc/assets/images/astra.svg', 'screens' => array( 'welcome' => array( // Use default heading. 'description' => __( 'Build a fast, beautiful WordPress site, effortlessly.', 'astra-sites' ), 'banner' => array( 'type' => 'video', 'url' => 'https://www.youtube-nocookie.com/embed/VCkFWDpjCrg?showinfo=0&autoplay=1&modestbranding=1&rel=0', 'title' => __( 'Getting Started with', 'astra-sites' ), 'thumbnail' => ASTRA_SITES_URI . 'inc/assets/images/astra-welcome-thumbnail.png', ), 'items' => array( __( 'Trusted by 1.8M+ websites worldwide', 'astra-sites' ), __( 'Blazing fast and lightweight for better performance', 'astra-sites' ), __( 'Easy customization, no coding or design skills', 'astra-sites' ), __( 'WooCommerce-ready for quick online store setup', 'astra-sites' ), ), ), 'user-info' => array( // Use default heading. 'description' => __( 'Get helpful updates, new features, and tips to make your website better, while helping us improve Astra.', 'astra-sites' ), 'sourceOptions' => array( 'wordpress' => __( 'WordPress Themes Directory', 'astra-sites' ), 'google' => __( 'Google Search', 'astra-sites' ), 'social' => __( 'Social Media', 'astra-sites' ), 'youtube' => __( 'YouTube', 'astra-sites' ), 'friend' => __( 'A friend or colleague', 'astra-sites' ), 'other' => __( 'Other', 'astra-sites' ), ), 'benefitOptions' => array( 'ai-and-templates' => __( 'AI and Templates will help me design quickly', 'astra-sites' ), 'fast-loading' => __( 'I need a fast-loading theme', 'astra-sites' ), 'design-flexibility' => __( 'I need advanced design flexibility without a bloated builder for free', 'astra-sites' ), 'updates-and-support' => __( 'I trust Brainstorm Force for regular updates and support', 'astra-sites' ), 'other' => __( 'Other (please specify)', 'astra-sites' ), ), 'privacyPolicy' => array( 'url' => 'https://wpastra.com/privacy-policy/?utm_source=starter-templates&utm_medium=astra-onboarding&utm_campaign=link', 'label' => __( 'Privacy Policy', 'astra-sites' ), ), 'optIn' => array( 'description' => __( 'Get helpful updates, new features, and tips to make your website better, while helping us improve Astra by sharing how you use it.', 'astra-sites' ), 'learnMoreUrl' => 'https://wpastra.com/privacy-policy/?utm_source=starter-templates&utm_medium=astra-onboarding&utm_campaign=link', ), ), 'features' => array( // Use default heading. 'description' => __( 'Unlock more design control, faster setup, and powerful customization, so you can build a better website, effortlessly.', 'astra-sites' ), 'featureList' => self::get_feature_list(), 'upgradeUrl' => 'https://wpastra.com/pricing/?utm_source=starter-templates&utm_medium=astra-onboarding&utm_campaign=pro-features', ), 'starter-templates' => array(), // Use default. 'add-ons' => array( // Use default heading and description. 'addonList' => self::get_addon_list(), ), 'done' => array( // Use default heading, description and itemsHeading. 'items' => array( __( 'Customize Your Website', 'astra-sites' ), __( 'Visit Dashboard', 'astra-sites' ), __( 'View Documentation', 'astra-sites' ), ), 'cta1' => array( 'url' => admin_url( 'customize.php' ), 'label' => __( 'Customize Your Site', 'astra-sites' ), ), 'cta2' => array( 'url' => admin_url( 'admin.php?page=astra' ), 'label' => __( 'Visit Dashboard', 'astra-sites' ), ), 'cta3' => array( 'url' => 'https://wpastra.com/docs/?utm_source=starter-templates&utm_medium=astra-onboarding', 'label' => __( 'Docs & Help Center', 'astra-sites' ), ), ), ), 'exit' => array( 'url' => admin_url( 'admin.php?page=astra' ), // Use default label. ), 'colors' => array(), // Use default colors. 'option_name' => 'astra_onboarding', 'pro_status' => Astra_Sites::get_instance()->get_plugin_status( 'astra-addon/astra-addon.php' ), 'pro_slug' => 'astra-addon', ) ); // Add completion hooks. add_action( 'one_onboarding_completion_astra', array( $this, 'handle_onboarding_completion' ), 10, 2 ); // Update product referer. add_action( 'one_onboarding_plugin_activated', array( $this, 'product_activation_utm_event' ) ); } /** * Handle onboarding completion * * @since 4.4.37 * @param array $completion_data Complete data including onboarding state, user info, and product details. * @param \WP_REST_Request $request The REST request object. */ public function handle_onboarding_completion( $completion_data, $request ) { $screens = isset( $completion_data['screens'] ) ? $completion_data['screens'] : array(); $is_user_info_screen_skipped = false; $is_features_screen_skipped = false; foreach ( $screens as $screen ) { if ( 'user-info' === $screen['id'] ) { $is_user_info_screen_skipped = isset( $screen['skipped'] ) ? $screen['skipped'] : true; // If not set, consider it skipped. } if ( 'features' === $screen['id'] ) { $is_features_screen_skipped = isset( $screen['skipped'] ) ? $screen['skipped'] : true; // If not set, consider it skipped. } } // Send user info to subscription webhook if the screen was not skipped. if ( ! $is_user_info_screen_skipped ) { self::generate_lead( $completion_data ); // Update analytics opt-in based on user's choice during onboarding. $user_info = isset( $completion_data['user_info'] ) ? $completion_data['user_info'] : array(); $analytics_optin = ! empty( $user_info['optIn'] ) ? 'yes' : 'no'; update_site_option( 'astra_sites_usage_optin', $analytics_optin ); } // Handle pro features selection if the screen was not skipped. if ( ! $is_features_screen_skipped ) { self::handle_pro_features_selection( $completion_data ); } } /** * Send data to subscription webhook * * @since 4.4.37 * @param array $data Data to send. */ private static function generate_lead( $data ) { if ( empty( $data['user_info'] ) || ! is_array( $data['user_info'] ) ) { return; // Stop if user info is not available. } $user_info = $data['user_info']; $lead_endpoint = Astra_Sites::get_instance()->get_metrics_api_domain() . 'wp-json/bsf-metrics-server/astra/v1/subscribe'; $lead_data = array( 'email' => isset( $user_info['email'] ) ? $user_info['email'] : '', 'first_name' => isset( $user_info['firstName'] ) ? $user_info['firstName'] : '', 'last_name' => isset( $user_info['lastName'] ) ? $user_info['lastName'] : '', 'domain' => wp_parse_url( home_url(), PHP_URL_HOST ), 'source' => isset( $user_info['source'] ) ? $user_info['source'] : '', 'new_user' => isset( $user_info['newUser'] ) ? $user_info['newUser'] : '', 'benefit_id' => isset( $user_info['benefitId'] ) ? $user_info['benefitId'] : '', 'benefit_text' => isset( $user_info['benefitText'] ) ? $user_info['benefitText'] : '', 'opt_in' => ! empty( $user_info['optIn'] ), ); $response = wp_safe_remote_post( $lead_endpoint, array( 'method' => 'POST', 'body' => wp_json_encode( $lead_data ), 'headers' => array( 'Content-Type' => 'application/json', ), ) ); // Log response for debugging. if ( is_wp_error( $response ) ) { astra_sites_error_log( 'Error sending data to subscription webhook: ' . $response->get_error_message() ); } } /** * Handle pro features selection * * @since 4.4.37 * @param array $completion_data Complete data including onboarding state, user info, and product details. */ private static function handle_pro_features_selection( $completion_data ) { if ( ! defined( 'ASTRA_EXT_VER' ) ) { return; // Stop if Astra Pro is not active. } if ( empty( $completion_data['pro_features'] ) && ! is_array( $completion_data['pro_features'] ) ) { return; // Stop if pro features are not available. } // Enable site builder module if selected. if ( in_array( 'advanced-hooks', $completion_data['pro_features'], true ) ) { if ( is_callable( array( 'Astra_Ext_Extension', 'activate_extension' ) ) ) { Astra_Ext_Extension::activate_extension( 'advanced-hooks', true ); } } // header-footer-builder is auto enabled if addon is active. // Enable WooCommerce module if selected. if ( in_array( 'woocommerce', $completion_data['pro_features'], true ) ) { if ( is_callable( array( 'Astra_Ext_Extension', 'activate_extension' ) ) ) { Astra_Ext_Extension::activate_extension( 'woocommerce', true ); } } } /** * Product activation utm event. * * @param string $slug Product slug. * @return void */ public function product_activation_utm_event( $slug ) { if ( empty( $slug ) ) { return; } if ( class_exists( 'BSF_UTM_Analytics' ) && is_callable( array( 'BSF_UTM_Analytics', 'update_referer' ) ) ) { // If the plugin is found and the update_referer function is callable, update the referer with the corresponding product slug. BSF_UTM_Analytics::update_referer( 'astra', $slug ); } } } /** * Initialize class */ Astra_Sites_Astra_Onboarding::get_instance(); } class-astra-sites-update.php 0000644 00000010446 15252526617 0012117 0 ustar 00 <?php /** * Astra Sites Update * * @package Astra Sites */ if ( ! class_exists( 'Astra_Sites_Update' ) ) : /** * Astra Sites Update * * @since 4.2.2 */ class Astra_Sites_Update { /** * Instance * * @access private * @var object Class object. * @since 4.2.2 */ private static $instance = null; /** * Initiator * * @since 4.2.2 * @return object initialized object of class. */ public static function set_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } /** * Constructor * * @since 4.2.2 */ public function __construct() { add_action( 'astra_update_before', __CLASS__ . '::init' ); // Check for plugin updates on plugins_loaded. self::init(); } /** * Update * * @since 4.2.2 * @return void */ public static function init() { do_action( 'astra_sites_update_before' ); // Get auto saved version number. $saved_version = get_option( 'astra-sites-auto-version', '0' ); // If equals then return. if ( version_compare( $saved_version, ASTRA_SITES_VER, '=' ) ) { return; } if ( version_compare( $saved_version, '4.2.2 ', '<' ) ) { // Run batch process to create the json files for existing users. delete_site_option( 'astra-sites-fresh-site' ); delete_site_option( 'astra-sites-last-export-checksums' ); $site_pages = get_option( 'astra-sites-requests' ); if ( ! empty( $site_pages ) ) { // Delete all sites. for ( $site_page = 1; $site_page <= $site_pages; $site_page++ ) { delete_site_option( 'astra-sites-and-pages-page-' . $site_page ); } } $old_options = array( 'astra-blocks-1', 'astra-blocks-2', 'astra-blocks-3', 'astra-blocks-4', 'astra-sites-site-category', 'astra-sites-all-site-categories', 'astra-sites-page-builders', 'astra-blocks-categories', 'astra-sites-requests', ); foreach ( $old_options as $option ) { delete_site_option( $option ); } delete_site_transient( 'astra-sites-import-check' ); } if ( version_compare( $saved_version, '4.3.1', '<' ) ) { if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) { delete_site_option( 'astra-sites-fresh-site' ); delete_site_option( 'astra-sites-batch-status' ); delete_site_transient( 'astra-sites-import-check' ); } } if ( version_compare( $saved_version, '4.4.2', '<' ) ) { $transient_name = 'nps-survay-form-dismissed'; $expiration_time = get_option( '_transient_timeout_' . $transient_name ); $nps_transient = get_transient( $transient_name ); if ( $nps_transient && $expiration_time ) { $transient_duration = 2 * WEEK_IN_SECONDS; $creation_time = $expiration_time - $transient_duration; $status = get_option( 'nps-survay-form-dismiss-status', array() ); $status['dismiss_time'] = $creation_time; update_option( 'nps-survay-form-dismiss-status', $status ); } } if ( version_compare( $saved_version, '4.4.6', '<' ) ) { $old_dismiss_varible = get_option( 'nps-survay-form-dismiss-status' ); if ( ! empty( $old_dismiss_varible ) ) { update_option( 'nps-survey-astra-sites', $old_dismiss_varible ); delete_option( 'nps-survay-form-dismiss-status' ); } } if ( version_compare( $saved_version, '4.4.49', '<' ) ) { self::background_updater_4_4_49(); } // Auto update product latest version. update_option( 'astra-sites-auto-version', ASTRA_SITES_VER, 'no' ); do_action( 'astra_sites_update_after' ); } /** * Background updates for version 4.4.49. * * @since 4.4.49 * @return void */ public static function background_updater_4_4_49() { // Retrieve the installed time and optin status of BSF Analytics and update it as per product specific key. $analytics_options = array( 'bsf_analytics_installed_time' => 'astra_sites_usage_installed_time', 'bsf_analytics_optin' => 'astra_sites_usage_optin', ); foreach ( $analytics_options as $source => $target ) { $status = get_site_option( $source ); if ( ! get_site_option( $target ) && $status ) { update_site_option( $target, $status ); } } } } /** * Kicking this off by calling 'set_instance()' method */ Astra_Sites_Update::set_instance(); endif; compatibility/astra-pro/class-astra-sites-compatibility-astra-pro.php 0000644 00000023335 15252526617 0022176 0 ustar 00 <?php /** * Astra Sites Compatibility for 'Astra Pro' * * @see https://wordpress.org/plugins/astra-pro/ * * @package Astra Sites * @since 1.0.0 */ use STImporter\Importer\Helpers\ST_Image_Importer; if ( ! class_exists( 'Astra_Sites_Compatibility_Astra_Pro' ) ) : /** * Astra_Sites_Compatibility_Astra_Pro * * @since 1.0.0 */ class Astra_Sites_Compatibility_Astra_Pro { /** * Instance * * @access private * @var object Class object. * @since 1.0.0 */ private static $instance; /** * Initiator * * @since 1.0.0 * @return object initialized object of class. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor * * @since 1.0.0 */ public function __construct() { add_action( 'astra_sites_after_plugin_activation', array( $this, 'astra_pro' ), 10, 2 ); add_action( 'astra_sites_import_start', array( $this, 'import_enabled_extension' ), 10, 2 ); add_action( 'astra_sites_import_complete', array( $this, 'import_enabled_extension' ), 10, 1 ); add_action( 'astra_sites_import_complete', array( $this, 'clear_cache' ) ); } /** * Import * * @since 1.1.6 * @return void */ public function import() { if ( defined( 'WP_CLI' ) ) { WP_CLI::line( 'Processing "Astra Pro" Batch Import' ); } Astra_Sites_Importer_Log::add( '---- Processing Mapping - for Astra Pro ----' ); self::start_post_mapping(); } /** * Update Site Origin Active Widgets * * @since 1.0.0 * * @param string $plugin_init Plugin init file. * @param array $data Data. * @return void */ public function astra_pro( $plugin_init = '', $data = array() ) { if ( 'astra-addon/astra-addon.php' === $plugin_init && ! empty( $data ) ) { if ( is_array( $data ) ) { $data = json_decode( wp_json_encode( $data ), true ); } if ( isset( $data['enabled_extensions'] ) ) { $extensions = $data['enabled_extensions']; if ( ! empty( $extensions ) ) { if ( is_callable( 'Astra_Admin_Helper::update_admin_settings_option' ) ) { Astra_Admin_Helper::update_admin_settings_option( '_astra_ext_enabled_extensions', $extensions ); } } } } } /** * Import custom 404 section. * * @since 1.0.0 * @param array $demo_data Site all data render from API call. * @param array $demo_api_uri Demo URL. */ public function import_custom_404( $demo_data = array(), $demo_api_uri = '' ) { if ( isset( $demo_data['astra-custom-404'] ) ) { if ( is_callable( 'Astra_Admin_Helper::update_admin_settings_option' ) ) { $options_404 = $demo_data['astra-custom-404']; Astra_Admin_Helper::update_admin_settings_option( '_astra_ext_custom_404', $options_404 ); } } } /** * Import settings enabled Astra extensions from the demo. * * @since 1.0.0 * @param array $demo_data Site all data render from API call. * @param array $demo_api_uri Demo URL. */ public function import_enabled_extension( $demo_data = array(), $demo_api_uri = '' ) { // Check if the demo data has enabled extensions data, if not then try to get it from the site data (in case of import complete action). if ( ! empty( $demo_data ) && isset( $demo_data['astra-enabled-extensions'] ) ) { $enabled_extensions = $demo_data['astra-enabled-extensions']; } elseif ( function_exists( 'astra_get_site_data' ) ) { $enabled_extensions = astra_get_site_data( 'astra-enabled-extensions' ); } else { return; } if ( ! empty( $enabled_extensions ) && is_callable( 'Astra_Admin_Helper::update_admin_settings_option' ) ) { Astra_Admin_Helper::update_admin_settings_option( '_astra_ext_enabled_extensions', $enabled_extensions ); } } /** * Start post meta mapping of Astra Addon * * @since 1.1.6 * * @return null If there is no import option data found. */ public static function start_post_mapping() { $demo_data = Astra_Sites_File_System::get_instance()->get_demo_content(); if ( ! isset( $demo_data['astra-post-data-mapping'] ) ) { return; } $post_type = 'astra-advanced-hook'; $posts = ( isset( $demo_data['astra-post-data-mapping'][ $post_type ] ) ) ? $demo_data['astra-post-data-mapping'][ $post_type ] : array(); if ( ! empty( $posts ) ) { foreach ( $posts as $key => $post ) { $page = Astra_Site_Options_Import::instance()->get_page_by_title( $post['post_title'], $post_type ); if ( is_object( $page ) ) { if ( defined( 'WP_CLI' ) ) { WP_CLI::line( 'Setting Location Rules for ' . $post['post_title'] ); } self::update_location_rules( $page->ID, 'ast-advanced-hook-location', $post['mapping']['ast-advanced-hook-location'] ); } } } $post_type = 'astra_adv_header'; $posts = ( isset( $demo_data['astra-post-data-mapping'][ $post_type ] ) ) ? $demo_data['astra-post-data-mapping'][ $post_type ] : array(); if ( ! empty( $posts ) ) { foreach ( $posts as $key => $post ) { $page = Astra_Site_Options_Import::instance()->get_page_by_title( $post['post_title'], $post_type ); if ( is_object( $page ) ) { if ( defined( 'WP_CLI' ) ) { WP_CLI::line( 'Setting Location Rules for ' . $post['post_title'] ); } self::update_location_rules( $page->ID, 'ast-advanced-headers-location', $post['mapping']['ast-advanced-headers-location'] ); self::update_location_rules( $page->ID, 'ast-advanced-headers-exclusion', $post['mapping']['ast-advanced-headers-exclusion'] ); self::update_header_mapping( $page->ID, 'ast-advanced-headers-design', $post['mapping']['ast-advanced-headers-design'] ); } } } } /** * Update Header Mapping Data * * @since 1.1.6 * * @param int $post_id Post ID. * @param string $meta_key Post meta key. * @param array $mapping Mapping array. * @return void */ public static function update_header_mapping( $post_id = '', $meta_key = '', $mapping = array() ) { Astra_Sites_Importer_Log::add( 'Mapping "' . $meta_key . '" for ' . $post_id ); $headers_old = get_post_meta( $post_id, $meta_key, true ); $headers_new = self::get_header_mapping( $headers_old, $mapping ); update_post_meta( $post_id, $meta_key, $headers_new ); } /** * Update Location Rules * * @since 1.1.6 * * @param int $post_id Post ID. * @param string $meta_key Post meta key. * @param array $mapping Mapping array. * @return void */ public static function update_location_rules( $post_id = '', $meta_key = '', $mapping = array() ) { Astra_Sites_Importer_Log::add( 'Mapping "' . $meta_key . '" for ' . $post_id ); $location_new = self::get_location_mappings( $mapping ); update_post_meta( $post_id, $meta_key, $location_new ); } /** * Get mapping locations. * * @since 1.1.6 * * @param array $location Location data. * @return array Location mapping data. */ public static function get_location_mappings( $location = array() ) { if ( empty( $location ) ) { return $location; } if ( ! isset( $location['specific'] ) || empty( $location['specific'] ) ) { return $location; } $mapping = array(); if ( isset( $location['specific']['post'] ) ) { foreach ( $location['specific']['post'] as $post_type => $old_post_data ) { if ( is_array( $old_post_data ) ) { foreach ( $old_post_data as $post_key => $post ) { $post_object = get_page_by_path( $post['slug'] ); if ( $post_object ) { $mapping[] = 'post-' . absint( $post_object->ID ); } } } } } if ( isset( $location['specific']['tax'] ) ) { foreach ( $location['specific']['tax'] as $taxonomy_type => $old_term_data ) { if ( is_array( $old_term_data ) ) { foreach ( $old_term_data as $term_key => $term_data ) { $term = get_term_by( 'slug', $term_data['slug'], $taxonomy_type ); if ( is_object( $term ) ) { $mapping[] = 'tax-' . absint( $term->term_id ); } } } } } $location['specific'] = $mapping; return $location; } /** * Get advanced header mapping data * * @since 1.1.6 * * @param array $headers_old Header mapping stored data. * @param array $headers_data Header mapping data. * @return array Filtered header mapping data. */ public static function get_header_mapping( $headers_old = array(), $headers_data = array() ) { // Set menu location by menu slug. if ( isset( $headers_data['menus'] ) && ! empty( $headers_data['menus'] ) ) { foreach ( $headers_data['menus'] as $header_option_name => $menu_data ) { $term = get_term_by( 'slug', $menu_data['slug'], 'nav_menu' ); if ( is_object( $term ) ) { $headers_old[ $header_option_name ] = $term->term_id; } } } // Set image ID & URL after importing these on website. if ( isset( $headers_data['images'] ) && ! empty( $headers_data['images'] ) ) { foreach ( $headers_data['images'] as $key => $image_data ) { if ( isset( $image_data['image'] ) && ! empty( $image_data['image'] ) ) { $downloaded_image = ST_Image_Importer::get_instance()->import( $image_data['image'] ); $headers_old[ $image_data['key_map']['url'] ] = $downloaded_image['url']; $headers_old[ $image_data['key_map']['id'] ] = $downloaded_image['id']; } } } return $headers_old; } /** * Clear Cache * * @since 1.2.3 * @return void */ public function clear_cache() { if ( is_callable( 'Astra_Minify::refresh_assets' ) ) { Astra_Minify::refresh_assets(); } } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Compatibility_Astra_Pro::get_instance(); endif; compatibility/woocommerce/class-astra-sites-compatibility-woocommerce.php 0000644 00000023147 15252526617 0023215 0 ustar 00 <?php /** * Astra Sites Compatibility for 'WooCommerce' * * @see https://wordpress.org/plugins/woocommerce/ * * @package Astra Sites * @since 1.1.4 */ if ( ! class_exists( 'Astra_Sites_Compatibility_WooCommerce' ) ) : /** * WooCommerce Compatibility * * @since 1.1.4 */ class Astra_Sites_Compatibility_WooCommerce { /** * Instance * * @access private * @var object Class object. * @since 1.1.4 */ private static $instance; /** * Initiator * * @since 1.1.4 * @return object initialized object of class. */ public static function instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor * * @since 1.1.4 */ public function __construct() { add_action( 'astra_sites_after_plugin_activation', array( $this, 'install_wc' ), 10, 2 ); add_action( 'astra_sites_before_import_prepare_xml', array( $this, 'import_attributes' ), 10 ); add_filter( 'cfvsw_is_required_screen_for_swatch_types', array( $this, 'screen_required_check' ), 10, 1 ); // WooCommerce product attributes registration. if ( class_exists( 'WooCommerce' ) ) { add_filter( 'wxr_importer.pre_process.term', array( $this, 'woocommerce_product_attributes_registration' ), 10, 1 ); add_action( 'astra_sites_import_complete', array( $this, 'update_wc_lookup_table' ) ); add_action( 'wxr_importer.pre_process.post_meta', array( $this, 'map_new_term_id' ), 10, 2 ); } add_filter( 'astra_sites_pre_process_post_disable_content', '__return_false' ); add_filter( 'astra_sites_pre_process_post_empty_excerpt', '__return_false' ); } /** * Map new term id. * * @param array $meta Meta data. * @param int $post_id Post ID. * @return array Modified meta data. * @since 4.4.19 */ public function map_new_term_id( $meta, $post_id ) { // Early return if not the target meta key. if ( ! isset( $meta['key'] ) || 'cfvsw_product_attr_pa_color' !== $meta['key'] ) { return $meta; } // Early return if value is empty or not serialized. if ( empty( $meta['value'] ) || ! is_serialized( $meta['value'] ) ) { return $meta; } // Safely unserialize data. $unserialized_data = maybe_unserialize( $meta['value'] ); if ( false === $unserialized_data || ! is_array( $unserialized_data ) ) { return $meta; } // Get terms and validate. $terms = wp_get_post_terms( $post_id, 'pa_color' ); if ( is_wp_error( $terms ) || empty( $terms ) ) { return $meta; } // Process only if we have valid color data. if ( empty( $unserialized_data['type'] ) || 'color' !== $unserialized_data['type'] ) { return $meta; } $modified = false; foreach ( $terms as $term ) { if ( ! is_object( $term ) || ! isset( $term->term_id ) ) { continue; } $color_id = get_term_meta( $term->term_id, 'pa_color_id', true ); if ( '' === $color_id || ! isset( $unserialized_data[ $color_id ] ) ) { continue; } $unserialized_data[ $term->term_id ] = $unserialized_data[ $color_id ]; $modified = true; } // Only serialize and update if changes were made. if ( $modified ) { $meta['value'] = maybe_serialize( $unserialized_data ); } return $meta; } /** * Returns true/false that need screen check required to retieve the swatch types * * @since 4.4.19 * @param bool $value Default screen check value passed by the filter. * @return bool */ public function screen_required_check( $value ) { if ( ! is_plugin_active( 'variation-swatches-woo/variation-swatches-woo.php' ) ) { return $value; } if ( ! function_exists( 'astra_sites_has_import_started' ) || ! astra_sites_has_import_started() ) { return $value; } return true; } /** * Add product attributes. * * @since 1.1.4 * * @param string $demo_data Import data. * @param array $demo_api_uri Demo site URL. * @return void */ public function add_attributes( $demo_data = array(), $demo_api_uri = '' ) { $attributes = ( isset( $demo_data['astra-site-options-data']['woocommerce_product_attributes'] ) ) ? $demo_data['astra-site-options-data']['woocommerce_product_attributes'] : array(); if ( ! empty( $attributes ) && function_exists( 'wc_create_attribute' ) ) { foreach ( $attributes as $key => $attribute ) { $args = array( 'name' => $attribute['attribute_label'], 'slug' => $attribute['attribute_name'], 'type' => $attribute['attribute_type'], 'order_by' => $attribute['attribute_orderby'], 'has_archives' => $attribute['attribute_public'], ); $id = wc_create_attribute( $args ); } } } /** * Create default WooCommerce tables * * @param string $plugin_init Plugin file which is activated. * @return void */ public function install_wc( $plugin_init ) { if ( 'woocommerce/woocommerce.php' !== $plugin_init ) { return; } // Create WooCommerce database tables. if ( is_callable( '\Automattic\WooCommerce\Admin\Install::create_tables' ) ) { \Automattic\WooCommerce\Admin\Install::create_tables(); \Automattic\WooCommerce\Admin\Install::create_events(); } if ( is_callable( 'WC_Install::install' ) ) { WC_Install::install(); } } /** * Responsible for importing the product attribute taxonomies * * @since 4.4.19 * @return void */ public function import_attributes() { if ( ! is_plugin_active( 'woocommerce/woocommerce.php' ) && ! is_plugin_active( 'variation-swatches-woo/variation-swatches-woo.php' ) ) { return; } // Get site options data containing product attributes. $options_data = astra_get_site_data( 'astra-site-options-data' ); // Get formatted attribute arguments. $attribute_args = $this->get_attribute_args( $options_data ); if ( ! empty( $attribute_args ) && function_exists( 'wc_create_attribute' ) ) { foreach ( $attribute_args as $attribute_arg ) { // Create WooCommerce attribute. $id = wc_create_attribute( $attribute_arg ); // Store attribute ID if creation was successful. if ( $id && ! is_wp_error( $id ) ) { update_option( $attribute_arg['slug'] . '_attribute_id', $id ); } } } } /** * Creates array of attributes with proper attribute values * * @since 4.4.19 * @param array $options_data Options data in import json. * @return array */ public function get_attribute_args( $options_data ) { $attributes = ( isset( $options_data['woocommerce_product_attributes'] ) ) ? $options_data['woocommerce_product_attributes'] : array(); $attribute_args = array(); foreach ( $attributes as $key => $attribute ) { if ( taxonomy_exists( 'pa_' . $attribute['attribute_name'] ) ) { continue; } $attribute_args[] = array( 'name' => $attribute['attribute_label'], 'slug' => $attribute['attribute_name'], 'type' => $attribute['attribute_type'], 'order_by' => $attribute['attribute_orderby'], 'has_archives' => $attribute['attribute_public'], ); } return apply_filters( 'astra_sites_woocommerce_attribute_args', $attribute_args ); } /** * Hook into the pre-process term filter of the content import and register the * custom WooCommerce product attributes, so that the terms can then be imported normally. * * This should probably be removed once the WP importer 2.0 support is added in WooCommerce. * * Fixes: [WARNING] Failed to import pa_size L warnings in content import. * Code from: woocommerce/includes/admin/class-wc-admin-importers.php (ver 2.6.9). * * Github issue: https://github.com/proteusthemes/one-click-demo-import/issues/71 * * @since 3.0.0 * @param array $data The term data to import. * @return array The unchanged term data. */ public function woocommerce_product_attributes_registration( $data ) { global $wpdb; if ( strstr( $data['taxonomy'], 'pa_' ) ) { if ( ! taxonomy_exists( $data['taxonomy'] ) ) { $attribute_name = wc_sanitize_taxonomy_name( str_replace( 'pa_', '', $data['taxonomy'] ) ); // Create the taxonomy. if ( ! in_array( $attribute_name, wc_get_attribute_taxonomies(), true ) ) { $attribute = array( 'attribute_label' => $attribute_name, 'attribute_name' => $attribute_name, 'attribute_type' => 'select', 'attribute_orderby' => 'menu_order', 'attribute_public' => 0, ); $wpdb->insert( $wpdb->prefix . 'woocommerce_attribute_taxonomies', $attribute ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- WP Query would be expensive here, we are adding taxonomy attributes for WooCommerce. delete_transient( 'wc_attribute_taxonomies' ); } // Register the taxonomy now so that the import works! register_taxonomy( $data['taxonomy'], apply_filters( 'woocommerce_taxonomy_objects_' . $data['taxonomy'], array( 'product' ) ), apply_filters( 'woocommerce_taxonomy_args_' . $data['taxonomy'], array( 'hierarchical' => true, 'show_ui' => false, 'query_var' => true, 'rewrite' => false, ) ) ); } } return $data; } /** * Update WooCommerce Lookup Table. * * @since 3.0.0 * * @return void */ public function update_wc_lookup_table() { if ( function_exists( 'wc_update_product_lookup_tables' ) ) { if ( ! wc_update_product_lookup_tables_is_running() ) { wc_update_product_lookup_tables(); } } } } /** * Kicking this off by calling 'instance()' method */ Astra_Sites_Compatibility_WooCommerce::instance(); endif; compatibility/spectra-pro/class-astra-sites-compatibility-spectra-pro.php 0000644 00000002573 15252526617 0023055 0 ustar 00 <?php /** * Astra Sites Compatibility for 'Spectra Pro' * * @see https://wpspectra.com/pricing/ * * @package Astra Sites * @since 4.4.21 */ if ( ! class_exists( 'Astra_Sites_Compatibility_Spectra_Pro' ) ) { /** * Spectra Pro Compatibility. * * @since 4.4.21 */ class Astra_Sites_Compatibility_Spectra_Pro { /** * Instance. * * @access private * @var self Class object. * @since 4.4.21 */ private static $instance; /** * Initiator. * * @since 4.4.21 * @return self initialized object of class. */ public static function instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor. * * @since 4.4.21 */ public function __construct() { add_action( 'astra_sites_after_plugin_activation', array( $this, 'disable_spectra_pro_redirection' ) ); } /** * Disables Spectra Pro redirection during plugin activation. * * @param string $plugin_init The path to the plugin file that was just activated. * * @since 4.4.21 */ public function disable_spectra_pro_redirection( $plugin_init ) { if ( 'spectra-pro/spectra-pro.php' === $plugin_init ) { delete_option( '__spectra_pro_do_redirect' ); } } } /** * Kicking this off by calling 'instance()' method. */ Astra_Sites_Compatibility_Spectra_Pro::instance(); } compatibility/power-coupons/class-astra-sites-compatibility-power-coupons.php 0000644 00000002675 15252526617 0024022 0 ustar 00 <?php /** * Astra Sites Compatibility for 'Power Coupons'. * * @package Astra Sites * @since 4.6.0 */ defined( 'ABSPATH' ) || exit; if ( ! class_exists( 'Astra_Sites_Compatibility_Power_Coupons' ) ) { /** * Power Coupons Compatibility. * * @since 4.6.0 */ class Astra_Sites_Compatibility_Power_Coupons { /** * Instance * * @access private * @var self Class object. * * @since 4.6.0 */ private static $instance = null; /** * Constructor. * * @since 4.6.0 */ public function __construct() { add_action( 'astra_sites_after_plugin_activation', array( $this, 'disable_power_coupons_redirection' ) ); } /** * Initiator. * * @since 4.6.0 * @return self initialized object of class. */ public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } /** * Disables Power Coupons onboarding redirection during plugin activation. * * @param string $plugin_init The path to the plugin file that was just activated. * * @since 4.6.0 * @return void */ public function disable_power_coupons_redirection( $plugin_init ) { if ( 'power-coupons/power-coupons.php' === $plugin_init ) { delete_transient( 'power_coupons_redirect_to_onboarding' ); } } } /** * Kicking this off by calling 'get_instance()' method. */ Astra_Sites_Compatibility_Power_Coupons::get_instance(); } compatibility/elementor/class-astra-sites-compatibility-elementor.php 0000644 00000011512 15252526617 0022334 0 ustar 00 <?php /** * Astra Sites Compatibility for 'Elementor' * * @package Astra Sites * @since 2.0.0 */ namespace AstraSites\Elementor; defined( 'ABSPATH' ) || exit; if ( ! class_exists( '\Elementor\Plugin' ) ) { return; } if ( ! class_exists( 'Astra_Sites_Compatibility_Elementor' ) ) : /** * Elementor Compatibility * * @since 2.0.0 */ class Astra_Sites_Compatibility_Elementor { /** * Instance * * @access private * @var object Class object. * @since 2.0.0 */ private static $instance; /** * Initiator * * @since 2.0.0 * @return object initialized object of class. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor * * @since 2.0.0 */ public function __construct() { /** * Add Slashes * * @todo Elementor already have below code which works on defining the constant `WP_LOAD_IMPORTERS`. * After defining the constant `WP_LOAD_IMPORTERS` in WP CLI it was not works. * Try to remove below duplicate code in future. */ if ( ! wp_doing_ajax() || ( defined( 'ELEMENTOR_VERSION' ) && version_compare( ELEMENTOR_VERSION, '3.0.0', '>=' ) ) ) { remove_filter( 'wp_import_post_meta', array( 'Elementor\Compatibility', 'on_wp_import_post_meta' ) ); remove_filter( 'wxr_importer.pre_process.post_meta', array( 'Elementor\Compatibility', 'on_wxr_importer_pre_process_post_meta' ) ); add_filter( 'wp_import_post_meta', array( $this, 'on_wp_import_post_meta' ) ); add_filter( 'wxr_importer.pre_process.post_meta', array( $this, 'on_wxr_importer_pre_process_post_meta' ) ); } add_action( 'astra_sites_before_delete_imported_posts', array( $this, 'force_delete_kit' ), 10, 2 ); add_action( 'astra_sites_before_sse_import', array( $this, 'disable_attachment_metadata' ) ); add_action( 'init', array( $this, 'init' ) ); add_action( 'astra_sites_after_plugin_activation', array( $this, 'disable_elementor_redirect' ) ); } /** * Disable Elementor redirect. * * @return void. */ public function disable_elementor_redirect() { $elementor_redirect = get_transient( 'elementor_activation_redirect' ); if ( ! empty( $elementor_redirect ) && '' !== $elementor_redirect ) { delete_transient( 'elementor_activation_redirect' ); } } /** * Remove the transient update check for plugins callback from Elementor. * This reduces the extra code execution for Elementor. */ public function init() { if ( astra_sites_has_import_started() && null !== \Elementor\Plugin::$instance->admin ) { remove_filter( 'pre_set_site_transient_update_plugins', array( \Elementor\Plugin::$instance->admin->get_component( 'canary-deployment' ), 'check_version' ) ); } } /** * Disable the attachment metadata */ public function disable_attachment_metadata() { remove_filter( 'wp_update_attachment_metadata', array( \Elementor\Plugin::$instance->uploads_manager->get_file_type_handlers( 'svg' ), 'set_svg_meta_data', ), 10, 2 ); } /** * Force Delete Elementor Kit * * Delete the previously imported Elementor kit. * * @param int $post_id Post name. * @param string $post_type Post type. */ public function force_delete_kit( $post_id = 0, $post_type = '' ) { if ( ! $post_id ) { return; } if ( 'elementor_library' === $post_type ) { $_GET['force_delete_kit'] = true; } } /** * Process post meta before WP importer. * * Normalize Elementor post meta on import, We need the `wp_slash` in order * to avoid the unslashing during the `add_post_meta`. * * Fired by `wp_import_post_meta` filter. * * @since 1.4.3 * @access public * * @param array $post_meta Post meta. * * @return array Updated post meta. */ public function on_wp_import_post_meta( $post_meta ) { foreach ( $post_meta as &$meta ) { if ( '_elementor_data' === $meta['key'] ) { $meta['value'] = wp_slash( $meta['value'] ); break; } } return $post_meta; } /** * Process post meta before WXR importer. * * Normalize Elementor post meta on import with the new WP_importer, We need * the `wp_slash` in order to avoid the unslashing during the `add_post_meta`. * * Fired by `wxr_importer.pre_process.post_meta` filter. * * @since 1.4.3 * @access public * * @param array $post_meta Post meta. * * @return array Updated post meta. */ public function on_wxr_importer_pre_process_post_meta( $post_meta ) { if ( '_elementor_data' === $post_meta['key'] ) { $post_meta['value'] = wp_slash( $post_meta['value'] ); } return $post_meta; } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Compatibility_Elementor::get_instance(); endif; compatibility/sfwd-lms/class-astra-sites-compatibility-sfwd-lms.php 0000644 00000005641 15252526617 0021646 0 ustar 00 <?php /** * Astra Sites Compatibility for 'LearnDash LMS' * * @see https://www.learndash.com/ * * @package Astra Sites * @since 1.3.13 */ if ( ! class_exists( 'Astra_Sites_Compatibility_SFWD_LMS' ) ) : /** * Astra_Sites_Compatibility_SFWD_LMS * * @since 1.3.13 */ class Astra_Sites_Compatibility_SFWD_LMS { /** * Instance * * @access private * @var object Class object. * @since 1.3.13 */ private static $instance; /** * Initiator * * @since 1.3.13 * @return object initialized object of class. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor * * @since 1.3.13 */ public function __construct() { add_filter( 'astra_sites_gutenberg_batch_process_post_types', array( $this, 'set_post_types' ) ); add_action( 'astra_sites_import_complete', array( $this, 'process_landing_pages_mapping' ) ); } /** * Set LearnDash Landing pages with respect to Cartflows. * * @since 2.3.2 */ public function process_landing_pages_mapping() { $demo_data = Astra_Sites_File_System::get_instance()->get_demo_content(); if ( ! isset( $demo_data['astra-post-data-mapping'] ) || ! isset( $demo_data['astra-post-data-mapping']['ld_landing_pages'] ) ) { return; } $index = 'ld_landing_pages'; $posts = ( isset( $demo_data['astra-post-data-mapping'][ $index ] ) ) ? $demo_data['astra-post-data-mapping'][ $index ] : array(); if ( ! empty( $posts ) ) { foreach ( $posts as $key => $post ) { if ( '' !== $post['landing_page'] ) { // Get course by Title. $course = Astra_Site_Options_Import::instance()->get_page_by_title( $post['course'], 'sfwd-courses' ); // Get landing step by Title. $landing_page = Astra_Site_Options_Import::instance()->get_page_by_title( $post['landing_page'], 'cartflows_step' ); if ( is_object( $course ) && is_object( $landing_page ) ) { if ( defined( 'WP_CLI' ) ) { WP_CLI::line( 'Setting LearnDash - CartFlows Landing page - ' . $course->post_title . ' - ( ' . $course->ID . ' )' ); } $ld_meta = get_post_meta( $course->ID, '_sfwd-courses', true ); $ld_meta['sfwd-courses_wcf_course_template'] = $landing_page->ID; // Update the imported landing step to the course. update_post_meta( $course->ID, '_sfwd-courses', $ld_meta ); } } } } } /** * Set post types * * @since 1.3.13 * * @param array $post_types Post types. */ public function set_post_types( $post_types = array() ) { return array_merge( $post_types, array( 'sfwd-courses', 'sfwd-lessons', 'sfwd-topic', 'sfwd-quiz', 'sfwd-certificates', 'sfwd-assignment' ) ); } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Compatibility_SFWD_LMS::get_instance(); endif; compatibility/uabb/class-astra-sites-compatibility-uabb.php 0000644 00000002110 15252526617 0020164 0 ustar 00 <?php /** * Astra Sites Compatibility for 'UABB - Lite' * * @see https://wordpress.org/plugins/ultimate-addons-for-beaver-builder-lite/ * * @package Astra Sites * @since 3.0.23 */ /** * UABB compatibility for Starter Templates. */ class Astra_Sites_Compatibility_UABB { /** * Instance * * @access private * @var object Class object. * @since 3.0.23 */ private static $instance; /** * Initiator * * @since 3.0.23 * @return object initialized object of class. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor. */ public function __construct() { add_action( 'astra_sites_after_plugin_activation', array( $this, 'uabb_activation' ), 10, 2 ); } /** * Disable redirec after installing and activating UABB. * * @return void */ public function uabb_activation() { update_option( 'uabb_lite_redirect', false ); } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Compatibility_UABB::get_instance(); compatibility/latepoint/class-astra-sites-compatibility-latepoint.php 0000644 00000002675 15252526620 0022352 0 ustar 00 <?php /** * Astra Sites Compatibility for 'LatePoint' * * @see https://wordpress.org/plugins/latepoint/ * * @package Astra Sites * @since 4.4.14 */ if ( ! class_exists( 'Astra_Sites_Compatibility_LatePoint' ) ) : /** * LatePoint Compatibility * * @since 4.4.14 */ class Astra_Sites_Compatibility_LatePoint { /** * Instance * * @access private * @var object Class object. * @since 4.4.14 */ private static $instance; /** * Initiator * * @since 4.4.14 * @return object initialized object of class. */ public static function instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor * * @since 4.4.14 */ public function __construct() { add_action( 'astra_sites_after_plugin_activation', array( $this, 'disable_latepoint_redirection' ) ); } /** * Disables LatePoint redirection during plugin activation. * * @param string $plugin_init The path to the plugin file that was just activated. * * @since 4.4.14 */ public function disable_latepoint_redirection( $plugin_init ) { if ( 'latepoint/latepoint.php' === $plugin_init ) { update_option( 'latepoint_redirect_to_wizard', false ); update_option( 'latepoint_show_version_5_modal', false ); } } } /** * Kicking this off by calling 'instance()' method */ Astra_Sites_Compatibility_LatePoint::instance(); endif; compatibility/cart-abandonment-recovery/class-astra-sites-compatibility-cartflows-ca.php 0000644 00000004076 15252526620 0026007 0 ustar 00 <?php /** * Astra Sites Compatibility for 'Cart Abandonment Recovery'. * * @package Astra Sites * @since 4.4.27 */ defined( 'ABSPATH' ) || exit; if ( ! class_exists( 'Astra_Sites_Compatibility_Cartflows_CA' ) ) { /** * Cart Abandonment Recovery Compatibility. * * @since 4.4.27 */ class Astra_Sites_Compatibility_Cartflows_CA { /** * Instance * * @access private * @var self Class object. * * @since 4.4.27 */ private static $instance = null; /** * Constructor. * * @since 4.4.27 */ public function __construct() { add_action( 'astra_sites_after_plugin_activation', array( $this, 'disable_wcar_redirection' ) ); add_filter( 'cartflows_ca_skip_default_email_templates', array( $this, 'skip_default_email_templates' ), 10, 2 ); } /** * Initiator. * * @since 4.4.27 * @return self initialized object of class. */ public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } /** * Disables Woo Cart Abandonment Recovery redirection during plugin activation. * * @param string $plugin_init The path to the plugin file that was just activated. * * @since 4.4.48 * @return void */ public function disable_wcar_redirection( $plugin_init ) { if ( 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' === $plugin_init ) { update_option( 'wcar_do_redirect', false ); delete_transient( 'wcar_redirect_to_onboarding' ); } } /** * Skip default email templates. * * @param bool $skip Skip flag. * @param bool $force_restore Force restore flag. * * @since 4.4.27 * @return bool */ public function skip_default_email_templates( $skip, $force_restore ) { // If the import has already started, skip the default email templates. if ( astra_sites_has_import_started() && ! $force_restore ) { return true; } return false; } } /** * Kicking this off by calling 'get_instance()' method. */ Astra_Sites_Compatibility_Cartflows_CA::get_instance(); } compatibility/learndash/class-astra-sites-compatibility-learndash.php 0000644 00000002151 15252526620 0022243 0 ustar 00 <?php /** * Compatibility for 'LearnDash' * * @see https://wordpress.org/plugins/astra-pro/ * * @package Astra Sites * @since 2.3.8 */ // If LearnDash is not defined then return false. if ( ! defined( 'LEARNDASH_COURSE_GRID_VERSION' ) ) { return; } if ( ! class_exists( 'Astra_Sites_Compatibility_LearnDash' ) ) : /** * Astra Sites Compatibility LearnDash * * @since 2.3.8 */ class Astra_Sites_Compatibility_LearnDash { /** * Instance * * @access private * @var object Class object. * @since 2.3.8 */ private static $instance; /** * Initiator * * @since 2.3.8 * @return object initialized object of class. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor * * @since 2.3.8 */ public function __construct() { add_filter( 'astra_sites_pre_process_post_disable_content', '__return_false' ); } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Compatibility_LearnDash::get_instance(); endif; compatibility/modern-cart/class-astra-sites-compatibility-modern-cart.php 0000644 00000002645 15252526620 0022777 0 ustar 00 <?php /** * Astra Sites Compatibility for 'Modern Cart'. * * @package Astra Sites * @since 4.4.48 */ defined( 'ABSPATH' ) || exit; if ( ! class_exists( 'Astra_Sites_Compatibility_Modern_Cart' ) ) { /** * Modern Cart Compatibility. * * @since 4.4.48 */ class Astra_Sites_Compatibility_Modern_Cart { /** * Instance * * @access private * @var self Class object. * * @since 4.4.48 */ private static $instance = null; /** * Constructor. * * @since 4.4.48 */ public function __construct() { add_action( 'astra_sites_after_plugin_activation', array( $this, 'disable_modern_cart_redirection' ) ); } /** * Initiator. * * @since 4.4.48 * @return self initialized object of class. */ public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } /** * Disables Woo Modern Cart redirection during plugin activation. * * @param string $plugin_init The path to the plugin file that was just activated. * * @since 4.4.48 * @return void */ public function disable_modern_cart_redirection( $plugin_init ) { if ( 'modern-cart/modern-cart.php' === $plugin_init ) { delete_transient( 'moderncart_redirect_to_onboarding' ); } } } /** * Kicking this off by calling 'get_instance()' method. */ Astra_Sites_Compatibility_Modern_Cart::get_instance(); } compatibility/class-astra-sites-compatibility.php 0000644 00000004517 15252526620 0016353 0 ustar 00 <?php /** * Astra Sites Compatibility for 3rd party plugins. * * @package Astra Sites * @since 1.0.11 */ if ( ! class_exists( 'Astra_Sites_Compatibility' ) ) : /** * Astra Sites Compatibility * * @since 1.0.11 */ class Astra_Sites_Compatibility { /** * Instance * * @access private * @var object Class object. * @since 1.0.11 */ private static $instance; /** * Initiator * * @since 1.0.11 * @return object initialized object of class. */ public static function instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor * * @since 1.0.11 */ public function __construct() { // Plugin - Astra Pro. require_once ASTRA_SITES_DIR . 'inc/classes/compatibility/astra-pro/class-astra-sites-compatibility-astra-pro.php'; // Plugin - WooCommerce. require_once ASTRA_SITES_DIR . 'inc/classes/compatibility/woocommerce/class-astra-sites-compatibility-woocommerce.php'; // Plugin - LearnDash LMS. require_once ASTRA_SITES_DIR . 'inc/classes/compatibility/sfwd-lms/class-astra-sites-compatibility-sfwd-lms.php'; // Plugin - Beaver Builder. require_once ASTRA_SITES_DIR . 'inc/classes/compatibility/beaver-builder/class-astra-sites-compatibility-bb.php'; // Plugin - LearnDash. require_once ASTRA_SITES_DIR . 'inc/classes/compatibility/learndash/class-astra-sites-compatibility-learndash.php'; // Plugin - UABB. require_once ASTRA_SITES_DIR . 'inc/classes/compatibility/uabb/class-astra-sites-compatibility-uabb.php'; // Plugin - Spectra Pro. require_once ASTRA_SITES_DIR . 'inc/classes/compatibility/spectra-pro/class-astra-sites-compatibility-spectra-pro.php'; // Plugin - Cart Abandonment Recovery for WooCommerce. require_once ASTRA_SITES_DIR . 'inc/classes/compatibility/cart-abandonment-recovery/class-astra-sites-compatibility-cartflows-ca.php'; // Plugin - Modern Cart. require_once ASTRA_SITES_DIR . 'inc/classes/compatibility/modern-cart/class-astra-sites-compatibility-modern-cart.php'; // Plugin - Power Coupons. require_once ASTRA_SITES_DIR . 'inc/classes/compatibility/power-coupons/class-astra-sites-compatibility-power-coupons.php'; } } /** * Kicking this off by calling 'instance()' method */ Astra_Sites_Compatibility::instance(); endif; compatibility/checkout-plugins-stripe-woo/class-astra-sites-checkout-plugins-stripe-woo.php 0000644 00000002510 15252526620 0026455 0 ustar 00 <?php /** * Astra Sites Compatibility for 'Checkout Plugins – Stripe for WooCommerce' * * @see https://wordpress.org/plugins/checkout-plugins-stripe-woo/ * * @package Astra Sites * @since 3.0.23 */ /** * Checkout Plugins - Stripe compatibility for Starter Templates. */ class Astra_Sites_Checkout_Plugins_Stripe_WOO { /** * Instance * * @access private * @var object Class object. * @since 3.0.23 */ private static $instance; /** * Initiator * * @since 3.0.23 * @return object initialized object of class. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor. */ public function __construct() { add_action( 'astra_sites_after_plugin_activation', array( $this, 'checkout_plugins' ), 10, 2 ); } /** * Disable redirec after installing and activating Checkout Plugins - Stripe. * * @param string $plugin_init Plugin init file used for activation. * @return void */ public function checkout_plugins( $plugin_init ) { if ( 'checkout-plugins-stripe-woo/checkout-plugins-stripe-woo.php' === $plugin_init ) { delete_option( 'cpsw_start_onboarding' ); } } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Checkout_Plugins_Stripe_WOO::get_instance(); compatibility/beaver-builder/class-astra-sites-compatibility-bb.php 0000644 00000002152 15252526620 0021615 0 ustar 00 <?php /** * Astra Sites Compatibility for 'Beaver Builder' * * @package Astra Sites * @since 3.0.21 */ defined( 'ABSPATH' ) || exit; /** * Beaver Builder Compatibility * * @since 3.0.21 */ class Astra_Sites_Compatibility_BB { /** * Instance * * @access private * @var object Class object. * @since 3.0.21 */ private static $instance; /** * Initiator * * @since 3.0.21 * @return object initialized object of class. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor * * @since 3.0.21 */ public function __construct() { add_action( 'fl_builder_activated', array( $this, 'bb_activated' ) ); } /** * Disable redirection for Beaver Builder plugin when activated via Starter templates import process. */ public function bb_activated() { if ( astra_sites_has_import_started() ) { delete_transient( '_fl_builder_activation_admin_notice' ); } } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Compatibility_BB::get_instance(); class-astra-sites-page.php 0000644 00000044467 15252526620 0011555 0 ustar 00 <?php /** * Astra Sites Page * * @since 1.0.6 * @package Astra Sites */ if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! class_exists( 'Astra_Sites_Page' ) ) { /** * Astra Admin Settings */ class Astra_Sites_Page { /** * View all actions * * @since 1.0.6 * @var array $view_actions */ public $view_actions = array(); /** * Member Variable * * @var instance */ private static $instance; /** * Initiator * * @return self * @since 1.3.0 */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor * * @since 1.3.0 */ public function __construct() { if ( ! current_user_can( 'edit_posts' ) ) { return; } add_action( 'wp_ajax_astra-sites-show-other-builders', array( $this, 'enable_other_builders' ) ); add_action( 'wp_ajax_astra-sites-change-page-builder', array( $this, 'save_page_builder_on_ajax' ) ); add_action( 'wp_ajax_astra-sites-dismiss-ai-promotion', array( $this, 'dismiss_ai_promotion' ) ); add_action( 'admin_init', array( $this, 'getting_started' ) ); add_filter( 'getting_started_menu_priority', array( $this, 'get_gs_menu_priority' ) ); } /** * Enable Other Builders via AJAX * * @since 4.4.21 * @return void */ public function enable_other_builders() { // Verify the AJAX nonce to ensure the request is legitimate. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); // Check if the current user has the capability to manage options. if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) ); } // Array of page builder keys to update. $page_builders = array( 'st-elementor-builder-flag', // Elementor. 'st-beaver-builder-flag', // Beaver Builder. // Add other page builder keys as needed. ); // Loop through each page builder key and update the option. foreach ( $page_builders as $builder_key ) { delete_option( $builder_key ); } // Send a success response back to the AJAX request. wp_send_json_success(); } /** * Admin notice * * @since 1.3.5 * * @return void */ public function getting_started() { $current_screen = get_current_screen(); // Bail if not on Astra Sites screen. if ( ! is_object( $current_screen ) && null === $current_screen ) { return; } if ( 'plugins' === $current_screen->base ) { $processed = get_option( '_astra_sites_gettings_started', 'no' ); $product_name = Astra_Sites_White_Label::get_instance()->get_white_label_name( 'Astra' ); if ( 'yes' === $processed ) { return; } // Get the starter templates URL. $url = esc_url( Astra_Sites::get_starter_templates_url() ); ?> <div class="notice notice-info is-dismissible astra-sites-notice astra-sites-getting-started-notice"> <?php /* translators: %1$s is the admin page URL, %2$s is product name. */ ?> <p><?php printf( esc_attr__( 'Thank you for choosing %1$s! Check the library of <a class="astra-sites-getting-started-btn" href="%2$s">ready starter templates here »</a>', 'astra-sites' ), esc_html( $product_name ), esc_url( $url ) ); ?></p> </div> <?php } } /** * Getting Started Menu Priority * * @since 4.4.35 * @param float $default_priority Default menu priority. * @return float Menu priority. */ public function get_gs_menu_priority( $default_priority ) { return 2.00001; } /** * Save Page Builder * * @since 1.4.0 The `$page_builder_slug` was added. * * @param string $page_builder_slug Page Builder Slug. * @return mixed */ public function save_page_builder_on_submit( $page_builder_slug = '' ) { // Only admins can save settings. if ( ! defined( 'WP_CLI' ) && ! current_user_can( 'manage_options' ) ) { return; } if ( ! defined( 'WP_CLI' ) && ( ! isset( $_REQUEST['astra-sites-page-builder'] ) || ! wp_verify_nonce( sanitize_text_field( $_REQUEST['astra-sites-page-builder'] ), 'astra-sites-welcome-screen' ) ) ) { return; } // Stored Settings. $stored_data = $this->get_settings(); $page_builder = isset( $_REQUEST['page_builder'] ) ? sanitize_key( $_REQUEST['page_builder'] ) : sanitize_key( $page_builder_slug ); if ( ! empty( $page_builder ) ) { // New settings. $new_data = array( 'page_builder' => $page_builder, ); // Merge settings. $data = wp_parse_args( $new_data, $stored_data ); // Update settings. update_option( 'astra_sites_settings', $data ); } if ( ! defined( 'WP_CLI' ) ) { wp_safe_redirect( admin_url( '/themes.php?page=astra-sites' ) ); exit; } } /** * Save Page Builder * * @return void */ public function save_page_builder_on_ajax() { check_ajax_referer( 'astra-sites', '_ajax_nonce' ); // Only admins can save settings. if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error(); } // Stored Settings. $stored_data = $this->get_settings(); // New settings. $new_data = array( 'page_builder' => ( isset( $_REQUEST['page_builder'] ) ) ? sanitize_key( $_REQUEST['page_builder'] ) : '', ); // Merge settings. $data = wp_parse_args( $new_data, $stored_data ); // Update settings. update_option( 'astra_sites_settings', $data, 'no' ); $sites = $this->get_sites_by_page_builder( $new_data['page_builder'] ); wp_send_json_success( $sites ); } /** * Dismiss AI Promotion * * @return void */ public function dismiss_ai_promotion() { check_ajax_referer( 'astra-sites', '_ajax_nonce' ); // Only admins can save settings. if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) ); } // Stored Settings. $stored_data = $this->get_settings(); // New settings. $new_data = array( 'dismiss_ai_promotion' => ( isset( $_REQUEST['dismiss_ai_promotion'] ) ) ? sanitize_key( $_REQUEST['dismiss_ai_promotion'] ) : false, ); // Merge settings. $data = wp_parse_args( $new_data, $stored_data ); // Update settings. update_option( 'astra_sites_settings', $data, 'no' ); wp_send_json_success( __( 'Notice Dismissed!', 'astra-sites' ) ); } /** * Get Page Builder Sites * * @since 2.0.0 * * @param string $default_page_builder default page builder slug. * @return array page builder sites. */ public function get_sites_by_page_builder( $default_page_builder = '' ) { $sites_and_pages = Astra_Sites::get_instance()->get_all_sites(); $current_page_builder_sites = array(); if ( ! empty( $sites_and_pages ) ) { $page_builder_keys = wp_list_pluck( $sites_and_pages, 'astra-site-page-builder' ); foreach ( $page_builder_keys as $site_id => $page_builder ) { if ( $default_page_builder === $page_builder ) { $current_page_builder_sites[ $site_id ] = $sites_and_pages[ $site_id ]; } } } return $current_page_builder_sites; } /** * Get single setting value * * @param string $key Setting key. * @param mixed $defaults Setting value. * @return mixed Stored setting value. */ public function get_setting( $key = '', $defaults = '' ) { $settings = $this->get_settings(); if ( empty( $settings ) ) { return $defaults; } if ( array_key_exists( $key, $settings ) ) { return $settings[ $key ]; } return $defaults; } /** * Get Settings * * @return array Stored settings. */ public function get_settings() { $defaults = array( 'page_builder' => 'gutenberg', ); $stored_data = get_option( 'astra_sites_settings', $defaults ); return wp_parse_args( $stored_data, $defaults ); } /** * Update Settings * * @param array $args Arguments. */ public function update_settings( $args = array() ) { $stored_data = get_option( 'astra_sites_settings', array() ); $new_data = wp_parse_args( $args, $stored_data ); update_option( 'astra_sites_settings', $new_data, 'no' ); } /** * View actions * * @since 1.0.11 */ public function get_view_actions() { if ( empty( $this->view_actions ) ) { $this->view_actions = apply_filters( 'astra_sites_menu_item', array() ); } return $this->view_actions; } /** * Site Filters * * @since 2.0.0 * * @return void */ public function site_filters() { ?> <div class="wp-filter hide-if-no-js"> <div class="section-left"> <div class="search-form"> <?php $categories = Astra_Sites_File_System::get_instance()->get_json_file_content( 'astra-sites-all-site-categories.json' ); if ( ! empty( $categories ) ) { ?> <div id="astra-sites__category-filter" class="dropdown-check-list" tabindex="100"> <span class="astra-sites__category-filter-anchor" data-slug=""><?php esc_html_e( 'All', 'astra-sites' ); ?></span> <ul class="astra-sites__category-filter-items"> <li class="ast-sites__filter-wrap category-active" data-slug=""><?php esc_html_e( 'All', 'astra-sites' ); ?> </li> <?php foreach ( $categories as $key => $value ) { if ( 'free' !== $value['slug'] ) { ?> <li class="ast-sites__filter-wrap" data-slug="<?php echo esc_attr( $value['slug'] ); ?>"><?php echo esc_html( $value['name'] ); ?> </li> <?php } } ?> <li class="ast-sites__filter-wrap-checkbox first-wrap"> <label> <input id="radio-all" type="radio" name="ast-sites-radio" class="checkbox active" value="" checked /><?php esc_html_e( 'All', 'astra-sites' ); ?> </label> </li> <li class="ast-sites__filter-wrap-checkbox"> <label> <input id="radio-free" type="radio" name="ast-sites-radio" class="checkbox" value="free" /><?php esc_html_e( 'Free', 'astra-sites' ); ?> </label> </li> <li class="ast-sites__filter-wrap-checkbox"> <label> <input id="radio-agency" type="radio" name="ast-sites-radio" class="checkbox" value="agency" /><?php esc_html_e( 'Premium', 'astra-sites' ); ?> </label> </li> </ul> </div> <?php } ?> <input autocomplete="off" placeholder="<?php esc_attr_e( 'Search...', 'astra-sites' ); ?>" type="search" aria-describedby="live-search-desc" id="wp-filter-search-input" class="wp-filter-search"> <span class="ast-icon-search search-icon"></span> <div class="astra-sites-autocomplete-result"></div> </div> </div> </div> <?php } /** * Get Default Page Builder * * @since 2.0.0 * * @return mixed page builders or empty string. */ public function get_default_page_builder() { $default_page_builder = $this->get_setting( 'page_builder' ); $page_builders = Astra_Sites::get_instance()->get_page_builders(); foreach ( $page_builders as $key => $page_builder ) { if ( $page_builder['slug'] === $default_page_builder ) { return $page_builder; } } return ''; } /** * Get Page Builders * * @since 2.0.0 * * @param string $slug Page Builder Slug. * @return array page builders. */ public function get_page_builder_image( $slug ) { $image = ''; switch ( $slug ) { case 'elementor': $image = ASTRA_SITES_URI . 'inc/assets/images/elementor.jpg'; break; case 'beaver-builder': $image = ASTRA_SITES_URI . 'inc/assets/images/beaver-builder.jpg'; break; case 'gutenberg': $image = ASTRA_SITES_URI . 'inc/assets/images/block-editor.png'; break; case 'brizy': $image = ASTRA_SITES_URI . 'inc/assets/images/brizy.jpg'; break; } return $image; } /** * Page Builder List * * @since 1.4.0 * @return array */ public function get_page_builders() { return array( 'gutenberg' => array( 'slug' => 'gutenberg', 'name' => esc_html__( 'Gutenberg', 'astra-sites' ), 'image_url' => ASTRA_SITES_URI . 'inc/assets/images/block-editor.jpg', 'title' => esc_html__( 'The default WordPress editor', 'astra-sites' ), ), 'elementor' => array( 'slug' => 'elementor', 'name' => esc_html__( 'Elementor', 'astra-sites' ), 'image_url' => ASTRA_SITES_URI . 'inc/assets/images/elementor.jpg', ), 'beaver-builder' => array( 'slug' => 'beaver-builder', 'name' => esc_html__( 'Beaver Builder', 'astra-sites' ), 'image_url' => ASTRA_SITES_URI . 'inc/assets/images/beaver-builder.jpg', ), 'brizy' => array( 'slug' => 'brizy', 'name' => esc_html__( 'Brizy', 'astra-sites' ), 'image_url' => ASTRA_SITES_URI . 'inc/assets/images/brizy.jpg', ), ); } /** * Get and return page URL * * @param string $menu_slug Menu name. * @since 1.0.6 * @return string page url */ public function get_page_url( $menu_slug ) { $current_slug = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : 'starter-templates'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Fetching GET parameter, no nonce associated with this action. $parent_page = 'themes.php'; if ( strpos( $parent_page, '?' ) !== false ) { $query_var = '&page=' . $current_slug; } else { $query_var = '?page=' . $current_slug; } $parent_page_url = admin_url( $parent_page . $query_var ); $url = $parent_page_url . '&action=' . $menu_slug; return esc_url( $url ); } /** * Converts a period of time in seconds into a human-readable format representing the interval. * * @since 2.0.0 * * Example: * * echo self::interval( 90 ); * // 1 minute 30 seconds * * @param int $since A period of time in seconds. * @return string An interval represented as a string. */ public function interval( $since ) { // Array of time period chunks. $chunks = array( /* translators: 1: The number of years in an interval of time. */ array( 60 * 60 * 24 * 365, _n_noop( '%s year', '%s years', 'astra-sites' ) ), /* translators: 1: The number of months in an interval of time. */ array( 60 * 60 * 24 * 30, _n_noop( '%s month', '%s months', 'astra-sites' ) ), /* translators: 1: The number of weeks in an interval of time. */ array( 60 * 60 * 24 * 7, _n_noop( '%s week', '%s weeks', 'astra-sites' ) ), /* translators: 1: The number of days in an interval of time. */ array( 60 * 60 * 24, _n_noop( '%s day', '%s days', 'astra-sites' ) ), /* translators: 1: The number of hours in an interval of time. */ array( 60 * 60, _n_noop( '%s hour', '%s hours', 'astra-sites' ) ), /* translators: 1: The number of minutes in an interval of time. */ array( 60, _n_noop( '%s minute', '%s minutes', 'astra-sites' ) ), /* translators: 1: The number of seconds in an interval of time. */ array( 1, _n_noop( '%s second', '%s seconds', 'astra-sites' ) ), ); if ( $since <= 0 ) { return esc_html__( 'now', 'astra-sites' ); } /** * We only want to output two chunks of time here, eg: * x years, xx months * x days, xx hours * so there's only two bits of calculation below: */ $j = count( $chunks ); // Step one: the first chunk. for ( $i = 0; $i < $j; $i++ ) { $seconds = $chunks[ $i ][0]; $name = $chunks[ $i ][1]; // Finding the biggest chunk (if the chunk fits, break). $count = floor( $since / $seconds ); if ( $count ) { break; } } // Set output var. $output = sprintf( translate_nooped_plural( $name, $count, 'astra-sites' ), $count ); // Step two: the second chunk. if ( $i + 1 < $j ) { $seconds2 = $chunks[ $i + 1 ][0]; $name2 = $chunks[ $i + 1 ][1]; $count2 = floor( ( $since - ( $seconds * $count ) ) / $seconds2 ); if ( $count2 ) { // Add to output var. $output .= ' ' . sprintf( translate_nooped_plural( $name2, $count2, 'astra-sites' ), $count2 ); } } return $output; } /** * Check Cron Status * * Gets the current cron status by performing a test spawn. Cached for one hour when all is well. * * @since 2.0.0 * * @param bool $cache Whether to use the cached result from previous calls. * @return true|WP_Error Boolean true if the cron spawner is working as expected, or a WP_Error object if not. */ public static function test_cron( $cache = true ) { global $wp_version; if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) { return new WP_Error( 'astra_sites_cron_error', esc_html__( 'ERROR! Cron schedules are disabled by setting constant DISABLE_WP_CRON to true.<br/>To start the import process please enable the cron by setting the constant to false. E.g. define( \'DISABLE_WP_CRON\', false );', 'astra-sites' ) ); } if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) { return new WP_Error( 'astra_sites_cron_error', esc_html__( 'ERROR! Cron schedules are disabled by setting constant ALTERNATE_WP_CRON to true.<br/>To start the import process please enable the cron by setting the constant to false. E.g. define( \'ALTERNATE_WP_CRON\', false );', 'astra-sites' ) ); } $cached_status = get_transient( 'astra-sites-cron-test-ok' ); if ( $cache && $cached_status ) { return true; } $sslverify = version_compare( $wp_version, 4.0, '<' ); $doing_wp_cron = sprintf( '%.22F', microtime( true ) ); $cron_request = apply_filters( 'cron_request', array( 'url' => site_url( 'wp-cron.php?doing_wp_cron=' . $doing_wp_cron ), 'key' => $doing_wp_cron, 'args' => array( 'timeout' => 3, 'blocking' => true, 'sslverify' => apply_filters( 'https_local_ssl_verify', $sslverify ), ), ) ); $cron_request['args']['blocking'] = true; $result = wp_safe_remote_post( $cron_request['url'], $cron_request['args'] ); if ( is_wp_error( $result ) ) { return $result; } elseif ( wp_remote_retrieve_response_code( $result ) >= 300 ) { return new WP_Error( 'unexpected_http_response_code', sprintf( /* translators: 1: The HTTP response code. */ __( 'Unexpected HTTP response code: %s', 'astra-sites' ), intval( wp_remote_retrieve_response_code( $result ) ) ) ); } else { set_transient( 'astra-sites-cron-test-ok', 1, 3600 ); return true; } } } Astra_Sites_Page::get_instance(); }// End if. class-astra-sites-importer-log.php 0000644 00000005663 15252526620 0013254 0 ustar 00 <?php /** * Astra Pro Sites Importer Log * * This class serves as a wrapper around ST_Importer_Log, * providing dynamic prefix switching between ai-builder and astra-sites based on page builder. * * @since 1.1.0 * @package Astra Sites */ if ( ! defined( 'ABSPATH' ) ) { exit; } use STImporter\Importer\ST_Importer_Log; if ( ! class_exists( 'Astra_Sites_Importer_Log' ) ) : /** * Astra Pro Sites Importer Log */ class Astra_Sites_Importer_Log { /** * Instance * * @since 1.1.0 * @var (Object) Class object */ private static $instance = null; /** * Set Instance * * @since 1.1.0 * * @return object Class object. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor. * * @since 1.1.0 */ private function __construct() { // Bail out if ST_Importer_Log does not exist. if ( ! class_exists( 'STImporter\Importer\ST_Importer_Log' ) ) { return; } // Set prefix based on page builder (dynamic switching). add_filter( 'st_importer_log_prefix', array( $this, 'get_prefix_by_page_builder' ), 99 ); // Initialize the ST_Importer_Log instance. ST_Importer_Log::get_instance(); } /** * Get prefix by page builder - Dynamic based on page builder setting * * @since 4.4.49 * @param string $prefix Default prefix. * @return string Modified prefix (astra_sites or ai_builder). */ public function get_prefix_by_page_builder( $prefix ) { $page_builder = Astra_Sites_Page::get_instance()->get_setting( 'page_builder', 'gutenberg' ); if ( 'ai-builder' === $page_builder ) { return 'ai_builder'; } return 'astra_sites'; } /** * Get Log File URL * * @return string File URL. * @since 4.4.49 */ public static function get_log_file_url() { $prefix = self::get_instance()->get_prefix_by_page_builder( '' ); $option_name = $prefix . '_recent_import_log_file'; $log_file = get_option( $option_name, false ); if ( ! empty( $log_file ) && is_string( $log_file ) ) { return str_replace( ABSPATH, esc_url( site_url() ) . '/', $log_file ); } return ''; } /** * Add log entry - Wrapper for ST_Importer_Log::add() * * @since 1.1.0 * @param string $content Content to be saved to the file. * @param string $severity Severity level: 'info', 'success', 'warning', 'error', 'fatal'. Default 'info'. * @param array $context Additional context data for the log entry. * @return void */ public static function add( $content, $severity = 'info', $context = array() ) { // Bail out if ST_Importer_Log does not exist. if ( ! class_exists( 'STImporter\Importer\ST_Importer_Log' ) ) { return; } ST_Importer_Log::add( $content, $severity, $context ); } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Importer_Log::get_instance(); endif; class-astra-sites-importer.php 0000644 00000122574 15252526620 0012476 0 ustar 00 <?php /** * Astra Sites Importer * * @since 1.0.0 * @package Astra Sites */ use STImporter\Importer\ST_Importer_Helper; use STImporter\Importer\WXR_Importer\ST_WXR_Importer; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } if ( ! class_exists( 'Astra_Sites_Importer' ) ) { /** * Astra Sites Importer */ class Astra_Sites_Importer { /** * Instance * * @since 1.0.0 * @var self Class object */ public static $instance = null; /** * Set Instance * * @since 1.0.0 * * @return self Class object. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor. * * @since 1.0.0 */ public function __construct() { require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-importer-log.php'; require_once ASTRA_SITES_DIR . 'inc/importers/class-astra-sites-helper.php'; require_once ASTRA_SITES_DIR . 'inc/importers/class-astra-widget-importer.php'; require_once ASTRA_SITES_DIR . 'inc/importers/class-astra-customizer-import.php'; require_once ASTRA_SITES_DIR . 'inc/importers/class-astra-site-options-import.php'; // Hooks in AJAX. add_action( 'wp_ajax_astra-sites-import-wpforms', array( $this, 'import_wpforms' ) ); add_action( 'wp_ajax_astra-sites-import-cartflows', array( $this, 'import_cartflows' ) ); add_action( 'wp_ajax_astra-sites-import-cart-abandonment-recovery', array( $this, 'import_cart_abandonment_recovery' ) ); add_action( 'wp_ajax_astra-sites-import-latepoint', array( $this, 'import_latepoint' ) ); add_action( 'wp_ajax_astra-sites-verify-required-plugins', array( $this, 'verify_required_plugins' ) ); add_action( 'astra_sites_import_complete', array( $this, 'clear_related_cache' ) ); add_action( 'astra_sites_batch_process_complete', array( $this, 'delete_related_transient' ) ); require_once ASTRA_SITES_DIR . 'inc/importers/batch-processing/class-astra-sites-batch-processing.php'; if ( version_compare( get_bloginfo( 'version' ), '5.1.0', '>=' ) ) { add_filter( 'http_request_timeout', array( $this, 'set_timeout_for_images' ), 10, 2 ); //phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_timeout -- We need this to avoid timeout on slow servers while installing theme, plugin etc. } add_action( 'init', array( $this, 'disable_default_woo_pages_creation' ), 2 ); add_filter( 'upgrader_package_options', array( $this, 'plugin_install_clear_directory' ) ); } /** * Delete imported posts * * @since 1.3.0 * @since 1.4.0 The `$post_id` was added. * Note: This function can be deleted after a few releases since we are performing the delete operation in chunks. * * @param integer $post_id Post ID. * @return void */ public function delete_imported_posts( $post_id = 0 ) { if ( wp_doing_ajax() ) { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'customize' ) ) { wp_send_json_error( __( "Permission denied: You don't have the required capability to delete imported posts. Please contact your site administrator.", 'astra-sites' ) ); } } $post_id = isset( $_REQUEST['post_id'] ) ? absint( $_REQUEST['post_id'] ) : $post_id; $message = 'Deleted - Post ID ' . $post_id . ' - ' . get_post_type( $post_id ) . ' - ' . get_the_title( $post_id ); $message = ''; if ( $post_id ) { $post_type = get_post_type( $post_id ); $message = 'Deleted - Post ID ' . $post_id . ' - ' . $post_type . ' - ' . get_the_title( $post_id ); do_action( 'astra_sites_before_delete_imported_posts', $post_id, $post_type ); Astra_Sites_Importer_Log::add( $message ); wp_delete_post( $post_id, true ); } Astra_Sites_Helper::success_response( $message ); } /** * Delete imported WP forms * * @since 1.3.0 * @since 1.4.0 The `$post_id` was added. * Note: This function can be deleted after a few releases since we are performing the delete operation in chunks. * * @param integer $post_id Post ID. * @return void */ public function delete_imported_wp_forms( $post_id = 0 ) { if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'customize' ) ) { wp_send_json_error( __( "Permission denied: You don't have the required capability to delete imported forms. Please contact your site administrator.", 'astra-sites' ) ); } } $post_id = isset( $_REQUEST['post_id'] ) ? absint( $_REQUEST['post_id'] ) : $post_id; $message = ''; if ( $post_id ) { do_action( 'astra_sites_before_delete_imported_wp_forms', $post_id ); $message = 'Deleted - Form ID ' . $post_id . ' - ' . get_post_type( $post_id ) . ' - ' . get_the_title( $post_id ); Astra_Sites_Importer_Log::add( $message ); wp_delete_post( $post_id, true ); } Astra_Sites_Helper::success_response( $message ); } /** * Delete imported terms * * @since 1.3.0 * @since 1.4.0 The `$post_id` was added. * Note: This function can be deleted after a few releases since we are performing the delete operation in chunks. * * @param integer $term_id Term ID. * @return void */ public function delete_imported_terms( $term_id = 0 ) { if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'customize' ) ) { wp_send_json_error( __( "Permission denied: You don't have the required capability to delete imported terms. Please contact your site administrator.", 'astra-sites' ) ); } } $term_id = isset( $_REQUEST['term_id'] ) ? absint( $_REQUEST['term_id'] ) : $term_id; $message = ''; if ( $term_id ) { $term = get_term( $term_id ); if ( ! is_wp_error( $term ) && ! empty( $term ) && is_object( $term ) ) { do_action( 'astra_sites_before_delete_imported_terms', $term_id, $term ); $message = 'Deleted - Term ' . $term_id . ' - ' . $term->name . ' ' . $term->taxonomy; Astra_Sites_Importer_Log::add( $message ); wp_delete_term( $term_id, $term->taxonomy ); } } Astra_Sites_Helper::success_response( $message ); } /** * Delete related transients * * @since 3.1.3 */ public function delete_related_transient() { delete_option( 'astra_sites_batch_process_started' ); delete_option( 'astra_sites_batch_process_started_time' ); delete_option( 'astra_sites_batch_process_complete' ); Astra_Sites_File_System::get_instance()->delete_demo_content(); delete_option( 'ast_ai_import_current_url' ); delete_option( 'astra_sites_ai_import_started' ); } /** * Delete directory when installing plugin. * * Set by enabling `clear_destination` option in the upgrader. * * @since 3.0.10 * @param array $options Options for the upgrader. * @return array $options The options. */ public function plugin_install_clear_directory( $options ) { Astra_Sites_Importer_Log::add( 'Checking if plugin directory clearing is needed' ); if ( true !== astra_sites_has_import_started() ) { return $options; } $is_ast_request = isset( $_REQUEST['is_ast_request'] ) && 'true' === $_REQUEST['is_ast_request']; //phpcs:ignore -- Nonce verification is not required here as we are just reading a request parameter. if ( ! $is_ast_request ) { Astra_Sites_Importer_Log::add( 'Plugin install clear directory - Not an Astra Sites request, skipping' ); return $options; } // Verify Nonce. check_ajax_referer( 'astra-sites', 'ajax_nonce' ); if ( isset( $_REQUEST['clear_destination'] ) && 'true' === $_REQUEST['clear_destination'] ) { Astra_Sites_Importer_Log::add( 'Plugin install clear directory enabled - Will clear destination directory' ); $options['clear_destination'] = true; } Astra_Sites_Importer_Log::add( 'Plugin install clear directory options returned' ); return $options; } /** * Restrict WooCommerce Pages Creation process * * Why? WooCommerce creates set of pages on it's activation * These pages are re created via our XML import step. * In order to avoid the duplicacy we restrict these page creation process. * * @since 3.0.0 */ public function disable_default_woo_pages_creation() { if ( astra_sites_has_import_started() ) { add_filter( 'woocommerce_create_pages', '__return_empty_array' ); } } /** * Set the timeout for the HTTP request by request URL. * * E.g. If URL is images (jpg|png|gif|jpeg) are from the domain `https://websitedemos.net` then we have set the timeout by 30 seconds. Default 5 seconds. * * @since 1.3.8 * * @param int $timeout_value Time in seconds until a request times out. Default 5. * @param string $url The request URL. */ public function set_timeout_for_images( $timeout_value, $url ) { // URL not contain `https://websitedemos.net` then return $timeout_value. if ( strpos( $url, 'https://websitedemos.net' ) === false ) { return $timeout_value; } // Check is image URL of type jpg|png|gif|jpeg. if ( astra_sites_is_valid_image( $url ) ) { $timeout_value = 300; } return $timeout_value; } /** * Change flow status * * @since 2.0.0 * * @param array $args Flow query args. * @return array Flow query args. */ public function change_flow_status( $args ) { $args['post_status'] = 'publish'; return $args; } /** * Track Flow * * @since 2.0.0 * * @param integer $flow_id Flow ID. * @return void */ public function track_flows( $flow_id ) { Astra_Sites_Importer_Log::add( 'Flow ID ' . $flow_id ); ST_Importer_Helper::track_post( $flow_id ); } /** * Common function for downloading and validating import data files. * * @since 4.4.39 * * @param string $url URL of the JSON data file to download and validate. * @param bool $decode Whether to decode the JSON data. Default true. * @return string|array|WP_Error Returns the file contents as a string if $decode is false, or an associative array if $decode is true. Returns WP_Error on failure. */ private function download_and_validate_import_data( $url = '', $decode = true ) { // Skip import gracefully if no URL (normal condition). if ( empty( $url ) ) { // Success response - no data to import is normal. if ( defined( 'WP_CLI' ) ) { WP_CLI::line( 'No data to import - ' . esc_url( $url ) ); } return array(); } // Validate URL format. if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) { return new WP_Error( 'invalid_url_format', sprintf( /* translators: %s: URL */ __( 'Invalid URL format - %s', 'astra-sites' ), $url ) ); } // Validate URL security. if ( ! astra_sites_is_valid_url( $url ) ) { return new WP_Error( 'invalid_url', sprintf( /* translators: %s: URL */ __( 'Invalid data file URL - %s', 'astra-sites' ), esc_url_raw( $url ) ) ); } // Download JSON file. $file_path = ST_WXR_Importer::download_file( $url ); Astra_Sites_Importer_Log::add( 'File downloaded successfully from: ' . $url, 'success' ); if ( empty( $file_path['success'] ) ) { $error_message = ! empty( $file_path['data'] ) ? $file_path['data'] : __( 'Could not download data file. Please check your internet connection and try again.', 'astra-sites' ); Astra_Sites_Importer_Log::add( 'Download failed for URL: ' . $url ); return new WP_Error( 'download_failed', sprintf( /* translators: %s: Error message */ __( 'File download failed - %s', 'astra-sites' ), $error_message ) ); } if ( empty( $file_path['data']['file'] ) ) { return new WP_Error( 'missing_file_path', __( 'Downloaded file path is missing in the response.', 'astra-sites' ) ); } $downloaded_file_path = $file_path['data']['file']; // Verify file exists. if ( ! file_exists( $downloaded_file_path ) ) { return new WP_Error( 'file_not_found', __( 'Downloaded file is missing. Please retry the import.', 'astra-sites' ) ); } // Verify file is readable. if ( ! is_readable( $downloaded_file_path ) ) { return new WP_Error( 'file_not_readable', __( 'Downloaded file is not readable. Please check server file permissions.', 'astra-sites' ) ); } // Validate file extension. $ext = strtolower( pathinfo( $downloaded_file_path, PATHINFO_EXTENSION ) ); if ( 'json' !== $ext ) { return new WP_Error( 'invalid_file_type', __( 'The file must be in JSON format.', 'astra-sites' ) ); } // Read file contents. $contents = Astra_Sites::get_instance()->get_filesystem()->get_contents( $downloaded_file_path ); // If decoding not required, return raw contents. if ( ! $decode ) { return $contents; } if ( false === $contents ) { return new WP_Error( 'file_read_failed', __( 'Could not read the file from the server.', 'astra-sites' ) ); } if ( empty( $contents ) ) { return new WP_Error( 'empty_file', __( 'The file is empty.', 'astra-sites' ) ); } // Parse JSON. $data = json_decode( $contents, true ); $json_error = json_last_error(); if ( JSON_ERROR_NONE !== $json_error ) { return new WP_Error( 'invalid_json', sprintf( /* translators: %s: JSON error */ __( 'Invalid JSON format - %s', 'astra-sites' ), json_last_error_msg() ) ); } return $data; } /** * Import WP Forms * * @since 1.2.14 * @since 1.4.0 The `$wpforms_url` was added. * * @param string $wpforms_url WP Forms JSON file URL. * @return void */ public function import_wpforms( $wpforms_url = '' ) { Astra_Sites_Importer_Log::add( '---' . PHP_EOL ); Astra_Sites_Importer_Log::add( 'Starting WP Forms import process' ); if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'customize' ) ) { wp_send_json_error( __( "Permission denied: You don't have the required capability to import forms. Please contact your site administrator.", 'astra-sites' ) ); } } Astra_Sites_Helper::extend_time_limit(); try { $screen = ( isset( $_REQUEST['screen'] ) ) ? sanitize_text_field( $_REQUEST['screen'] ) : ''; $id = ( isset( $_REQUEST['id'] ) ) ? absint( $_REQUEST['id'] ) : ''; // Get WPForms URL with enhanced error handling. if ( 'elementor' === $screen ) { if ( empty( $id ) ) { Astra_Sites_Helper::error_response( sprintf( // translators: %s is Elementor plugin name. __( 'WPForms import failed: Template ID is missing. Unable to proceed with %s import.', 'astra-sites' ), 'Elementor' ) ); return; } $wpforms_url = astra_sites_get_wp_forms_url( $id ); Astra_Sites_Importer_Log::add( 'Retrieved WPForms URL for Elementor template: ' . $wpforms_url ); } else { $wpforms_url = astra_get_site_data( 'astra-site-wpforms-path' ); } $ids_mapping = array(); $forms = $this->download_and_validate_import_data( $wpforms_url ); if ( is_wp_error( $forms ) ) { Astra_Sites_Helper::error_response( sprintf( // translators: %s is the error message. __( 'WPForms import failed: %s', 'astra-sites' ), $forms->get_error_message() ) ); return; } if ( empty( $forms ) ) { Astra_Sites_Helper::success_response( array( 'message' => __( 'No WP Forms to import.', 'astra-sites' ), 'file' => $wpforms_url, ) ); return; } // Ensure WPForms plugin is loaded. $result = $this->ensure_plugin_loaded( 'wpforms-lite/wpforms.php', 'WPForms', function() { return function_exists( 'wpforms_encode' ); } ); if ( is_wp_error( $result ) ) { Astra_Sites_Helper::error_response( $result->get_error_message() ); return; } // Process forms with error handling. foreach ( $forms as $form ) { if ( ! is_array( $form ) ) { continue; // Skip invalid form data. } $title = ! empty( $form['settings']['form_title'] ) ? sanitize_text_field( $form['settings']['form_title'] ) : ''; $desc = ! empty( $form['settings']['form_desc'] ) ? sanitize_textarea_field( $form['settings']['form_desc'] ) : ''; if ( empty( $title ) ) { continue; // Skip forms without titles. } $new_id = post_exists( $title ); if ( ! $new_id ) { try { $new_id = wp_insert_post( array( 'post_title' => $title, 'post_status' => 'publish', 'post_type' => 'wpforms', 'post_excerpt' => $desc, ) ); if ( is_wp_error( $new_id ) ) { astra_sites_error_log( 'WPForms import error: ' . $new_id->get_error_message() ); continue; // Skip this form and continue with others. } if ( defined( 'WP_CLI' ) ) { WP_CLI::line( 'Imported Form ' . $title ); } // Set meta for tracking the post.. update_post_meta( $new_id, '_astra_sites_imported_wp_forms', true ); Astra_Sites_Importer_Log::add( 'Successfully inserted WP Form ID ' . $new_id . ' - ' . $title, 'success' ); } catch ( Exception $e ) { astra_sites_error_log( 'WPForms post creation error: ' . $e->getMessage() ); continue; // Skip this form and continue with others. } } if ( $new_id && ! empty( $form['id'] ) ) { // ID mapping.. $ids_mapping[ $form['id'] ] = $new_id; $form['id'] = $new_id; try { $encoded_form = wpforms_encode( $form ); wp_update_post( array( 'ID' => $new_id, 'post_content' => $encoded_form, ) ); } catch ( Exception $e ) { astra_sites_error_log( 'WPForms content update error: ' . $e->getMessage() ); // Continue even if content update fails. } } } // Save ID mapping. update_option( 'astra_sites_wpforms_ids_mapping', $ids_mapping, 'no' ); Astra_Sites_Importer_Log::add( 'WPForms ID mappings saved: ' . count( $ids_mapping ) . ' mappings' ); Astra_Sites_Helper::success_response( array( 'message' => __( 'WP Forms Imported.', 'astra-sites' ), 'mapping' => $ids_mapping, ) ); return; } catch ( \Exception $e ) { // Catch any unexpected errors. astra_sites_error_log( 'WPForms import error: ' . $e->getMessage() ); Astra_Sites_Helper::error_response( sprintf( // translators: %s is exception error message. __( 'WPForms import failed: Unexpected error - %s', 'astra-sites' ), $e->getMessage() ) ); return; } catch ( \Error $e ) { Astra_Sites_Helper::error_response( sprintf( // translators: %s: Fatal error message. __( 'WPForms import failed: Fatal Error: %s', 'astra-sites' ), $e->getMessage() ) ); return; } } /** * Import CartFlows * * @since 2.0.0 * * @param string $url Cartflows JSON file URL. * @return void */ public function import_cartflows( $url = '' ) { Astra_Sites_Importer_Log::add( '---' . PHP_EOL ); Astra_Sites_Importer_Log::add( 'Starting CartFlows import process' ); if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error( __( "Permission Denied: You don't have permission to import CartFlows flows. Please contact your site administrator.", 'astra-sites' ) ); } } Astra_Sites_Helper::extend_time_limit(); // Disable CartFlows import logging. add_filter( 'cartflows_enable_log', '__return_false' ); // Make the flow publish. add_filter( 'cartflows_flow_importer_args', array( $this, 'change_flow_status' ) ); add_action( 'cartflows_flow_imported', array( $this, 'track_flows' ) ); add_action( 'cartflows_step_imported', array( $this, 'track_flows' ) ); add_filter( 'cartflows_enable_imported_content_processing', '__return_false' ); $url = astra_get_site_data( 'astra-site-cartflows-path' ); try { $flows = $this->download_and_validate_import_data( $url ); if ( is_wp_error( $flows ) ) { Astra_Sites_Helper::error_response( sprintf( // translators: %s is the error message. __( 'CartFlows import failed: %s', 'astra-sites' ), $flows->get_error_message() ) ); return; } if ( empty( $flows ) ) { Astra_Sites_Helper::success_response( array( 'message' => __( 'No CartFlows data to import.', 'astra-sites' ), 'file' => $url, ) ); return; } // Ensure CartFlows plugin is loaded. $result = $this->ensure_plugin_loaded( 'cartflows/cartflows.php', 'CartFlows', function() { return class_exists( 'CartFlows_Importer' ); } ); if ( is_wp_error( $result ) ) { Astra_Sites_Helper::error_response( $result->get_error_message() ); return; } // Import CartFlows flows. $import_result = CartFlows_Importer::get_instance()->import_from_json_data( $flows ); Astra_Sites_Importer_Log::add( 'CartFlows data imported successfully', 'success' ); if ( is_wp_error( $import_result ) ) { Astra_Sites_Helper::error_response( sprintf( // translators: Sending cartflows import failed. __( 'CartFlows import failed: %s', 'astra-sites' ), $import_result->get_error_message() ) ); } } catch ( \Exception $e ) { astra_sites_error_log( 'Astra Sites CartFlows Import Exception: ' . $e->getMessage() ); // translators: %s: Exception error message. Astra_Sites_Helper::error_response( sprintf( __( 'CartFlows import failed: Unexpected error - %s', 'astra-sites' ), $e->getMessage() ) ); } catch ( \Error $e ) { astra_sites_error_log( 'Astra Sites CartFlows Import Fatal Error: ' . $e->getMessage() ); // translators: %s: Fatal error message. Astra_Sites_Helper::error_response( sprintf( __( 'CartFlows import failed: Fatal Error - %s', 'astra-sites' ), $e->getMessage() ) ); } Astra_Sites_Helper::success_response( // translators: %s is the URL. sprintf( __( 'Imported from %s', 'astra-sites' ), $url ) ); } /** * Import Cart Abandonment Recovery data. * * @since 4.4.27 * * @param string $url JSON file URL. * @return void */ public function import_cart_abandonment_recovery( $url = '' ) { Astra_Sites_Importer_Log::add( '---' . PHP_EOL ); Astra_Sites_Importer_Log::add( 'Starting Cart Abandonment Recovery import process' ); try { if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error( __( "Permission denied: You don't have permission to import Cart Abandonment Recovery data. Please contact your site administrator.", 'astra-sites' ) ); } } $url = astra_get_site_data( 'astra-site-cart-abandonment-recovery-path' ); $data = $this->download_and_validate_import_data( $url ); if ( is_wp_error( $data ) ) { Astra_Sites_Helper::error_response( sprintf( // translators: %s is the error message. __( 'Cart Abandonment Recovery import failed: %s', 'astra-sites' ), $data->get_error_message() ) ); return; } // Skip import gracefully if no URL (normal condition). if ( empty( $data ) ) { Astra_Sites_Helper::success_response( array( 'message' => __( 'No Cart Abandonment Recovery data to import.', 'astra-sites' ), 'file' => $url, ) ); return; } // Ensure Cart Abandonment Recovery plugin is loaded. $class_file = WP_PLUGIN_DIR . '/woo-cart-abandonment-recovery/modules/cart-abandonment/classes/class-cartflows-ca-email-template-importer-exporter.php'; $loaded = $this->ensure_plugin_loaded( 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php', 'Cart Abandonment Recovery', function() { return class_exists( 'Cartflows_CA_Email_Template_Importer_Exporter' ); }, $class_file ); if ( is_wp_error( $loaded ) ) { Astra_Sites_Helper::error_response( $loaded->get_error_message() ); return; } Cartflows_CA_Email_Template_Importer_Exporter::get_instance()->insert_templates( $data ); Astra_Sites_Importer_Log::add( 'Cart Abandonment Recovery templates inserted successfully', 'success' ); Astra_Sites_Helper::success_response( // translators: %s is the URL. sprintf( __( 'Imported Cart Abandonment Recovery data from %s', 'astra-sites' ), $url ) ); } catch ( Exception $e ) { // translators: %s: Exception error message. Astra_Sites_Helper::error_response( sprintf( __( 'Cart Abandonment Recovery import failed: Unexpected error - %s', 'astra-sites' ), $e->getMessage() ) ); } catch ( \Error $e ) { // translators: %s: Fatal error message. Astra_Sites_Helper::error_response( sprintf( __( 'Cart Abandonment Recovery import failed: Fatal Error - %s', 'astra-sites' ), $e->getMessage() ) ); } } /** * Import LatePoint * * @since 2.0.0 * * @param string $url LatePoint JSON file URL. * @return void */ public function import_latepoint( $url = '' ) { Astra_Sites_Importer_Log::add( '---' . PHP_EOL ); Astra_Sites_Importer_Log::add( 'Starting LatePoint import process' ); if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error( __( "Permission denied: You don't have permission to import LatePoint data. Please contact your site administrator.", 'astra-sites' ) ); } } $url = astra_get_site_data( 'astra-site-latepoint-path' ); try { $content = $this->download_and_validate_import_data( $url, false ); if ( is_wp_error( $content ) ) { Astra_Sites_Helper::error_response( sprintf( // translators: %s is the error message. __( 'LatePoint import failed: %s', 'astra-sites' ), $content->get_error_message() ) ); return; } // Ensure LatePoint plugin is loaded and ready. $loaded = $this->ensure_plugin_loaded( 'latepoint/latepoint.php', 'LatePoint', function() { return class_exists( 'OsSettingsHelper' ); } ); if ( is_wp_error( $loaded ) ) { Astra_Sites_Helper::error_response( $loaded->get_error_message() ); return; } try { OsSettingsHelper::import_data( $content ); Astra_Sites_Importer_Log::add( 'LatePoint data imported successfully', 'success' ); } catch ( \Exception $e ) { Astra_Sites_Helper::error_response( // translators: %s is exception error message. sprintf( __( 'LatePoint import failed: %s', 'astra-sites' ), $e->getMessage() ) ); return; } } catch ( \Exception $e ) { Astra_Sites_Helper::error_response( // translators: %s is exception error message. sprintf( __( 'LatePoint import failed: Unexpected error - %s', 'astra-sites' ), $e->getMessage() ) ); } catch ( \Error $e ) { Astra_Sites_Helper::error_response( // translators: %s: Fatal error message. sprintf( __( 'LatePoint import failed: Fatal Error - %s', 'astra-sites' ), $e->getMessage() ) ); } Astra_Sites_Helper::success_response( // translators: %s is the URL. sprintf( __( 'Imported from %s', 'astra-sites' ), $url ) ); } /** * Verify that all required plugins are installed and activated. * * This is called before import to ensure all plugins are ready. * * @since 4.4.51 * @return void */ public function verify_required_plugins() { // Verify Nonce. check_ajax_referer( 'astra-sites', '_ajax_nonce' ); if ( ! current_user_can( 'activate_plugins' ) ) { wp_send_json_error( array( 'message' => __( 'Permission denied: You do not have permission to verify plugins.', 'astra-sites' ), ) ); return; } // Include plugin.php for is_plugin_active check. if ( ! function_exists( 'is_plugin_active' ) ) { include_once ABSPATH . 'wp-admin/includes/plugin.php'; } // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- JSON data needs to be decoded first. $required_plugins_json = isset( $_POST['required_plugins'] ) ? wp_unslash( $_POST['required_plugins'] ) : ''; $required_plugins = ! empty( $required_plugins_json ) ? json_decode( $required_plugins_json, true ) : array(); if ( empty( $required_plugins ) || ! is_array( $required_plugins ) ) { // No plugins to verify - that's fine. wp_send_json_success( array( 'message' => __( 'No plugins to verify.', 'astra-sites' ), 'verified' => true, ) ); return; } $missing = array(); $not_activated = array(); // Flush the options cache so is_plugin_active() reads the DB rather than // a potentially stale object-cache entry left over from the activation // requests that just completed in separate PHP processes. wp_cache_delete( 'active_plugins', 'options' ); wp_cache_delete( 'alloptions', 'options' ); foreach ( $required_plugins as $plugin ) { if ( ! is_array( $plugin ) || empty( $plugin['init'] ) ) { continue; } $plugin_init = sanitize_text_field( $plugin['init'] ); // Reject path traversal attempts. if ( false !== strpos( $plugin_init, '..' ) || false !== strpos( $plugin_init, '\\' ) ) { Astra_Sites_Importer_Log::add( 'Plugin verification blocked - invalid path: ' . $plugin_init ); continue; } // Check if a pro equivalent of this lite plugin is active. $pro_plugin = Astra_Sites::get_instance()->pro_plugin_exist( $plugin_init ); if ( is_array( $pro_plugin ) && is_plugin_active( $pro_plugin['init'] ) ) { continue; } $plugin_file = WP_PLUGIN_DIR . '/' . $plugin_init; if ( ! file_exists( $plugin_file ) ) { $missing[] = $plugin; Astra_Sites_Importer_Log::add( 'Plugin verification failed - missing: ' . $plugin_init ); } elseif ( ! is_plugin_active( $plugin_init ) ) { $not_activated[] = $plugin; Astra_Sites_Importer_Log::add( 'Plugin verification failed - not activated: ' . $plugin_init ); } } if ( ! empty( $missing ) || ! empty( $not_activated ) ) { Astra_Sites_Importer_Log::add( 'Plugin verification failed. Missing: ' . count( $missing ) . ', Not activated: ' . count( $not_activated ) ); wp_send_json_error( array( 'message' => __( 'Some required plugins are not ready.', 'astra-sites' ), 'missing' => $missing, 'not_activated' => $not_activated, 'verified' => false, ) ); return; } Astra_Sites_Importer_Log::add( 'All required plugins verified successfully.' ); wp_send_json_success( array( 'message' => __( 'All plugins verified.', 'astra-sites' ), 'verified' => true, ) ); } /** * Get single demo. * * @since 1.0.0 * * @param (String) $demo_api_uri API URL of a demo. * * @return (Array) $astra_demo_data demo data for the demo. */ public static function get_single_demo( $demo_api_uri ) { if ( is_int( $demo_api_uri ) ) { $demo_api_uri = Astra_Sites::get_instance()->get_api_url() . 'astra-sites/' . $demo_api_uri; } // default values. $remote_args = array(); $defaults = array( 'id' => '', 'astra-site-widgets-data' => '', 'astra-site-customizer-data' => '', 'astra-site-options-data' => '', 'astra-post-data-mapping' => '', 'astra-site-wxr-path' => '', 'astra-site-wpforms-path' => '', 'astra-site-cartflows-path' => '', 'astra-site-cart-abandonment-recovery-path' => '', 'astra-site-latepoint-path' => '', 'astra-site-surecart-settings' => '', 'astra-enabled-extensions' => '', 'astra-custom-404' => '', 'required-plugins' => '', 'astra-site-taxonomy-mapping' => '', 'license-status' => '', 'site-type' => '', 'astra-site-url' => '', ); $api_args = apply_filters( 'astra_sites_api_args', array( 'timeout' => 15, ) ); // Use this for premium demos. $request_params = apply_filters( 'astra_sites_api_params', array( 'purchase_key' => '', 'site_url' => '', ) ); $demo_api_uri = add_query_arg( $request_params, trailingslashit( $demo_api_uri ) ); // API Call. $response = wp_safe_remote_get( $demo_api_uri, $api_args ); if ( is_wp_error( $response ) || ( isset( $response->status ) && 0 === $response->status ) ) { if ( isset( $response->status ) ) { $data = json_decode( $response, true ); } else { return new WP_Error( 'api_invalid_response_code', $response->get_error_message() ); } } if ( wp_remote_retrieve_response_code( $response ) !== 200 ) { return new WP_Error( 'api_invalid_response_code', wp_remote_retrieve_body( $response ) ); } else { $data = json_decode( wp_remote_retrieve_body( $response ), true ); } $data = json_decode( wp_remote_retrieve_body( $response ), true ); if ( ! isset( $data['code'] ) ) { $remote_args['id'] = $data['id']; $remote_args['astra-site-widgets-data'] = json_decode( $data['astra-site-widgets-data'] ); $remote_args['astra-site-customizer-data'] = $data['astra-site-customizer-data']; $remote_args['astra-site-options-data'] = $data['astra-site-options-data']; $remote_args['astra-post-data-mapping'] = $data['astra-post-data-mapping']; $remote_args['astra-site-wxr-path'] = $data['astra-site-wxr-path']; $remote_args['astra-site-wpforms-path'] = $data['astra-site-wpforms-path']; $remote_args['astra-site-cartflows-path'] = isset( $data['astra-site-cartflows-path'] ) ? $data['astra-site-cartflows-path'] : ''; $remote_args['astra-site-cart-abandonment-recovery-path'] = isset( $data['astra-site-cart-abandonment-recovery-path'] ) ? $data['astra-site-cart-abandonment-recovery-path'] : ''; $remote_args['astra-site-latepoint-path'] = isset( $data['astra-site-latepoint-path'] ) ? $data['astra-site-latepoint-path'] : ''; $remote_args['astra-site-surecart-settings'] = isset( $data['astra-site-surecart-settings'] ) ? $data['astra-site-surecart-settings'] : ''; $remote_args['astra-enabled-extensions'] = $data['astra-enabled-extensions']; $remote_args['astra-custom-404'] = $data['astra-custom-404']; $remote_args['required-plugins'] = $data['required-plugins']; $remote_args['astra-site-taxonomy-mapping'] = $data['astra-site-taxonomy-mapping']; $remote_args['license-status'] = $data['license-status']; $remote_args['site-type'] = $data['astra-site-type']; $remote_args['astra-site-url'] = $data['astra-site-url']; } // Merge remote demo and defaults. return wp_parse_args( $remote_args, $defaults ); } /** * Clear PHP opcode cache for a specific file or entire cache. * * This helps prevent issues where PHP opcode cache serves stale bytecode * after a plugin is freshly installed or updated. * * @since 4.4.47 * * @param string $file_path Optional. Specific file path to invalidate. Default empty (clears entire cache). * @return bool True if cache was cleared, false otherwise. */ private function clear_opcode_cache( $file_path = '' ) { $cleared = false; // Try to reset entire opcode cache if no specific file provided. if ( empty( $file_path ) && function_exists( 'opcache_reset' ) ) { // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.opcache_opcache_reset, PHPCompatibility.FunctionUse.NewFunctions.opcache_resetFound -- Needed to clear entire opcode cache. $cleared = opcache_reset(); } elseif ( ! empty( $file_path ) && function_exists( 'opcache_invalidate' ) ) { // Invalidate specific file from opcode cache. // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.opcache_opcache_invalidate, PHPCompatibility.FunctionUse.NewFunctions.opcache_invalidateFound -- Needed to clear specific file from opcode cache. $cleared = opcache_invalidate( $file_path, true ); } return $cleared; } /** * Ensure a plugin is properly loaded and its classes/functions are available. * * This method handles the complete plugin loading process including verification, * cache clearing, and initialization to prevent timing/race condition issues. * * @since 4.4.47 * * @param string $plugin_file Relative path to plugin file (e.g., 'wpforms-lite/wpforms.php'). * @param string $plugin_name Human-readable plugin name for error messages. * @param callable $is_loaded_callback Callback that returns true if plugin is loaded, false otherwise. * @param string $plugin_main_file Optional. Full path to the main plugin file. If empty, it will be constructed. * * @return bool|WP_Error True if plugin loaded successfully, WP_Error on failure. */ private function ensure_plugin_loaded( $plugin_file, $plugin_name, $is_loaded_callback, $plugin_main_file = '' ) { // Initial verification if plugin is already loaded. Astra_Sites_Importer_Log::add( 'Checking if ' . $plugin_name . ' is already loaded' ); if ( call_user_func( $is_loaded_callback ) ) { Astra_Sites_Importer_Log::add( $plugin_name . ' is already loaded and ready' ); return true; } // Include plugin.php for is_plugin_active check. if ( ! function_exists( 'is_plugin_active' ) ) { include_once ABSPATH . 'wp-admin/includes/plugin.php'; } // Construct full plugin main file path if not provided. if ( empty( $plugin_main_file ) ) { $plugin_main_file = WP_PLUGIN_DIR . '/' . $plugin_file; } // Verify plugin file exists. if ( ! file_exists( $plugin_main_file ) ) { return new WP_Error( 'plugin_files_not_found', sprintf( /* translators: %1$s: Plugin name */ __( '%1$s import failed: Plugin files not found. Please ensure %1$s is properly installed.', 'astra-sites' ), $plugin_name ) ); } // Verify plugin is actually activated. if ( wp_doing_ajax() && ! is_plugin_active( $plugin_file ) ) { return new WP_Error( 'plugin_not_activated', sprintf( /* translators: %1$s: Plugin name */ __( '%1$s import failed: Plugin is installed but not activated. Please activate %1$s and try again.', 'astra-sites' ), $plugin_name ) ); } // Clear opcode cache to prevent stale bytecode. Astra_Sites_Importer_Log::add( 'Clearing opcode cache for ' . $plugin_name ); $this->clear_opcode_cache( $plugin_main_file ); // Force load the plugin. Astra_Sites_Importer_Log::add( 'Manually loading ' . $plugin_name . ' from: ' . $plugin_main_file ); require_once $plugin_main_file; // Trigger WordPress plugin loaded hooks to initialize autoloaders. if ( ! did_action( 'plugins_loaded' ) ) { do_action( 'plugins_loaded' ); } // Wait a moment for autoloaders to register. usleep( 500000 ); // 0.5 second // Final verification that plugin is ready. if ( ! call_user_func( $is_loaded_callback ) ) { return new WP_Error( 'plugin_not_ready', sprintf( /* translators: %s: Plugin name */ __( '%s import failed: Plugin class/functions not available after loading. Please try again or contact support.', 'astra-sites' ), $plugin_name ) ); } // Log success for debugging. astra_sites_error_log( sprintf( '%s successfully loaded after manual initialization.', $plugin_name ) ); return true; } /** * Clear Cache. * * @since 1.0.9 */ public function clear_related_cache() { // Clear 'Builder Builder' cache. if ( is_callable( 'FLBuilderModel::delete_asset_cache_for_all_posts' ) ) { FLBuilderModel::delete_asset_cache_for_all_posts(); Astra_Sites_Importer_Log::add( 'Cache for Beaver Builder cleared.' ); } // Clear 'Astra Addon' cache. if ( is_callable( 'Astra_Minify::refresh_assets' ) ) { Astra_Minify::refresh_assets(); Astra_Sites_Importer_Log::add( 'Cache for Astra Addon cleared.' ); } Astra_Sites_Utils::third_party_cache_plugins_clear_cache(); $this->update_latest_checksums(); // Flush permalinks. flush_rewrite_rules(); //phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.flush_rewrite_rules_flush_rewrite_rules -- This function is called only after import is completed } /** * Update Latest Checksums * * Store latest checksum after batch complete. * * @since 2.0.0 * @return void */ public function update_latest_checksums() { $latest_checksums = get_site_option( 'astra-sites-last-export-checksums-latest', '' ); update_site_option( 'astra-sites-last-export-checksums', $latest_checksums ); } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Importer::get_instance(); } class-astra-sites-elementor-images.php 0000644 00000004064 15252526620 0014063 0 ustar 00 <?php /** * Astra_Sites_Elementor_Images class * * This class is used to manage Pixabay Images. * * @package Astra Sites * @since 2.0.0 */ use Elementor\Utils; // If plugin - 'Elementor' not exist then return. if ( class_exists( 'Astra_Sites_Elementor_Images' ) ) { return; } /** * Astra_Sites_Elementor_Images */ class Astra_Sites_Elementor_Images { /** * Instance of Astra_Sites * * @since 2.0.0 * @var (Object) Astra_Sites */ private static $instance = null; /** * Instance of Astra_Sites_Elementor_Images. * * @since 2.0.0 * * @return object Class object. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Import Image. * * @since 2.0.0 * @param array $image Downloaded Image array. */ public function get_attachment_data( $image ) { if ( ! empty( $image ) ) { \Astra_Sites_Importer_Log::add( 'Getting Elementor attachment data for image ID: ' . $image ); return array( 'content' => array( array( 'id' => \Elementor\Utils::generate_random_string(), 'elType' => 'section', 'settings' => array(), 'isInner' => false, 'elements' => array( array( 'id' => \Elementor\Utils::generate_random_string(), 'elType' => 'column', 'elements' => array( array( 'id' => \Elementor\Utils::generate_random_string(), 'elType' => 'widget', 'settings' => array( 'image' => array( 'url' => wp_get_attachment_url( $image ), 'id' => $image, ), 'image_size' => 'full', ), 'widgetType' => 'image', ), ), 'isInner' => false, ), ), ), ), ); } \Astra_Sites_Importer_Log::add( 'Elementor attachment data skipped - Empty image ID', 'warning' ); return array(); } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Elementor_Images::get_instance(); class-astra-sites-analytics-events.php 0000644 00000007512 15252526620 0014120 0 ustar 00 <?php /** * Analytics Events helper for event tracking. * * Supports both one-time (unique) and repeatable events. * Tracks events temporarily, sends them via BSF Analytics, * then cleans up. For unique events, a minimal deduplicate flag remains. * * @package Starter Templates * @since 4.4.51 */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Astra_Sites_Analytics_Events Class. * * @since 4.4.51 */ class Astra_Sites_Analytics_Events { /** * Option name for pending events queue. * * @var string */ const OPTION_PENDING = 'astra_sites_usage_events_pending'; /** * Option name for pushed (sent) events deduplicate list. * * @var string */ const OPTION_PUSHED = 'astra_sites_usage_events_pushed'; /** * Track an event. By default, unique events are tracked only once. * Pass $unique = false to allow the same event name multiple times. * * @param string $event_name Event identifier. * @param string $event_value Primary value (version, form ID, mode, etc.). * @param array<string, mixed> $properties Additional context as key-value pairs. * @param bool $unique Whether to deduplicate by event_name. Default true. * @since 4.4.51 * @return void */ public static function track( $event_name, $event_value = '', $properties = array(), $unique = true ) { if ( $unique && self::is_tracked( $event_name ) ) { return; } $pending = get_option( self::OPTION_PENDING, array() ); $pending = is_array( $pending ) ? $pending : array(); // Add to pending queue. Store 'unique' flag internally for flush_pending(). $pending[] = array( 'event_name' => sanitize_text_field( $event_name ), 'event_value' => sanitize_text_field( (string) $event_value ), 'properties' => ! empty( $properties ) ? $properties : new \stdClass(), 'date' => current_time( 'mysql' ), ); update_option( self::OPTION_PENDING, $pending ); } /** * Flush pending events: returns them for the payload, then cleans up. * * After this call: * - astra_sites_usage_events_pending is EMPTY (full event data deleted). * - astra_sites_usage_events_pushed has unique event_name strings added (deduplicated). * * @since 4.4.51 * @return array Pending events to include in payload. Empty if none. */ public static function flush_pending() { $pending = get_option( self::OPTION_PENDING, array() ); if ( empty( $pending ) || ! is_array( $pending ) ) { return array(); } // Add all event names to the pushed flag (ensures every event is sent at least once). $unique_event_names = array(); foreach ( $pending as $event ) { if ( ! in_array( $event['event_name'], $unique_event_names, true ) ) { $unique_event_names[] = $event['event_name']; } } if ( ! empty( $unique_event_names ) ) { $pushed = get_option( self::OPTION_PUSHED, array() ); $pushed = is_array( $pushed ) ? $pushed : array(); $pushed = array_unique( array_merge( $pushed, $unique_event_names ) ); update_option( self::OPTION_PUSHED, $pushed ); } // DELETE all temporary event data. update_option( self::OPTION_PENDING, array() ); return $pending; } /** * Check if an event has already been tracked (sent or pending). * * @param string $event_name Event identifier. * @since 4.4.51 * @return bool */ public static function is_tracked( $event_name ) { // Check pushed flag — already sent in a previous cycle. $pushed = get_option( self::OPTION_PUSHED, array() ); $pushed = is_array( $pushed ) ? $pushed : array(); if ( in_array( $event_name, $pushed, true ) ) { return true; } // Check if already queued in current cycle. $pending = get_option( self::OPTION_PENDING, array() ); $pending = is_array( $pending ) ? $pending : array(); return in_array( $event_name, wp_list_pluck( $pending, 'event_name' ), true ); } } class-astra-sites-file-system.php 0000644 00000012474 15252526620 0013073 0 ustar 00 <?php /** * Astra Sites File System * * @since 4.2.0 * @package Astra Sites */ if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! class_exists( 'Astra_Sites_File_System' ) ) { /** * Astra_Sites_File_System */ class Astra_Sites_File_System { /** * Instance of Astra_Sites * * @since 4.2.0 * @var (self) Astra_Sites */ private static $instance = null; /** * Folder name for the json files. * * @var string * @since 4.2.0 */ public static $folder_name = 'json'; /** * Instance of Astra_Sites. * * @since 4.2.0 * @return self Class object. */ public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } /** * Create files for demo content. * * @return void * @since 4.2.0 */ public function create_file() { $upload_dir = wp_upload_dir(); $file = array( 'file_base' => $upload_dir['basedir'] . '/astra-sites/' . self::$folder_name, 'file_name' => 'astra_sites_import_data.json', 'file_content' => array(), ); $this->create_single_file( $file ); } /** * Delete a JSON file from the uploads directory. * * @param string $file_name File name to be deleted. * @return void True on success, false on failure. */ public function delete_json_file( $file_name ) { $file_name = wp_basename( $file_name ); $upload_dir = wp_upload_dir(); $file_name = $upload_dir['basedir'] . '/astra-sites/' . self::$folder_name . '/' . $file_name; if ( file_exists( $file_name ) ) { wp_delete_file( $file_name ); } else { astra_sites_error_log( 'File not found: ' . $file_name ); } } /** * Getting json file for templates from uploads. * * @param string $file_name File data. * @param bool $array_format Is The file content array. * * @return mixed */ public function get_json_file_content( $file_name, $array_format = true ) { $file_name = wp_basename( $file_name ); $upload_dir = wp_upload_dir(); $file_name = $upload_dir['basedir'] . '/astra-sites/' . self::$folder_name . '/' . $file_name; if ( file_exists( $file_name ) ) { // Ignoring the rule as it is not a remote file. $file_content = file_get_contents( $file_name ); //phpcs:ignore WordPressVIPMinimum.Performance.FetchingRemoteData.FileGetContentsUnknown if ( $array_format ) { return json_decode( (string) $file_content, true ); } else { return $file_content; } } return ''; } /** * Getter for get_json_file_content * * @since 4.2.0 * * @return mixed */ public function get_demo_content() { return $this->get_json_file_content( 'astra_sites_import_data.json' ); } /** * Delete for get_json_file_content * * @since 4.2.0 * * @return mixed */ public function delete_demo_content() { $this->delete_json_file( 'astra_sites_import_data.json' ); } /** * Create single json file. * * @since 4.2.2 * @param array<string, mixed> $file file data. * * @return void */ public function create_single_file( $file ) { if ( wp_mkdir_p( $file['file_base'] ) ) { $file_handle = @fopen( trailingslashit( $file['file_base'] ) . $file['file_name'], 'w' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen if ( $file_handle ) { if ( is_string( wp_json_encode( $file['file_content'] ) ) ) { fwrite( $file_handle, wp_json_encode( $file['file_content'] ) ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fwrite, WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_fwrite fclose( $file_handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose astra_sites_error_log( 'File: ' . $file['file_name'] . ' Created Successfully!' ); } } } } /** * Update files/directories. * * @param string $file_name The file name. * @param mixed $file_content The file content. * * @return void */ public function update_json_file( $file_name, $file_content ) { $file_name = wp_basename( $file_name ); $upload_dir = wp_upload_dir(); $dir_info = array( 'path' => $upload_dir['basedir'] . '/astra-sites/' . self::$folder_name . '/', ); if ( ! file_exists( $dir_info['path'] . $file_name ) ) { $file = array( 'file_base' => $dir_info['path'], 'file_name' => $file_name, 'file_content' => '', ); $this->create_single_file( $file ); } if ( file_exists( $dir_info['path'] . $file_name ) && file_put_contents( $dir_info['path'] . $file_name, wp_json_encode( $file_content ) ) !== false ) { //phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_file_put_contents astra_sites_error_log( 'File: ' . $file_name . ' Updated Successfully!' ); } else { astra_sites_error_log( 'File: ' . $file_name . ' Not Updated!' ); } } /** * Setter for update_json_file() * * @param string|int $file_content The file content. * * @return mixed */ public function update_demo_data( $file_content ) { $this->update_json_file( 'astra_sites_import_data.json', $file_content ); } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_File_System::get_instance(); } class-astra-sites-white-label.php 0000644 00000017304 15252526620 0013024 0 ustar 00 <?php /** * Astra Sites White Label * * @package Astra Sites * @since 1.0.12 */ if ( ! class_exists( 'Astra_Sites_White_Label' ) ) : /** * Astra_Sites_White_Label * * @since 1.0.12 */ class Astra_Sites_White_Label { /** * Instance * * @since 1.0.12 * * @var object Class Object. * @access private */ private static $instance; /** * Member Variable * * @since 1.0.12 * * @var array branding * @access private */ private static $branding; /** * Settings * * @since 1.2.11 * * @var array settings * * @access private */ private $settings; /** * Initiator * * @since 1.0.12 * * @return object initialized object of class. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor * * @since 1.0.12 */ public function __construct() { add_filter( 'all_plugins', array( $this, 'plugins_page' ) ); add_filter( 'astra_addon_branding_options', __CLASS__ . '::settings' ); add_action( 'astra_pro_white_label_add_form', __CLASS__ . '::add_white_label_form' ); add_filter( 'astra_sites_menu_page_title', array( $this, 'get_white_label_name' ) ); add_filter( 'astra_sites_page_title', array( $this, 'get_white_label_name' ) ); // Update Astra's admin top level menu position. add_filter( 'astra_menu_priority', array( $this, 'update_admin_menu_position' ) ); // Display the link with the plugin meta. if ( is_admin() ) { add_filter( 'plugin_row_meta', array( $this, 'plugin_links' ), 10, 4 ); } add_filter( 'gutenberg_templates_localize_vars', array( $this, 'add_white_label_name' ) ); add_filter( 'ast_block_templates_white_label', array( $this, 'is_white_labeled' ) ); add_filter( 'ast_block_templates_white_label_name', array( $this, 'get_white_label' ) ); } /** * Update Astra's menu priority to show after Dashboard menu. * * @param int $menu_priority top level menu priority. * @since 3.1.22 */ public function update_admin_menu_position( $menu_priority ) { return 2.1; } /** * Add White Label data * * @param array $args White label. * @since 2.6.0 */ public function add_white_label_name( $args = array() ) { $args['white_label_name'] = $this->get_white_label(); return $args; } /** * White labels the plugins page. * * @since 1.0.12 * * @param array $plugins Plugins Array. * @return array */ public function plugins_page( $plugins ) { if ( ! is_callable( 'Astra_Ext_White_Label_Markup::get_whitelabel_string' ) ) { return $plugins; } if ( ! isset( $plugins[ ASTRA_SITES_BASE ] ) ) { return $plugins; } // Set White Labels. $name = Astra_Ext_White_Label_Markup::get_whitelabel_string( 'astra-sites', 'name' ); $description = Astra_Ext_White_Label_Markup::get_whitelabel_string( 'astra-sites', 'description' ); $author = Astra_Ext_White_Label_Markup::get_whitelabel_string( 'astra-agency', 'author' ); $author_uri = Astra_Ext_White_Label_Markup::get_whitelabel_string( 'astra-agency', 'author_url' ); if ( ! empty( $name ) ) { $plugins[ ASTRA_SITES_BASE ]['Name'] = $name; // Remove Plugin URI if Agency White Label name is set. $plugins[ ASTRA_SITES_BASE ]['PluginURI'] = ''; } if ( ! empty( $description ) ) { $plugins[ ASTRA_SITES_BASE ]['Description'] = $description; } if ( ! empty( $author ) ) { $plugins[ ASTRA_SITES_BASE ]['Author'] = $author; } if ( ! empty( $author_uri ) ) { $plugins[ ASTRA_SITES_BASE ]['AuthorURI'] = $author_uri; } return $plugins; } /** * Get value of single key from option array. * * @since 2.0.0. * @param string $type Option type. * @param string $key Option key. * @param string $default Default value if key not found. * @return mixed Return stored option value. */ public static function get_option( $type = '', $key = '', $default = null ) { if ( ! is_callable( 'Astra_Ext_White_Label_Markup::get_white_label' ) ) { return $default; } $value = Astra_Ext_White_Label_Markup::get_white_label( $type, $key ); if ( ! empty( $value ) ) { return $value; } return $default; } /** * Remove a "view details" link from the plugin list table * * @since 1.0.12 * * @param array $plugin_meta List of links. * @param string $plugin_file Relative path to the main plugin file from the plugins directory. * @param array $plugin_data Data from the plugin headers. * @return array */ public function plugin_links( $plugin_meta, $plugin_file, $plugin_data ) { if ( ! is_callable( 'Astra_Ext_White_Label_Markup::get_whitelabel_string' ) ) { return $plugin_meta; } // Set White Labels. if ( ASTRA_SITES_BASE === $plugin_file ) { $name = Astra_Ext_White_Label_Markup::get_whitelabel_string( 'astra-sites', 'name' ); $description = Astra_Ext_White_Label_Markup::get_whitelabel_string( 'astra-sites', 'description' ); // Remove Plugin URI if Agency White Label name is set. if ( ! empty( $name ) ) { unset( $plugin_meta[2] ); } } return $plugin_meta; } /** * Add White Label setting's * * @since 1.0.12 * * @param array $settings White label setting. * @return array */ public static function settings( $settings = array() ) { $settings['astra-sites'] = array( 'name' => '', 'description' => '', ); return $settings; } /** * Add White Label form * * @since 1.0.12 * * @param array $settings White label setting. * @return void */ public static function add_white_label_form( $settings = array() ) { /* translators: %1$s product name */ $plugin_name = sprintf( __( '%1$s Branding', 'astra-sites' ), ASTRA_SITES_NAME ); require_once ASTRA_SITES_DIR . 'inc/includes/white-label.php'; } /** * Page Title * * @since 1.0.12 * * @param string $title Page Title. * @return string Filtered Page Title. */ public function get_white_label_name( $title = '' ) { if ( is_callable( 'Astra_Ext_White_Label_Markup::get_whitelabel_string' ) ) { $astra_sites_name = Astra_Ext_White_Label_Markup::get_whitelabel_string( 'astra-sites', 'name' ); if ( ! empty( $astra_sites_name ) ) { return Astra_Ext_White_Label_Markup::get_whitelabel_string( 'astra-sites', 'name' ); } } return ASTRA_SITES_NAME; } /** * White Label Link * * @since 2.0.0 * * @param string $link Default link. * @return string Filtered Page Title. */ public function get_white_label_link( $link = '' ) { if ( is_callable( 'Astra_Ext_White_Label_Markup::get_whitelabel_string' ) ) { $white_label_link = Astra_Ext_White_Label_Markup::get_whitelabel_string( 'astra-agency', 'licence' ); if ( ! empty( $white_label_link ) ) { return $white_label_link; } } return $link; } /** * Is Astra sites White labeled * * @since 1.2.13 * * @return string */ public function is_white_labeled() { $white_label = $this->get_white_label(); if ( empty( $white_label ) ) { return false; } return true; } /** * Get white label name * * @since 2.6.0 * * @return string */ public function get_white_label() { if ( ! is_callable( 'Astra_Ext_White_Label_Markup::get_whitelabel_string' ) ) { return ''; } $name = Astra_Ext_White_Label_Markup::get_whitelabel_string( 'astra-sites', 'name' ); if ( ! empty( $name ) ) { return $name; } return ''; } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_White_Label::get_instance(); endif; class-astra-sites-analytics.php 0000644 00000126522 15252526620 0012621 0 ustar 00 <?php /** * Astra Sites Analytics * * @since 4.4.27 * @package Astra Sites */ if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! class_exists( 'Astra_Sites_Analytics' ) ) { /** * Astra_Sites_Analytics */ class Astra_Sites_Analytics { /** * Instance of Astra_Sites_Analytics * * @since 4.4.27 * @var self Astra_Sites_Analytics */ private static $instance = null; /** * Analytics Events instance for tracking one-time milestone events. * * @since 4.5.2 * @var BSF_Analytics_Events */ private static $events; /** * Instance of Astra_Sites_Analytics. * * @since 4.4.27 * * @return self Class object. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor. * * @since 4.4.27 */ private function __construct() { if ( ! class_exists( 'BSF_Analytics_Events' ) ) { require_once ASTRA_SITES_DIR . 'admin/bsf-analytics/class-bsf-analytics-events.php'; } self::$events = new BSF_Analytics_Events( 'astra_sites' ); add_action( 'astra_sites_after_plugin_activation', array( $this, 'update_settings_after_plugin_activation' ), 10, 2 ); add_action( 'admin_init', array( $this, 'maybe_update_finish_setup_banner_clicked' ) ); add_action( 'wp_ajax_astra_sites_set_woopayments_analytics', array( $this, 'set_woopayments_analytics' ) ); add_filter( 'bsf_core_stats', array( $this, 'add_astra_sites_analytics_data' ), 10, 1 ); add_action( 'customize_save_after', array( $this, 'track_astra_customizer_update' ) ); // Track import events for events_record. add_action( 'astra_sites_import_complete', array( $this, 'track_template_imported_event' ) ); add_action( 'ast_block_templates_after_block_import', array( $this, 'track_block_pattern_imported_event' ), 10, 2 ); add_action( 'ast_block_templates_after_kit_import', array( $this, 'track_kit_imported_event' ) ); // Track onboarding step visits. add_action( 'astra_sites_onboarding_step_visited', array( $this, 'track_onboarding_step_visited_event' ) ); // Track content edits for KPI records. add_action( 'save_post', array( $this, 'track_content_edited' ), 10, 2 ); // Track setup/onboarding milestone events. add_action( 'getting_started_action_items_served', array( $this, 'track_finish_setup_initiated_event' ) ); add_action( 'update_option_getting_started_action_items', array( $this, 'track_finish_setup_course_progress_event' ), 10, 2 ); add_action( 'getting_started_setup_wizard_dismissed', array( $this, 'track_finish_setup_dismissed_event' ) ); // Track WooPayments banner dismissal. add_action( 'astra_sites_woopayments_banner_dismissed', array( $this, 'track_woopayments_banner_dismissed_event' ) ); // Track license activation/deactivation events. add_action( 'bsf_activate_license_astra-pro-sites_after_success', array( $this, 'track_license_activated_event' ) ); add_action( 'bsf_deactivate_license_astra-pro-sites_after_success', array( $this, 'track_license_deactivated_event' ) ); // Track plugin version updates (hooked before update class overwrites the version option). add_action( 'astra_sites_update_before', array( $this, 'track_plugin_updated_event' ) ); } /** * Update settings after plugin activation. * * @param string $plugin_init The plugin initialization path. * @param array $data Additional data (optional). * * @since 4.4.27 * @return void */ public function update_settings_after_plugin_activation( $plugin_init, $data = array() ) { // Bail if the plugin slug is not set or empty. if ( ! isset( $data['plugin_slug'] ) || '' === $data['plugin_slug'] ) { return; } // Set WooPayments related settings. $this->maybe_woopayments_included( $plugin_init, $data ); $plugin_slug = $data['plugin_slug']; $required_plugins = Astra_Sites_Page::get_instance()->get_setting( 'required_plugins', array() ); // If the plugin is already activated by starter templates, return early. if ( ( isset( $required_plugins[ $plugin_slug ] ) && 'activated' === $required_plugins[ $plugin_slug ] ) ) { return; } // If required plugins is not an array, initialize it. if ( ! is_array( $required_plugins ) ) { $required_plugins = array(); } // Set the plugin activation status and update in settings. $required_plugins[ $plugin_slug ] = isset( $data['was_plugin_active'] ) && $data['was_plugin_active'] ? 'was_active' : 'activated'; Astra_Sites_Page::get_instance()->update_settings( array( 'required_plugins' => $required_plugins, ) ); } /** * Maybe update finish setup banner clicked. * * @since 4.4.37 * @return void */ public function maybe_update_finish_setup_banner_clicked() { // Only allow administrators to update this setting. if ( ! current_user_can( 'manage_options' ) ) { return; } // Bail early if the source is not dashboard-banner. // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification not needed here. if ( ! isset( $_GET['source'] ) || 'dashboard-banner' !== sanitize_text_field( $_GET['source'] ) ) { return; } // Update the finish setup banner clicked setting. Astra_Sites_Page::get_instance()->update_settings( array( 'fs_banner_clicked' => 'yes', ) ); // Track as a one-time event. self::$events->track( 'finish_setup_banner_clicked', ASTRA_SITES_VER ); } /** * Check if WooCommerce Payments plugin is included and update settings accordingly. * * @param string $plugin_init The plugin initialization path. * @param array $data Additional data (optional). * * @since 4.4.23 * @return void */ public function maybe_woopayments_included( $plugin_init, $data = array() ) { if ( 'woocommerce-payments/woocommerce-payments.php' === $plugin_init ) { // Prevent showing the banner if plugin was already active. if ( ! isset( $data['was_plugin_active'] ) || ! $data['was_plugin_active'] ) { Astra_Sites_Page::get_instance()->update_settings( array( 'woopayments_ref' => true, 'wcpay_referred_time' => time(), ) ); } Astra_Sites_Page::get_instance()->update_settings( array( 'woopayments_included' => true, ) ); } } /** * Set WooPayments analytics. * * @since 4.4.23 * @return void */ public function set_woopayments_analytics() { // Verify user has permission to modify settings. if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'astra-sites' ) ) ); exit; } // Verify nonce. if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'woopayments_nonce' ) ) { wp_send_json_error( array( 'message' => __( 'Invalid nonce', 'astra-sites' ) ) ); exit; } $source = isset( $_POST['source'] ) ? sanitize_text_field( wp_unslash( $_POST['source'] ) ) : ''; if ( ! in_array( $source, array( 'banner', 'onboarding' ), true ) ) { wp_send_json_error( array( 'message' => __( 'Invalid source', 'astra-sites' ) ) ); exit; } $key = "woopayments_{$source}_clicked"; Astra_Sites_Page::get_instance()->update_settings( array( $key => true ) ); // Track as a one-time event. self::$events->track( $key, ASTRA_SITES_VER, array( 'source' => $source ) ); wp_send_json_success( array( 'message' => 'WooPayments analytics updated!' ) ); exit; } /** * Track when a full template import completes. * * @param array $demo_data Demo data from the import. * * @since 4.4.51 * @return void */ public function track_template_imported_event( $demo_data = array() ) { $required_plugins = Astra_Sites_Page::get_instance()->get_setting( 'required_plugins', array() ); $properties = array( 'template_id' => ! empty( $demo_data['id'] ) ? $demo_data['id'] : '', 'template_url' => ! empty( $demo_data['astra-site-url'] ) ? $demo_data['astra-site-url'] : '', 'title' => ! empty( $demo_data['title']['rendered'] ) ? sanitize_text_field( $demo_data['title']['rendered'] ) : '', 'site_type' => ! empty( $demo_data['astra-site-type'] ) ? $demo_data['astra-site-type'] : '', 'page_builder' => Astra_Sites_Page::get_instance()->get_setting( 'page_builder' ), 'plugins' => is_array( $required_plugins ) && ! empty( $required_plugins ) ? $required_plugins : array(), ); self::$events->track( 'template_imported', ASTRA_SITES_VER, $properties ); // Store timestamp for KPI records. $this->store_kpi_timestamp( 'template' ); } /** * Track when a block pattern is imported. * * @param int $block_id The ID of the imported block. * @param string $type The type of pattern (e.g., 'block', 'page'). * * @since 4.4.51 * @return void */ public function track_block_pattern_imported_event( $block_id, $type ) { $properties = array( 'block_id' => $block_id, 'type' => $type, ); self::$events->track( 'block_pattern_imported', ASTRA_SITES_VER, $properties ); // Store timestamp for KPI records — $type is 'block' or 'page'. $this->store_kpi_timestamp( $type ); } /** * Track when a template kit is imported. * * @since 4.4.51 * @return void */ public function track_kit_imported_event() { self::$events->track( 'kit_imported', ASTRA_SITES_VER ); // Store timestamp for KPI records. $this->store_kpi_timestamp( 'kit' ); } /** * Track cumulative onboarding steps visited state. * * Reads all visited steps from settings and retracks with full state. * Uses track() with $force=true so the server always has the latest cumulative snapshot. * * @param string $step The step identifier (e.g. 'welcome', 'template-listing'). * * @since 4.5.2 * @return void */ public function track_onboarding_step_visited_event( $step ) { // Get all visited steps from settings (cumulative state). $steps_visited = Astra_Sites_Page::get_instance()->get_setting( 'steps_visited' ); $steps_visited = is_array( $steps_visited ) ? $steps_visited : array(); // Build properties map: each step as key with its status (yes/skipped). $properties = array(); foreach ( $steps_visited as $visited_step => $status ) { $properties[ sanitize_key( $visited_step ) ] = $status; } // Replace any existing pending/pushed entry with updated state. self::$events->track( 'onboarding_step_visited', ASTRA_SITES_VER, $properties, true ); } /** * Store a timestamp for KPI tracking. * * @param string $type The type of import ('template', 'block', 'page', 'kit', 'content_edited'). * * @since 4.4.51 * @return void */ private function store_kpi_timestamp( $type ) { $timestamps = Astra_Sites_Page::get_instance()->get_setting( '_import_timestamps', array() ); if ( ! is_array( $timestamps ) ) { $timestamps = array(); } $bucket_map = array( 'template' => 'templates', 'kit' => 'kits', 'content_edited' => 'content_edited', ); $bucket = isset( $bucket_map[ $type ] ) ? $bucket_map[ $type ] : 'block_patterns'; if ( ! isset( $timestamps[ $bucket ] ) || ! is_array( $timestamps[ $bucket ] ) ) { $timestamps[ $bucket ] = array(); } $timestamps[ $bucket ][] = time(); Astra_Sites_Page::get_instance()->update_settings( array( '_import_timestamps' => $timestamps ) ); } /** * Track when a post, page, or CPT is added or edited. * * Stores a timestamp in the 'content_edited' bucket for KPI tracking. * Skips auto-saves, revisions, and non-public post types. * * @param int $post_id The post ID. * @param \WP_Post $post The post object. * * @since 4.4.51 * @return void */ public function track_content_edited( $post_id, $post ) { if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; } if ( wp_is_post_revision( $post_id ) ) { return; } $post_type_obj = get_post_type_object( $post->post_type ); if ( ! $post_type_obj || ! $post_type_obj->public ) { return; } $this->store_kpi_timestamp( 'content_edited' ); } /** * Track Astra Customizer updates after template import. * * This method tracks when users modify Astra Customizer settings after * a successful template import. It only tracks once per user to avoid * repeated logging on every save. * * @since 4.4.47 * @return void */ public function track_astra_customizer_update() { // Only track if import has been completed. $import_complete = get_option( 'astra_sites_import_complete', 'no' ); if ( 'yes' !== $import_complete ) { return; } // Check if we've already tracked this (one-time tracking). $already_tracked = Astra_Sites_Page::get_instance()->get_setting( 'astra_customizer_updated', false ); if ( $already_tracked ) { return; } // Get the current theme to ensure this is Astra-related. $current_theme = get_stylesheet(); if ( 0 !== strpos( $current_theme, 'astra' ) ) { return; } // Mark as tracked to ensure one-time logging. Astra_Sites_Page::get_instance()->update_settings( array( 'astra_customizer_updated' => true, ) ); } /** * Track cumulative course progress state (done / not_done per course). * * Fires on `update_option_getting_started_action_items`. Compares old vs new * to detect status changes, then retracks with full state of all courses. * Uses track() with $force=true so the server always has the latest cumulative snapshot. * * @param mixed $old_value The old option value. * @param mixed $new_value The new option value. * * @since 4.5.2 * @return void */ public function track_finish_setup_course_progress_event( $old_value, $new_value ) { if ( ! is_array( $new_value ) || empty( $new_value ) ) { return; } $old_value = is_array( $old_value ) ? $old_value : array(); // Check if any course status actually changed. $has_change = false; foreach ( $new_value as $key => $action_item ) { $is_done = ! empty( $action_item['status'] ); $was_done = isset( $old_value[ $key ] ) && ! empty( $old_value[ $key ]['status'] ); if ( $is_done !== $was_done ) { $has_change = true; break; } } if ( ! $has_change ) { return; } // Get full course list from default action items. if ( ! class_exists( '\GS\Classes\GS_Helper' ) ) { return; } $all_courses = \GS\Classes\GS_Helper::get_default_action_items(); if ( ! is_array( $all_courses ) || empty( $all_courses ) ) { return; } // Build properties map from full course list, checking status in DB state. $properties = array(); $all_complete = true; foreach ( $all_courses as $course ) { $course_id = isset( $course['id'] ) ? $course['id'] : ''; if ( empty( $course_id ) ) { continue; } $is_done = isset( $new_value[ $course_id ] ) && ! empty( $new_value[ $course_id ]['status'] ); $properties[ sanitize_key( $course_id ) ] = $is_done ? 'completed' : 'pending'; if ( ! $is_done ) { $all_complete = false; } } $event_value = $all_complete ? 'completed' : 'in_progress'; // Replace any existing pending/pushed entry with updated state. self::$events->track( 'finish_setup_course_progress', $event_value, $properties, true ); } /** * Track when the finish setup wizard is dismissed. * * @since 4.5.2 * @return void */ public function track_finish_setup_dismissed_event() { self::$events->track( 'finish_setup_dismissed', ASTRA_SITES_VER ); } /** * Track when the WooPayments banner is dismissed. * Non-unique so each dismissal is counted separately. * * @since 4.5.2 * @return void */ public function track_woopayments_banner_dismissed_event() { self::$events->track( 'woopayments_banner_dismissed', ASTRA_SITES_VER, array(), false ); } /** * Track finish setup initiated when courses are first served to the user. * Dedup ensures this fires only once even if the endpoint is called multiple times. * * @param array $action_items The action items being served. * * @since 4.5.2 * @return void */ public function track_finish_setup_initiated_event( $action_items ) { if ( empty( $action_items ) || ! is_array( $action_items ) ) { return; } $course_names = array(); foreach ( $action_items as $action_item ) { if ( ! empty( $action_item['id'] ) ) { $course_names[] = sanitize_key( $action_item['id'] ); } } if ( empty( $course_names ) ) { return; } self::$events->track( 'finish_setup_initiated', ASTRA_SITES_VER, array( 'courses' => $course_names, ) ); } /** * Track when the product license is activated. * * @since 4.5.2 * @return void */ public function track_license_activated_event() { self::$events->track( 'license_activated', ASTRA_SITES_VER ); } /** * Track when the product license is deactivated. * * @since 4.5.2 * @return void */ public function track_license_deactivated_event() { self::$events->track( 'license_deactivated', ASTRA_SITES_VER ); } /** * Track plugin version updates. * * Fires on `astra_sites_update_before` — before the update class * overwrites `astra-sites-auto-version` with the new version. * Uses track() with $force=true so each version transition is tracked. * * @since 4.5.2 * @return void */ public function track_plugin_updated_event() { $old_version = get_option( 'astra-sites-auto-version', '' ); if ( empty( $old_version ) || version_compare( $old_version, ASTRA_SITES_VER, '>=' ) ) { return; } self::$events->track( 'plugin_updated', ASTRA_SITES_VER, array( 'from_version' => $old_version, ), true ); } /** * Detect state-based milestone events from already-computed stats. * Dedup in BSF_Analytics_Events::track() ensures each fires only once. * * @since 4.5.2 * @return void */ private function detect_state_events() { // plugin_activated: track once with install source and time-to-value. $referer_key = defined( 'BSF_UTM_ANALYTICS_REFERER' ) ? BSF_UTM_ANALYTICS_REFERER : 'bsf_product_referers'; $bsf_referrers = get_option( $referer_key, array() ); $source = ! empty( $bsf_referrers['astra-sites'] ) ? $bsf_referrers['astra-sites'] : 'self'; $is_pro = defined( 'ASTRA_PRO_SITES_NAME' ); $install_time = get_option( 'astra_sites_usage_installed_time', 0 ); $days_since_install = 0; if ( $install_time > 0 ) { $days_since_install = (int) floor( ( time() - $install_time ) / DAY_IN_SECONDS ); } self::$events->track( 'plugin_activated', ASTRA_SITES_VER, array( 'source' => $source, 'is_pro' => $is_pro ? 'yes' : 'no', 'days_since_install' => (string) $days_since_install, ) ); // woopayments_referred: track once if WooPayments was newly activated via template. if ( get_option( 'astra_sites_import_complete', 'no' ) === 'yes' && Astra_Sites_Page::get_instance()->get_setting( 'woopayments_ref' ) ) { self::$events->track( 'woopayments_referred', ASTRA_SITES_VER ); } } /** * Check if WooPayments is configured and connected to Stripe. * * @since 4.4.24 * @return bool True if WooPayments is active and connected to Stripe, false otherwise. */ public static function is_woo_payments_configured() { // Check if WCPay account is connected to Stripe. if ( class_exists( 'WC_Payments' ) && method_exists( 'WC_Payments', 'get_account_service' ) ) { $account_service = WC_Payments::get_account_service(); if ( method_exists( $account_service, 'is_stripe_connected' ) && $account_service->is_stripe_connected() ) { self::$events->track( 'woopayments_configured', ASTRA_SITES_VER ); return true; } } return false; } /** * Checks if WooPayments has processed at least one transaction. * * @since 4.4.34 * @return bool True if WooPayments has transactions, false otherwise. */ private static function has_woopayments_successful_transaction() { // Check if WooPayments plugin is active. if ( ! is_plugin_active( 'woocommerce-payments/woocommerce-payments.php' ) ) { return false; } // Check if WooCommerce is active (required for WooPayments). if ( ! is_plugin_active( 'woocommerce/woocommerce.php' ) || ! function_exists( 'wc_get_orders' ) ) { return false; } // Get the timestamp after which to check for transactions. $after_timestamp = Astra_Sites_Page::get_instance()->get_setting( 'wcpay_referred_time', 0 ); // Use WooCommerce's built-in order query system to support both legacy and HPOS storage. $orders = wc_get_orders( array( 'payment_method' => 'woocommerce_payments', 'status' => array( 'completed', 'processing', 'on-hold' ), 'limit' => 1, 'date_after' => intval( $after_timestamp ), 'meta_query' => array( //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Required for analytics and run in background. array( 'key' => '_wcpay_payment_transaction_id', 'value' => '', 'compare' => '!=', ), ), ) ); if ( ! empty( $orders ) ) { self::$events->track( 'woopayments_transaction_completed', ASTRA_SITES_VER ); return true; } return false; } /** * Get all posts that have been imported and not modified since import. * * These are posts that were imported via Starter Templates and haven't been * edited by the user since import (within a 3-minute buffer for background processing). * * @param string $post_type The post type to check. Default is 'any'. * * @since 4.4.33 * @return array Post IDs that have not been modified since their import. */ private static function get_unmodified_imported_post_ids( $post_type = 'any' ) { // Get all posts that have been imported. $args = array( 'post_type' => $post_type, 'post_status' => 'publish', 'posts_per_page' => -1, 'meta_query' => array( //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Required for analytics and run in background. array( 'key' => '_astra_sites_imported_post', 'value' => '1', 'compare' => '=', ), ), ); $posts = get_posts( $args ); // Get all post IDs that have not been modified since their import. return array_reduce( $posts, function ( $carry, $post ) { $post_date = strtotime( $post->post_date ); $modified_date = strtotime( $post->post_modified ); // Check if modified time is within 3 minutes (180 seconds) of post date. 3 mins buffer for background post processing. if ( abs( $modified_date - $post_date ) <= 180 ) { $carry[] = $post->ID; } return $carry; }, array() ); } /** * Check if any user-engaged posts exist for a given post type. * * "User-engaged" means either: * - Posts created by the user (not imported). * - Imported posts that have been modified by the user since import. * * @param string $post_type The post type to check. * @param array $args Optional arguments for WP_Query. * * @since 4.4.33 * @return bool True if any qualifying posts exist, false otherwise. */ private static function has_user_engaged_posts_of_type( $post_type = 'any', $args = array() ) { // If post type is not 'any', ensure it exists. if ( 'any' !== $post_type && ! post_type_exists( $post_type ) ) { return false; } // Merge default arguments with provided ones. $args = array_merge( array( 'post_type' => $post_type, 'post_status' => 'publish', 'fields' => 'ids', 'numberposts' => 1, ), $args ); // Exclude post__not_in if already set. if ( ! isset( $args['post__not_in'] ) ) { // Exclude posts that have been imported and not modified since import. $excluded_post_ids = self::get_unmodified_imported_post_ids( $post_type ); if ( ! empty( $excluded_post_ids ) ) { $args['post__not_in'] = $excluded_post_ids; } } $query = new \WP_Query( $args ); $found = $query->have_posts(); wp_reset_postdata(); return $found; } /** * Checks if Astra Customizer has been updated after template import. * * ACTIVE CONDITION: * - Astra theme is active. * - User modified Astra Customizer settings after template import. * * @since 4.4.47 * @return bool True if Astra Customizer was updated post-import, false otherwise. */ public static function is_astra_customizer_updated() { // Verify Astra theme is still active. $current_theme = get_stylesheet(); if ( 0 !== strpos( $current_theme, 'astra' ) ) { return false; } // Check if the setting has been tracked. $customizer_updated = (bool) Astra_Sites_Page::get_instance()->get_setting( 'astra_customizer_updated', false ); if ( ! $customizer_updated ) { return false; } return true; } /** * Checks if any Spectra block is used on the site. * * ACTIVE CONDITION: * - Imported post/page is updated, published and has at least one Spectra block. * - New post/page is published and has at least one Spectra block. * * @since 4.4.27 * * @return bool */ public static function is_spectra_blocks_used() { if ( ! is_plugin_active( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ) ) { return false; } // Check for Spectra v2 blocks (wp:uagb/). $has_spectra_v2_blocks = self::has_user_engaged_posts_of_type( 'any', array( 's' => '<!-- wp:uagb/' ) ); if ( $has_spectra_v2_blocks ) { return true; } // Check for Spectra v3 blocks (wp:spectra/). return self::has_user_engaged_posts_of_type( 'any', array( 's' => '<!-- wp:spectra/' ) ); } /** * Checks if any UAE Header Footer Layout is published or any UAE widget is used on the site. * * ACTIVE CONDITION: * - Imported header footer post is updated, published. * - New header footer post is published. * * @since 4.4.27 * * @return bool */ public static function is_uae_widgets_used() { if ( ! is_plugin_active( 'header-footer-elementor/header-footer-elementor.php' ) ) { return false; } // Check for user-engaged elementor-hf posts. if ( self::has_user_engaged_posts_of_type( 'elementor-hf' ) ) { return true; } // Check UAE widget usage data (fallback for older detection method). $uae_used_widgets = get_option( 'uae_widgets_usage_data_option', array() ); if ( is_array( $uae_used_widgets ) && ! empty( $uae_used_widgets ) ) { return true; } return false; } /** * Checks if any SureForms form is published. * * ACTIVE CONDITION: * - Imported form is updated and published. * - New form is published. * * @since 4.4.27 * * @return bool */ public static function is_sureforms_form_published() { return self::has_user_engaged_posts_of_type( 'sureforms_form' ); } /** * Checks if SureMail has at least one connection configured. * * ACTIVE CONDITION: SureMails is connected. * * @since 4.4.27 * * @return bool */ public static function is_suremails_connected() { if ( ! is_plugin_active( 'suremails/suremails.php' ) ) { return false; } // Get SureMails connections from options. $suremails_connections_option = defined( 'SUREMAILS_CONNECTIONS' ) ? SUREMAILS_CONNECTIONS : 'suremails_connections'; $suremails_connections = get_option( $suremails_connections_option, array() ); if ( is_array( $suremails_connections ) && isset( $suremails_connections['connections'] ) && ! empty( $suremails_connections['connections'] ) ) { return true; } return false; } /** * Checks if SureCart has any published product. * * ACTIVE CONDITION: * - Imported SureCart product is updated and published. * - New SureCart product is published. * * @since 4.4.27 * * @return bool */ public static function is_surecart_product_published() { return self::has_user_engaged_posts_of_type( 'sc_product' ); } /** * Checks if CartFlows has any published funnel. * * ACTIVE CONDITION: * - Imported funnel is updated and published. * - New funnel is published. * * @since 4.4.27 * * @return bool */ public static function is_cartflows_funnel_published() { return self::has_user_engaged_posts_of_type( 'cartflows_flow' ); } /** * Checks if LatePoint activities are made by admin or appointment created by users. * * ACTIVE CONDITION: Any activity is made by admin or appointment created by users. * * @since 4.4.27 * * @return bool */ public static function is_latepoint_booking_managed() { if ( ! is_plugin_active( 'latepoint/latepoint.php' ) ) { return false; } global $wpdb; $latepoint_activities_table = defined( 'LATEPOINT_TABLE_ACTIVITIES' ) ? LATEPOINT_TABLE_ACTIVITIES : $wpdb->prefix . 'latepoint_activities'; // Table names can't be parameterized in wpdb::prepare(), safe to ignore PHPCS here. // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $count = $wpdb->get_var( "SELECT COUNT(*) FROM {$latepoint_activities_table}" ); return $count > 0; } /** * Checks if a Presto Player video is embedded on the site. * * ACTIVE CONDITION: Presto Player block/shortcode used on any post/page * * @since 4.4.27 * * @return bool */ public static function is_presto_player_used() { if ( ! is_plugin_active( 'presto-player/presto-player.php' ) ) { return false; } // Exclude 'pp_video_block' post type to avoid false positives. $args = array( 'post_type' => array_diff( get_post_types( array( 'public' => true ), 'names' ), array( 'pp_video_block' ) ), 'posts__not_in' => array(), // To search in all posts including imported ones. 's' => '<!-- /wp:presto-player', ); // Check for Presto Player block in posts. $is_presto_player_block_used = self::has_user_engaged_posts_of_type( 'any', $args ); if ( $is_presto_player_block_used ) { return true; } // Check for Presto Player shortcode in posts. $args['s'] = '[presto_player id='; return self::has_user_engaged_posts_of_type( 'any', $args ); } /** * Checks if SureRank optimization is done on any post or 3+ site level SEO settings. * * ACTIVE CONDITION: * - Optimization of any pages/posts (update SureRank meta, etc. of any posts/pages) * - Optimize 3+ things in "site level" SEO settings (change configuration of 3 things from default values) * * @since 4.4.39 * * @return bool True if optimization is done on any post or 3+ site level SEO settings, false otherwise. */ public static function is_surerank_optimization_done() { if ( ! defined( 'SURERANK_VERSION' ) || ! is_plugin_active( 'surerank/surerank.php' ) ) { return false; } // Check if 3 or more site-level settings are changed from default. if ( is_callable( '\SureRank\Inc\Functions\Defaults::get_instance' ) ) { $key = defined( 'SURERANK_SETTINGS' ) ? SURERANK_SETTINGS : 'surerank_settings'; $surerank_defaults = \SureRank\Inc\Functions\Defaults::get_instance()->get_global_defaults(); $surerank_settings = get_option( $key, array() ); if ( is_array( $surerank_settings ) && is_array( $surerank_defaults ) ) { $changed_settings = self::shallow_two_level_diff( $surerank_settings, $surerank_defaults ); if ( count( $changed_settings ) >= 3 ) { return true; } } } global $wpdb; // Use direct SQL with IN() for multiple meta keys instead of WP_Query to avoid heavy JOINs and improve performance. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $posts = $wpdb->get_col( $wpdb->prepare( " SELECT DISTINCT pm.post_id FROM {$wpdb->postmeta} pm INNER JOIN {$wpdb->posts} p ON pm.post_id = p.ID WHERE pm.meta_key IN (%s, %s, %s, %s, %s, %s) AND p.post_status = 'publish' LIMIT 1 ", 'surerank_settings_general', 'surerank_settings_schemas', 'surerank_settings_social', 'surerank_settings_post_no_index', 'surerank_settings_post_no_follow', 'surerank_settings_post_no_archive' ) ); return count( $posts ) >= 1; } /** * Checks if ModernCart is enabled. * * ACTIVE CONDITION: Modern Cart setting is enabled. * * @since 4.4.41 * * @return bool True if ModernCart is enabled, false otherwise. */ public static function is_modern_cart_enabled() { if ( ! defined( 'MODERNCART_VER' ) || ! is_plugin_active( 'modern-cart/modern-cart.php' ) ) { return false; } $option_name = defined( 'MODERNCART_MAIN_SETTINGS' ) ? MODERNCART_MAIN_SETTINGS : 'moderncart_settings'; $settings = get_option( $option_name, array() ); if ( ! is_array( $settings ) || ! isset( $settings['enable_moderncart'] ) ) { return true; // Default is set to `all` which indicates that Modern Cart is enabled everywhere. } // Check if Modern Cart is enabled on WooCommerce pages or everywhere. return 'wc_pages' === $settings['enable_moderncart'] || 'all' === $settings['enable_moderncart']; } /** * Add required plugins analytics data. * * @param array $stats Stats array. * * @since 4.4.27 * @return void */ private static function add_required_plugins_analytics( &$stats ) { $required_plugins = Astra_Sites_Page::get_instance()->get_setting( 'required_plugins', array() ); if ( ! is_array( $required_plugins ) ) { return; } $stats['plugins_data'] = ! empty( $required_plugins ) ? wp_json_encode( $required_plugins ) : ''; } /** * Add plugin active analytics data. * * @param array $stats Stats array. * * @since 4.4.27 * @return void */ private static function add_plugin_active_analytics( &$stats ) { $stats = array_merge( $stats, array( 'astra_customizer_updated' => self::is_astra_customizer_updated(), 'spectra_blocks_used' => self::is_spectra_blocks_used(), 'uae_widgets_used' => self::is_uae_widgets_used(), 'sureforms_form_published' => self::is_sureforms_form_published(), 'suremails_connected' => self::is_suremails_connected(), 'surecart_product_published' => self::is_surecart_product_published(), 'cartflows_funnel_published' => self::is_cartflows_funnel_published(), 'latepoint_booking_managed' => self::is_latepoint_booking_managed(), 'presto_player_used' => self::is_presto_player_used(), 'surerank_optimization_done' => self::is_surerank_optimization_done(), 'modern_cart_enabled' => self::is_modern_cart_enabled(), ) ); } /** * Add finish setup analytics data. * * @param array $stats Stats array. * * @since 4.4.28 * @return void */ private static function add_finish_setup_analytics( &$stats ) { // Get setup wizard showing option name. $option_name = class_exists( '\GS\Classes\GS_Helper' ) ? \GS\Classes\GS_Helper::get_setup_wizard_showing_option_name() : 'getting_started_is_setup_wizard_showing'; $is_setup_wizard_showing = get_option( $option_name, false ); $action_items_status = get_option( 'getting_started_action_items', array() ); $fs_banner_clicked = (string) Astra_Sites_Page::get_instance()->get_setting( 'fs_banner_clicked', '' ); $courses_status = array(); $no_of_completed_courses = 0; // Get the courses status from action items. if ( is_array( $action_items_status ) ) { foreach ( $action_items_status as $key => $action_item ) { $status = isset( $action_item['status'] ) ? $action_item['status'] : false; $courses_status[ $key ] = $status ? 'done' : 'not_done'; if ( $status ) { $no_of_completed_courses++; } } } // Total number of courses. $total_courses = count( $courses_status ); // Boolean and numeric values. $stats['boolean_values']['is_finish_setup_showing'] = $is_setup_wizard_showing; $stats['numeric_values']['total_courses'] = $total_courses; $stats['numeric_values']['no_of_completed_courses'] = $no_of_completed_courses; $stats['boolean_values']['course_completed'] = 0 !== $total_courses && $no_of_completed_courses >= $total_courses; // Dashboard banner clicked. if ( $fs_banner_clicked ) { $stats['boolean_values']['finish_setup_banner_clicked'] = 'yes' === $fs_banner_clicked; } // Plain Json data. $stats['courses_status'] = ! empty( $courses_status ) ? wp_json_encode( $courses_status ) : ''; } /** * Add KPI tracking data for import events. * * Groups stored timestamps by date, counts per metric per day, * skips today's (incomplete) data, and cleans up sent timestamps. * * @param array $stats Reference to the astra sites stats data. * @since 4.4.51 * @return void */ public static function add_kpi_tracking_data( &$stats ) { $timestamps = Astra_Sites_Page::get_instance()->get_setting( '_import_timestamps', array() ); if ( empty( $timestamps ) || ! is_array( $timestamps ) ) { return; } $kpi_data = array(); // Mapping: option key => KPI metric name. $metric_map = array( 'templates' => 'templates_imported', 'block_patterns' => 'block_patterns_imported', 'kits' => 'kits_imported', 'content_edited' => 'post_content_edited', ); $remaining_timestamps = array(); foreach ( $metric_map as $bucket => $metric_name ) { if ( empty( $timestamps[ $bucket ] ) || ! is_array( $timestamps[ $bucket ] ) ) { continue; } $result = self::process_kpi_bucket( $timestamps[ $bucket ], $metric_name, $kpi_data ); $kpi_data = $result['kpi_data']; $remaining_timestamps[ $bucket ] = $result['remaining']; } // Only add to stats if we have data to report. if ( ! empty( $kpi_data ) ) { $stats['kpi_records'] = $kpi_data; } // Cleanup: keep only today's timestamps. $remaining_timestamps = array_filter( $remaining_timestamps ); Astra_Sites_Page::get_instance()->update_settings( array( '_import_timestamps' => $remaining_timestamps ) ); } /** * Process a single bucket of timestamps for KPI reporting. * * @param array $bucket_timestamps Array of Unix timestamps. * @param string $metric_name The KPI metric name. * @param array $kpi_data Existing KPI data to merge into. * * @since 4.4.51 * @return array { kpi_data: array, remaining: array } */ private static function process_kpi_bucket( $bucket_timestamps, $metric_name, $kpi_data ) { $today = gmdate( 'Y-m-d' ); $remaining = array(); foreach ( $bucket_timestamps as $timestamp ) { if ( ! is_numeric( $timestamp ) ) { continue; } $date = gmdate( 'Y-m-d', (int) $timestamp ); // Keep today's timestamps — incomplete day, skip from reporting. if ( $date === $today ) { $remaining[] = $timestamp; continue; } if ( ! isset( $kpi_data[ $date ] ) ) { $kpi_data[ $date ] = array( 'numeric_values' => array() ); } if ( ! isset( $kpi_data[ $date ]['numeric_values'][ $metric_name ] ) ) { $kpi_data[ $date ]['numeric_values'][ $metric_name ] = 0; } $kpi_data[ $date ]['numeric_values'][ $metric_name ]++; } return array( 'kpi_data' => $kpi_data, 'remaining' => $remaining, ); } /** * Add astra sites analytics data. * * @param array $stats stats array. * * @since 4.4.27 * @return array */ public function add_astra_sites_analytics_data( $stats ) { // Load the plugin.php file to use is_plugin_active function. if ( ! function_exists( 'is_plugin_active' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $import_complete = get_option( 'astra_sites_import_complete', 'no' ) === 'yes'; $stats['plugin_data']['astra_sites'] = array( 'version' => defined( 'ASTRA_PRO_SITES_NAME' ) ? 'premium' : 'free', 'site_language' => get_locale(), 'plugin_version' => ASTRA_SITES_VER, 'page_builder' => Astra_Sites_Page::get_instance()->get_setting( 'page_builder' ), 'boolean_values' => array( 'import_complete' => $import_complete, 'woopayments_included' => Astra_Sites_Page::get_instance()->get_setting( 'woopayments_included' ), 'was_woopayments_referred' => Astra_Sites_Page::get_instance()->get_setting( 'woopayments_ref' ), 'woopayments_banner_clicked' => Astra_Sites_Page::get_instance()->get_setting( 'woopayments_banner_clicked' ), 'woopayments_onboarding_clicked' => Astra_Sites_Page::get_instance()->get_setting( 'woopayments_onboarding_clicked' ), 'woopayments_configured' => self::is_woo_payments_configured(), 'has_woopayments_transaction' => self::has_woopayments_successful_transaction(), ), 'numeric_values' => array( 'woopayments_banner_dismissed_count' => Astra_Sites_Page::get_instance()->get_setting( 'woopayments_banner_dismissed_count' ), ), 'steps_visited' => Astra_Sites_Page::get_instance()->get_setting( 'steps_visited' ), ); if ( $import_complete ) { self::add_required_plugins_analytics( $stats['plugin_data']['astra_sites'] ); self::add_plugin_active_analytics( $stats['plugin_data']['astra_sites']['boolean_values'] ); self::add_finish_setup_analytics( $stats['plugin_data']['astra_sites'] ); } // Add KPI tracking data. self::add_kpi_tracking_data( $stats['plugin_data']['astra_sites'] ); // Detect state-based milestone events (dedup in track() ensures each fires only once). $this->detect_state_events(); // Flush pending events into payload (only if any exist). $pending_events = self::$events->flush_pending(); if ( ! empty( $pending_events ) ) { $stats['plugin_data']['astra_sites']['events_record'] = $pending_events; } return $stats; } /** * Compare top-level and one-level nested settings with defaults. * * @param array $settings Current settings. * @param array $defaults Default settings. * * @since 4.4.39 * @return array Changed settings (top-level + one-level deep). */ public static function shallow_two_level_diff( array $settings, array $defaults ) { $difference = array(); foreach ( $settings as $key => $value ) { // Key missing in defaults = changed. if ( ! array_key_exists( $key, $defaults ) ) { $difference[ $key ] = $value; continue; } // If value is an array, only check one level deep. if ( is_array( $value ) && is_array( $defaults[ $key ] ) ) { $nested_diff = array(); foreach ( $value as $sub_key => $sub_value ) { if ( ! array_key_exists( $sub_key, $defaults[ $key ] ) || $sub_value !== $defaults[ $key ][ $sub_key ] ) { $nested_diff[ $sub_key ] = $sub_value; } } if ( ! empty( $nested_diff ) ) { $difference[ $key ] = $nested_diff; } } elseif ( $value !== $defaults[ $key ] ) { // Compare scalar values directly. $difference[ $key ] = $value; } } return $difference; } } /** * Kicking this off by calling 'get_instance()' method */ Astra_Sites_Analytics::get_instance(); }
dvadf
dvadf
| ver. 1.4 |
Github
|
.
| PHP 7.3.33 | Generation time: 0.01 |
proxy
|
phpinfo
|
Settings