PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.7.2
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.7.2
3.7.5 3.7.4 3.7.3 3.7.2 1-final 3.7.1 3.7.0 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.10 All 111 releases
← All changes | includes/Utils/Helper.php +72 -0 3.6.63.7.2 View file →
@@ -151,8 +151,13 @@
151 151 'Authorization' => 'Bearer ' . $api_key,
152 152 'x-templately-ip' => self::get_ip(),
153 153 'x-templately-url' => home_url('/'),
154 154 'x-templately-version' => defined( 'TEMPLATELY_VERSION' ) ? constant( 'TEMPLATELY_VERSION' ) : '1.0.0',
155 + // Force JSON responses so the cloud returns JSON errors instead of an HTML
156 + // error page (which json_decode() cannot parse). Binary/XML downloads
157 + // (zip pack, attachment WXR) use their own wp_remote_* calls and bypass
158 + // this helper, so they are unaffected. Callers can override via $extra_headers.
159 + 'Accept' => 'application/json',
155 160 ];
156 161
157 162 // Add Content-Type for POST requests
158 163 if (strtoupper($method) === 'POST') {
@@ -742,7 +747,74 @@
742 747 $r[$key] = $value;
743 748 }
744 749 }
745 750 return $r;
751 + }
752 +
753 + /**
754 + * Creates the plugin's working directory under wp-uploads and blocks direct
755 + * web access to it.
756 + *
757 + * Everything the importer needs on disk lands here: the extracted pack (its
758 + * WXR, its template JSON, its attachments), the AI-generated page JSON, and
759 + * the FSI logs. wp-uploads is web-served, so these paths are not private just
760 + * because their session id is a uuid — the guards are what makes them
761 + * unreadable, not the name.
762 + *
763 + * .htaccess covers Apache and is inherited by everything below this point;
764 + * web.config covers IIS; index.php stops a directory listing on any server.
765 + * nginx honours none of them, so an nginx site still needs a location rule —
766 + * this raises the floor, it does not replace server configuration.
767 + *
768 + * @param string $dir Absolute path to create and protect.
769 + *
770 + * @return bool Whether the directory exists and is usable.
771 + */
772 + public static function protect_directory( $dir ) {
773 + if ( empty( $dir ) ) {
774 + return false;
775 + }
776 +
777 + if ( ! is_dir( $dir ) && ! wp_mkdir_p( $dir ) ) {
778 + return false;
779 + }
780 +
781 + $guards = [
782 + 'index.php' => "<?php\n// Silence is golden.\n",
783 + '.htaccess' => "# Templately working files — not for direct access.\n<IfModule mod_authz_core.c>\n\tRequire all denied\n</IfModule>\n<IfModule !mod_authz_core.c>\n\tOrder allow,deny\n\tDeny from all\n</IfModule>\n",
784 + 'web.config' => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration>\n\t<system.webServer>\n\t\t<authorization>\n\t\t\t<deny users=\"*\" />\n\t\t</authorization>\n\t</system.webServer>\n</configuration>\n",
785 + ];
786 +
787 + foreach ( $guards as $file => $contents ) {
788 + $path = trailingslashit( $dir ) . $file;
789 + // Never overwrite: a site owner may have relaxed these deliberately.
790 + if ( ! file_exists( $path ) ) {
791 + @file_put_contents( $path, $contents ); // phpcs:ignore
792 + }
793 + }
794 +
795 + return true;
796 + }
797 +
798 + /**
799 + * Absolute path to the plugin's protected working directory in wp-uploads.
800 + *
801 + * @param string $sub Optional subdirectory ('tmp', 'log', 'preview', ...).
802 + *
803 + * @return string Trailing-slashed path, or '' when uploads is unusable.
804 + */
805 + public static function upload_dir( $sub = '' ) {
806 + $upload_dir = wp_upload_dir();
807 +
808 + if ( ! empty( $upload_dir['error'] ) || empty( $upload_dir['basedir'] ) ) {
809 + return '';
810 + }
811 +
812 + $base = trailingslashit( $upload_dir['basedir'] ) . 'templately' . DIRECTORY_SEPARATOR;
813 +
814 + // The guards go on the root so every subdirectory inherits them.
815 + self::protect_directory( $base );
816 +
817 + return '' === $sub ? $base : trailingslashit( $base . $sub );
746 818 }
747 819
748 820 }