403Webshell
Server IP : 138.197.107.151  /  Your IP : 216.73.217.7
Web Server : Apache/2.4.58 (Ubuntu)
System : Linux BloxBy-Builder 6.8.0-71-generic #71-Ubuntu SMP PREEMPT_DYNAMIC Tue Jul 22 16:52:38 UTC 2025 x86_64
User : wpbetasites_mrakzqskir ( 1022)
PHP Version : 8.3.6
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/shark/app/Http/Controllers/Api/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/shark/app/Http/Controllers/Api/WebsiteController.php
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Session;
use App\Models\Prompt;
use App\Models\UserSetting;
use App\Models\Website;
use Auth;

class WebsiteController extends Controller
{
    //Generate Sitemap from AI
    public function generateSitemapFromAI($apiKey, $payload) {
        $ch = curl_init('https://api.openai.com/v1/chat/completions');

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $apiKey,
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));

        $response = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            return ['error' => $error];
        }

        $decoded = json_decode($response, true);

        if (!isset($decoded['choices'][0]['message']['content'])) {
            return ['error' => 'Invalid OpenAI response'];
        }

        return json_decode($decoded['choices'][0]['message']['content'], true);
    }
    // Save JSON data to session
    public function getDefaultSiteData(Request $request)
    {
        $data = $request->json()->all();

        $prompt = $data['prompt'];
        $ai_xpandedprompt = $data['expanded_prompt'];
        $response_format = $data['response_format']; // e.g. 'json'

        $apiKey = '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';

        $payload = [
            'model' => 'gpt-4o-mini',
            'messages' => [
                [
                    'role' => 'system',
                    'content' => "You are a helpful assistant that suggests website_type, website_industry, and then generates website_title, website_description, and all pages with their respective sections for a website based on the suggested website_type, website_industry, and the given user prompt. Return your response in the required JSON format.

                        Follow these steps strictly (follow internally, do not output intermediate steps):

                        ### Step 1: Initial Generation
                        Generate the JSON as per all the rules:
                        - Must include website_type, website_industry, website_title, and website_description.
                        - Always generate at least 4 and no more than 6 unique pages.
                        - The following pages apply:
                          - Home (mandatory) and follows special rules.
                          - About (mandatory), should include after homepage.
                          - Contact (mandatory), should include at very last in every website.
                          - Services — create only if the website provides or showcases services, skills, or products.
                          - Blog — create only if the website supports news, tips, or articles.
                        - If Services or Blog are not applicable, replace them with other meaningful, relevant pages such as About, Portfolio, Testimonials, Projects, or Team.
                        - Each page must be unique, relevant, and follow all section rules.
                        - Must include 'pages', each with sections as per the detailed rules given in Instructions to follow:.
                        - Home page will always include 8-10 sections 
                        - Each other page (except homepage and service page) must have 6-7 sections with unique names.

                        ### Step 2: Self-Check
                        After generating the JSON, count how many 'pages' exist.
                        - If fewer than 4 pages exist:
                          - Add additional unique pages relevant to the website’s purpose until there are at least 4 in total.
                        - If more than 6 pages exist:
                          - Remove or merge extra pages until there are no more than 6 total.
                        - Ensure Home, About and Contact always exist.
                        - Ensure missing required pages (Services, Blog, Contact) are added when applicable.
                        - Confirm all pages follow naming and section structure rules.
                        - Confirm that service page must have all the services if provided in the user prompt.

                        ### Step 3: Final Output
                        Return only the final JSON after the self-check.
                        Do not include explanations, reasoning, or intermediate steps — output only valid JSON.

                        ### Instructions to follow:

                        1. Personal Websites:
                           - If the website is personal, reference it as 'my website' and all sections should say 'me'.
                           - **DONOT** add sections that sound an agency/comapny like meet our team, social_cards. 
                           - For showing quotes or principles use testimonials section_type.
                        2. Page Rules:
                           - Always include Home (mandatory), About (mandatory) and Contact (mandatory).
                           - Always include a service page to list all the services if the website have services, skills, practice areas, or products.
                           - Include Blog if the website supports posts, tips, or updates.
                           - If Blog or Services are not needed, replace them with relevant alternative pages to ensure 4–6 pages total.
                           - **IMPORTANT RULE (OVERRIDES ALL PAGE RULES ABOVE)**:
                                - If the user prompt mentions or lists specific pages by name, you must generate:
                                  - Home (mandatory)
                                  - PLUS all other pages specified in the user's prompt (exactly as intended by the user)
                                - Do NOT add, remove, rename, merge, or replace user-specified pages.
                        3. Home Page:
                           a. Keep the title as 'Home' and do not change section titles.
                           b. **MUST** Always create 8-10 distinct sections for the homepage.
                           c. Always add an 'About' section.
                           d. If the website provides services or benefits, create a listing_grid section on homepage, include all the services if provided in the prompt.
                             - List all the services in comma separated form in the Section Prompt.
                             - When making a listing_grid section, The list of services/products shown here must match exactly with those on the Services/Products page. 
                           e. Include a 'call to action' as the final section.
                        4. Unique Page Titles:
                           a. Generate distinct, unique titles for all pages except Home.
                           b. Page titles must be ≤3 words and not include the website name.
                        5. Unique Section Titles:
                           a. Each section must have a unique, descriptive title.
                           b. Each non-home page must have 6–7 sections.
                           c. Use features_listing for multiple items; feature_detail for single highlights.
                        6. Unique Section Descriptions:
                           - Write professional, distinct descriptions for every section.
                           - Donot mention any services provided in the description.
                        7. Section Prompts:
                           - section_prompt is always required. Always include the structure of the section and what this section has to offer or want to convey in the section_prompt.
                           - If the section is intended to show list if services. Include all the services in comma separated form in section_prompt. For example: List main services (Service 1, Service 2, ...) provided by the firm/website/business etc.
                        8. Service Page:
                           a. If the website provides services or products, create a dedicated service page.
                           b. **Important** Donot combine services based on their category add all the services exactly if provided in the user prompt.
                           c. Always include media_and_text sections for every service.
                           d. Always include a faqs section before call to action section.
                        9. Blog Page (if applicable):
                           a. Create only if the site supports posts or updates.
                           b. Include a posts_grid section.
                           c. Add a latest_posts section to the homepage as second-to-last.
                        10. Contact Page:
                           a. For informational websites, include a contact page with a form.
                           b. Never add 'call_to_action' section in contact page.
                        11. Universal Sections:
                            - All pages start with 'Header' section titled 'Header' and end with 'Footer' section titled 'Footer'.
                            - On all pages except the homepage, include a 'inner_banner' section using the page title as the section name.4
                            - Do not add multiple about sections per page, there should be only one about section per page page if needed.
                            - Add 'call-to-action' before Footer (except on Contact page).
                            - Each page should have 5–6 sections total.
                        12. Formatting:
                            - Use 'slug' format for page_type and section_type.
                            - Keep section_description concise and section_prompt descriptive with Bootstrap layout details.
                        13. Search Terms:
                            - Generate 2-3 relevant comma separated search terms each of one to two word only for finding appropriate images on Unsplash for this website.
                        14. Portfolio or Statistics Websites:
                            - Include 'statistics_bar' for numbers/achievements.
                        15. Team Section:
                            - Donot create any team section for personal websites.
                            - Use 'social_cards' only for team members, contributors, advisory board, speakers.
                        16. Consistency and Localization:
                            - If any Location is mentioned in the user prompt. Localize content to that selected location for example: local courts or procedural notes etc.
                            - Keep Home page titles and sections unchanged.
                            - Maintain professional tone and relevance to website industry.
                            - Keep tone professional, clear, and relevant to the website industry.

                        Output your response strictly in the JSON format as defined in the provided schema."
                ],
                [
                    'role' => 'user',
                    'content' => $ai_xpandedprompt
                ]
            ],
            'response_format' => $response_format,
        ];

        $maxRetries = 3;
        $attempt = 0;

        //Retry the page generation if page count is less than 3
        do {
            $attempt++;

            $finalArr = $this->generateSitemapFromAI($apiKey, $payload);

            if (isset($finalArr['error'])) {
                return response()->json(['error' => $finalArr['error']], 500);
            }

            $pageCount = isset($finalArr['pages']) ? count($finalArr['pages']) : 0;

            // Break if enough pages
            if ($pageCount >= 3) {
                break;
            }

        } while ($attempt < $maxRetries);
        
        $finalArr['user_prompt'] = $prompt;

        $promptdb = new Prompt;

        $promptdb->prompt = $prompt;

        

       $user = Auth::user();

        if($user){
            $promptdb->user_id = $user->id;
        }
        $promptdb->save();
        
        $finalArr['prompt_id'] = $promptdb->id;

        $promptdb->meta = json_encode($finalArr);

        $promptdb->save();

        return response()->json($finalArr);
    }

    public function uploadUserSelectedLogo( Request $request ) {
        $request->validate([
            'logo' => 'max:1024', // max 1MB
        ]);

        $file = $request->file('logo');
        $filename = uniqid('logo_') . '.' . $file->getClientOriginalExtension();

        $file->move(public_path('temp-logos'), $filename);
        $url = url('temp-logos/' . $filename);

        return response()->json([
            'message' => 'Logo uploaded successfully',
            'url' => $url,

        ], 200);

    }

    public function addNewPage( Request $request ) {
        $data = $request->json()->all();
        $apiKey = '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';
        $pageName = $data['page'];
        $websiteName = $data['website_name'];
        $websiteDesc = $data['website_description'];
        
        $payload = [
            'model' => 'gpt-4o-mini',
            'messages' => [
                [
                    'role' => 'system',
                    'content' => 'You are an AI assistant that generate page structure with their respective sections for a website based on the suggested websiteName, websiteDesc, using the page name given in user prompt. 

                    Rules:
                    1. Personal Websites: If the website is a personal website, reference it as "my website" and all sections should say "me".
                    2. All sections should have unique, descriptive titles that are relevant to the page content. Avoid repeating generic names like “About Us” or “Services.”
                    3. Section Rules 
                        3a. Start all pages with a "Header" section titled "Header.""
                        3b. Each page should have 5-6 section each.
                        3c. On all pages except the homepage, include a "inner_banner" section using the page title as the section name.
                        3d. Always add call-to-action section before Footer in all the pages except Contact page
                        3e. Conclude all pages with a "Footer" section titled "Footer.
                    4. Formatting:
                        4a. Use "slug" format for page_type and section_type fields.
                        4b. For section_description, provide concise, clear language that highlights the section’s purpose and key points.
                        4c. For section_prompt, provide a clear description of what the section is about and what this section wants to convey, so it can be used to generate the section structure using WordPress Gutenberg blocks. Also add a description about the layout of the section to create it using Bootstrap 5 (e.g., Responsive left-aligned hero with image).
                    
                    websiteName: '.$websiteName .'
                    websiteDesc: '.$websiteDesc .'
                    
                    Return your response in the required JSON format:
                    {
                        "page_type": {
                            "type": "string"
                        },
                        "page_title": {
                            "type": "string"
                        },
                        "page_description": {
                            "type": "string"
                        },
                        "sections": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "section_type": {
                                        "type": "string",
                                        "enum": [
                                            "header",
                                            "hero_banner",
                                            "inner_banner",
                                            "about",
                                            "benefit",
                                            "posts_grid",
                                            "latest_posts",
                                            "contact_section",
                                            "call_to_action",
                                            "faqs",
                                            "feature_highlight",
                                            "features_list",
                                            "social_cards",
                                            "gallery",
                                            "listing_grid",
                                            "statistics_bar",
                                            "reviews",
                                            "testimonials",
                                            "pricing_table",
                                            "menu_listing",
                                            "media_and_text",
                                            "informational_content_without_media",
                                            "footer"
                                        ]
                                    },
                                    "section_title": {
                                        "type": "string"
                                    },
                                    "section_description": {
                                        "type": "string"
                                    },
                                    "section_prompt": {
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "section_type",
                                    "section_title",
                                    "section_description",
                                    "section_prompt"
                                ]
                            }
                        }
                    }

                    '
                ],
                [
                    'role' => 'user',
                    'content' => 'pageName:'. $pageName
                ]
            ]
        ];

        $ch = curl_init('https://api.openai.com/v1/chat/completions');

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $apiKey,
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));

        $response = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            return response()->json(['error' => $error], 500);
        }

        $decoded = json_decode($response, true);

        if ( !isset($decoded['choices'][0]['message']['content']) ) {
            return response()->json(['error' => $response ], 500);
        }
        $json_str = $decoded['choices'][0]['message']['content'];

        // Extract content within ```json ... ``` in AI output.
        if (preg_match('/```json\s*(.*?)```/is', $json_str, $matches)) {
            $json_str = trim($matches[1]);
        }

        $finalArr = json_decode($json_str, true);

        return response()->json($finalArr);
        
    }

    public function checkPromptValidation( Request $request ) {
        $data = $request->json()->all();

        $prompt = $data['prompt'];

        $apiKey = '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';

        //Check if user has website quota available
        $user = Auth::user();
        if( $user ) {
            $websites_limit = 3;
            $setting = UserSetting::where("user_id",  $user->id)->first();
            $setting = UserSetting::where("user_id",  auth()->user()->id)->first();
            if($setting){
                $websites_limit = $setting->websites_limit;
            }

            $websites_count = Website::withTrashed()->where('user_id', auth()->id())->count();

            if( $websites_count >= $websites_limit ) {
                return response()->json([
                    "status" => "error",
                    "content" => "You’ve reached the maximum number of website generations. Please upgrade your plan or delete some websites."
                ]);
            }
        }

        $payload = [
            'model' => 'gpt-4o-mini',
            'messages' => [
                [
                    'role' => 'system',
                    'content' => 'You are an AI assistant that validates and expands website generation prompts.
                        Task:
                        1. First check the user’s prompt for inappropriate or disallowed topics.
                        - Inappropriate topics include: pornography, gambling, drugs, scams, violence, hate, if any question, or anything illegal.
                        - If the prompt contains inappropriate content, return ONLY a JSON object with:
                            {{
                            "status": "error",
                            "content": "This request cannot be processed as it involves inappropriate or restricted content."
                            }}

                        2. If the prompt is safe:
                        - Expand the user’s idea into a clear, professional website concept.
                        - The expansion should start with a brief description of 40 to 50 words.
                        - Also tell about what to include in website. List all the pages clearly in the content if mentioned in the user prompt. 
                        - If any location is mentioned in the user prompt then clearly mention that location in the content and localize the content to that location.
                        - Services Rules
                            -- If the website supports some services, products, categories, areas of practice/service etc. list all of them in the content.
                            -- **Important** If the user explicitly provide their own services, products, areas of practice/service or any other information respect those rules and include all of them in content. 
                        - In content dont return in json like in string only 
                        - Personal Websites: If the website is a personal website (for example: A portfolio website of a person.) reference it as "my website" and ensure all sections speak in the first person using "me" like "my journey", "about me" or "my portfolio".

                        Return ONLY a JSON response with two fields:
                        {{
                        "status": "success",
                        "content": "Expanded prompt"
                        }}'
                ],
                [
                    'role' => 'user',
                    'content' => 'User’s prompt: ' . $prompt
                ]
            ]
        ];

        $ch = curl_init('https://api.openai.com/v1/chat/completions');

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $apiKey,
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));

        $response = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            return response()->json(['error' => $error], 500);
        }

        $decoded = json_decode($response, true);

        if ( !isset($decoded['choices'][0]['message']['content']) ) {
            return response()->json(['error' => $response ], 500);
        }
        $json_str = $decoded['choices'][0]['message']['content'];

        // Extract content within ```json ... ``` in AI output.
        if (preg_match('/```json\s*(.*?)```/is', $json_str, $matches)) {
            $json_str = trim($matches[1]);
        }

        $finalArr = json_decode($json_str, true);

        return response()->json($finalArr);
    }

    public function transcribeSpeechToText(Request $request)
    {
        //|mimes:mp3,wav,m4a,webm
        $request->validate([
            'file' => 'required|file'
        ]);

        $filePath = $request->file('file')->getPathname();
        $fileName = $request->file('file')->getClientOriginalName();

        $endpoint = 'https://api.openai.com/v1/audio/translations';

        $response = Http::withToken("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")
            ->attach('file', fopen($filePath, 'r'), $fileName)
            ->post($endpoint, [
                'model' => 'whisper-1',
                'response_format' => 'text'
            ]);

        if ($response->failed()) {
            return response()->json([
                'error' => $response->json(),
            ], 200);
        }

        return response($response->body(), 200)
            ->header('Content-Type', 'text/plain');
    }

}


Youez - 2016 - github.com/yon3zu
LinuXploit