PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.6.8
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.6.8
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 +0 -88 3.7.33.6.8 View file →
@@ -114,29 +114,8 @@
114 114 }
115 115 }
116 116
117 117 /**
118 - * A URL on the public Templately website, honouring the dev domain.
119 - *
120 - * The PHP counterpart of `react-src/utils/helper.js#webURL`. A hard-coded
121 - * `https://templately.com/...` sends a site running against the dev API to
122 - * the live site, where its account does not exist — so build every out-link
123 - * through this instead.
124 - *
125 - * Note this is the *website*, not the API host `get_api_url()` builds.
126 - *
127 - * @param string $path Path with or without a leading slash.
128 - * @param array $args Query args (utm_* etc).
129 - * @return string
130 - */
131 - public static function web_url( string $path = '', array $args = [] ): string {
132 - $base_url = self::is_dev_api() ? 'https://templately.dev' : 'https://templately.com';
133 - $url = $base_url . '/' . ltrim( $path, '/' );
134 -
135 - return empty( $args ) ? $url : add_query_arg( $args, $url );
136 - }
137 -
138 - /**
139 118 * Get API URL for Templately endpoints
140 119 *
141 120 * @param string $endpoint API endpoint path (e.g., 'v2/import/pack/123')
142 121 * @return string Complete API URL
@@ -768,74 +747,7 @@
768 747 $r[$key] = $value;
769 748 }
770 749 }
771 750 return $r;
772 - }
773 -
774 - /**
775 - * Creates the plugin's working directory under wp-uploads and blocks direct
776 - * web access to it.
777 - *
778 - * Everything the importer needs on disk lands here: the extracted pack (its
779 - * WXR, its template JSON, its attachments), the AI-generated page JSON, and
780 - * the FSI logs. wp-uploads is web-served, so these paths are not private just
781 - * because their session id is a uuid — the guards are what makes them
782 - * unreadable, not the name.
783 - *
784 - * .htaccess covers Apache and is inherited by everything below this point;
785 - * web.config covers IIS; index.php stops a directory listing on any server.
786 - * nginx honours none of them, so an nginx site still needs a location rule —
787 - * this raises the floor, it does not replace server configuration.
788 - *
789 - * @param string $dir Absolute path to create and protect.
790 - *
791 - * @return bool Whether the directory exists and is usable.
792 - */
793 - public static function protect_directory( $dir ) {
794 - if ( empty( $dir ) ) {
795 - return false;
796 - }
797 -
798 - if ( ! is_dir( $dir ) && ! wp_mkdir_p( $dir ) ) {
799 - return false;
800 - }
801 -
802 - $guards = [
803 - 'index.php' => "<?php\n// Silence is golden.\n",
804 - '.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",
805 - '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",
806 - ];
807 -
808 - foreach ( $guards as $file => $contents ) {
809 - $path = trailingslashit( $dir ) . $file;
810 - // Never overwrite: a site owner may have relaxed these deliberately.
811 - if ( ! file_exists( $path ) ) {
812 - @file_put_contents( $path, $contents ); // phpcs:ignore
813 - }
814 - }
815 -
816 - return true;
817 - }
818 -
819 - /**
820 - * Absolute path to the plugin's protected working directory in wp-uploads.
821 - *
822 - * @param string $sub Optional subdirectory ('tmp', 'log', 'preview', ...).
823 - *
824 - * @return string Trailing-slashed path, or '' when uploads is unusable.
825 - */
826 - public static function upload_dir( $sub = '' ) {
827 - $upload_dir = wp_upload_dir();
828 -
829 - if ( ! empty( $upload_dir['error'] ) || empty( $upload_dir['basedir'] ) ) {
830 - return '';
831 - }
832 -
833 - $base = trailingslashit( $upload_dir['basedir'] ) . 'templately' . DIRECTORY_SEPARATOR;
834 -
835 - // The guards go on the root so every subdirectory inherits them.
836 - self::protect_directory( $base );
837 -
838 - return '' === $sub ? $base : trailingslashit( $base . $sub );
839 751 }
840 752
841 753 }