Jump to content

All Activity

This stream auto-updates

  1. Past hour
  2. @Strider64 I think my intention (at first, anyway) was to increase upload speed (especially if a few images were involved) and avoid upload size maximum limits (that the server /hosting service enforces). Will this actually address the issue? Is there another reliable resolution?
  3. Yesterday
  4. I use Intervention using composer which is a very handy utility. // Load the image $image = Image::make($image_path); // Resize the image $image->resize(2048, 1365, function ($constraint) { $constraint->aspectRatio(); $constraint->upsize(); }); // Save the new image $image->save($image_path, 100); You can do other image manipulation with Intervention as well and pretty easily. I don't know if this is something you are looking for?
  5. Some time ago I was playing with PHP code to minimize the size of images. My primary purpose was to reduce the file size so that uploading would be quicker and thereby encounter fewer instances of exceeding the upload limits of the hosting server. It recently occurred to me that this was a futile exercise because once PHP was involved, the files at full size had already engaged with the server. Am I correct in my assumption? Is there a reliable way to approach what I had initially intended?
  6. I was asked to create a form and database system for a local entrepreneur and need some business advice and acceptable practices input. From the technical side, I'm concerned about keeping my intellectual property secure and private. If I allow the 'customer' to have access to the files I create, I may not be needed long term. How can I maintain control over the code that I write? And the database that it populates? From a business standpoint, are there generally accepted guidelines for ownership of intellectual property? I also have questions regarding compensation. Is there a ballpark of generality based on hours invested or (USA) dollars for such an endeavor or it's pieces?
  7. Most systems I've seen will write the file to a temporary directory on the server, zip it and serve the zip to the user, then delete the file from the temporary directory. But honestly requinix is right - just direct the user in a new tab to the page that gathers the data and presents it. If I'm not mistaken, the tab itself will close and your user will get the browser's download window.
  8. Looks like requinix responded while I was considering my answer, which would be a YES. ITEM 1 is easy enough. ITEM 2 would require some research (for me, anyway) but should be do-able since PHP can go to a directory and find the file you want to use. ITEM 3 can also be done. I forget the methodology, but I did create a page that allowed me to download files from <a> links; a few modifications and your requirements would be met. As for wanting to NOT have the file on the server, did you want PHP to write the script and ZIP it every time it's needed? I suppose it could be done, but a cumbersome way of making sure nobody sees the script on the server, yet they can grab it through the browser.
  9. Why use AJAX at all? Simply send the browser to the "page" which (immediately) serves the download.
  10. Hey guys, I have a script I’m working on, and I was curious if I can do the following: 1. user clicks button on browser, that sends a request to the server using ajax 2. the server creates a zip file and stores it in php://memory 3. the browser get the needed information to initiate a download of the zip file. can this be done? I suspect I have to physically save the file on the server, and delete it after; which I would like to avoid
  11. Last week
  12. wildcard characters % and _ are only used with a LIKE comparison in a query. if your first query produces any result, it means that you managed to store the % characters in with the data in the database table. preg_match() is a php function. you cannot put it a query to match data in the database table. this query would be producing an sql error. are you using exceptions for errors for the sql queries (this is the default setting now in php8+)? MySql does have regular expressions. see this link - https://dev.mysql.com/doc/refman/8.4/en/regexp.html the regex pattern you came up with matches a string with exactly 3 decimal digits. your stated example is to match 2 digits. which is it and can it vary? what exactly is the overall top-level task you are trying to accomplish, because using regex pattern matching is slow and cannot use indexes, so is a poor choice when you have large amounts of data? lastly, do NOT put dynamic data values directly into sql queries, where any sql special character in a value can break the sql query syntax. use a prepared query instead. if it seems like using the mysqli extension is overly complicated and inconsistent, especially when dealing with prepared queries, it is. this would be a good time to switch to the much simpler and better designed PDO extension.
  13. Lets say you have the following values: 1341 1234 4567 12 1 I'm trying to right a preg_match which will only return true for '34' thus only matching if 2 digits. This is what I have, but it is also matching 1341 and 1234. I may have something after it too. currently my query is as follows: if(isset($_GET['search'])){ $cari = $_GET['search']; $data = mysqli_query($con,"select *** where (table1.test2 = '%".$search."%' or left(table1.test3,3) = '%".$search."%') and date(table.created_date) = '" .$today. "'" but after I change to this following: if(isset($_GET['search'])){ $cari = $_GET['search']; $data = mysqli_query($con,"select *** where (table1.test2 = preg_match('/^[0-9]{3}$/',$search) or left(table1.test3,3) = preg_match('/^[0-9]{3}$/',$search);) and date(table.created_date) = '" .$today. "'" failed. do you have any idea how to construct the preg_match ?
  14. the problem is solved. thank you
  15. You are reinventing the wheel for no good reason. Your database wrapper functions are simplistic and have many issues with them. Just looking at the code here are the things you are trying to accomplish: mysql connection setup and management Query building Query execution and result set fetching There are already a number of well designed PDO wrapper libraries out there. I recommend using Doctrine2 DBal. Doctrine2 is an Object Relational Mapping library that is used by many projects, and is the standard ORM integrated into the Symfony framework. Doctrine2 was architected to utilize a "Database Abstraction Layer" (DBAL) and layers the ORM features on top of that, but you can easily use DBAL by itself. I did exactly that in this simple example web application (rowCloner) I created to illustrate one particular feature of DBAL. By looking at that code, you have an example of how to setup a connection, make a query with parameters and get results. DBAL provides you all the things you need to make queries of different types when you require that. It also has a well designed Query Builder which is fluent and alllows you to create any type of query you want. You can further abstract DBAL with your own classes as I did with the rowCloner class in the example app.
  16. Yes, using fetch is easier in my opinion and here's an example of a page on my website (not the full code): 'use strict'; class ProductManager { constructor() { // DOM Elements this.category = document.querySelector('#category'); this.container = document.querySelector('.main_manager_container'); this.sidebar = document.querySelector('.sidebar_pages'); this.lightbox = document.querySelector('.lightbox'); // Pagination Configurations this.current_page = 1; this.per_page = 3; this.offset = 0; this.total_pages = 0; // Data fetched from the database this.database_data = { 'category': 'images', 'current_page': this.current_page, 'per_page': this.per_page, 'total_count': 0, 'offset': this.offset }; this.pages = [{}]; // Binding `this` context to methods this.categoryUISuccess = this.categoryUISuccess.bind(this); this.paginationUISuccess = this.paginationUISuccess.bind(this); this.resetLinks = this.resetLinks.bind(this); } // Handle fetch errors handleErrors(response) { if (!response.ok) { throw (response.status + ' : ' + response.statusText); } return response; } // Update the UI upon successfully fetching gallery category data async categoryUISuccess(parsedData) { this.clearContainer(); console.log('parsed data', parsedData); // Close the lightbox if it's open this.exitLightbox(); parsedData.forEach((slide, index) => { this.createSlide(slide, index); }); this.addImageListeners(); } // Clear all child elements of the container clearContainer() { while (this.container.firstChild) { this.container.removeChild(this.container.firstChild); } } // Function to truncate text and add a "More..." link addReadMore(paragraph) { const fullText = paragraph.textContent; const truncatedText = fullText.slice(0, 300) + '...'; // Adjust the number of characters as needed const moreLink = document.createElement('span'); moreLink.textContent = ' More...'; //moreLink.style.color = 'blue'; //moreLink.style.cursor = 'pointer'; paragraph.textContent = truncatedText; paragraph.appendChild(moreLink); paragraph.dataset.fullText = fullText; moreLink.addEventListener('click', function() { if (paragraph.textContent.includes('...')) { paragraph.textContent = paragraph.dataset.fullText; moreLink.textContent = ' Less'; } else { paragraph.textContent = truncatedText; paragraph.appendChild(moreLink); } }); } equalizeArticleHeights() { const articles = document.querySelectorAll('.article'); let maxHeight = 0; // Find the tallest article articles.forEach(article => { if (article.offsetHeight > maxHeight) { maxHeight = article.offsetHeight; } }); // Set all articles to the height of the tallest one articles.forEach(article => { article.style.minHeight = `${maxHeight}px`; }); } // Create individual gallery slides createSlide(slide) { const article = this.createElementWithClass('section', 'article'); this.container.appendChild(article); const largeImage = this.createElementWithClass('a', 'largeImage'); largeImage.href = "#"; largeImage.setAttribute('data-image', slide.image_path); // Updated part: Attach event listener to largeImage largeImage.addEventListener('click', (event) => { event.preventDefault(); // Prevent default anchor action this.handleImageClick(largeImage); }); article.appendChild(largeImage); console.log('largeImage', largeImage); const image = this.createElement('img', { src: slide.thumb_path, alt: slide.content, loading: 'lazy', class: 'imageStyle' }); largeImage.appendChild(image); const heading = this.createElementWithClassAndContent('h2', 'articleHeading', slide.heading); article.appendChild(heading); const paragraph = this.createElementWithClassAndContent('p', 'articleText', slide.content); article.appendChild(paragraph); // Truncate text and add "More..." link this.addReadMore(paragraph); this.equalizeArticleHeights(); } // Utility function to create an HTML element with attributes createElement(tag, attributes = {}) { const element = document.createElement(tag); Object.entries(attributes).forEach(([key, value]) => { element.setAttribute(key, value); }); return element; } createElementWithClass(tag, className) { const element = this.createElement(tag); element.className = className; return element; } createElementWithClassAndContent(tag, className, content) { const element = this.createElementWithClass(tag, className); element.textContent = content; return element; } // Add click event listeners to images to open in lightbox addImageListeners() { const images = document.querySelectorAll('img'); images.forEach(image => { image.addEventListener('click', () => this.handleImageClick(image)); }); } // Add click event listener to lightbox to close it addLightboxListener() { this.lightbox.addEventListener('click', () => { this.exitLightbox(); }); } // Updated handleImageClick to include title and content handleImageClick(anchor) { const largeImageUrl = anchor.getAttribute('data-image'); // Get large image URL const title = anchor.getAttribute('data-title'); // Assuming you add this attribute const content = anchor.getAttribute('data-content'); // Assuming you add this attribute // Clear and set up the lightbox this.lightbox.innerHTML = ''; // Clear previous content // Create and display the large image const largeImage = this.createElement('img', { src: largeImageUrl }); largeImage.classList.add('lightbox-image'); this.lightbox.appendChild(largeImage); // Create and append the title if (title) { const imageTitle = this.createElementWithClassAndContent('h2', 'lightbox-title', title); this.lightbox.appendChild(imageTitle); } // Create and append the content if (content) { const imageContent = this.createElementWithClassAndContent('p', 'lightbox-content', content); this.lightbox.appendChild(imageContent); } // Show the lightbox this.lightbox.style.display = 'block'; } // Close the lightbox exitLightbox() { this.lightbox.style.display = 'none'; // Hide the lightbox this.lightbox.innerHTML = ''; // Clear the lightbox content } // Handle errors when fetching gallery category data fails categoryUIError(error) { console.log("Database Table did not load", error); } // Send a request to the server to fetch images async createImageRequest(url, succeed, fail) { try { const response = await fetch(url, { method: 'POST', // or 'PUT' body: JSON.stringify(this.database_data), }); this.handleErrors(response); const data = await response.json(); succeed(data); } catch (error) { fail(error); } } // Clear all pagination links resetLinks() { /* Remove Links For Screen (cleanup) */ while (this.sidebar.firstChild) { this.sidebar.removeChild(this.sidebar.firstChild) } } // Update the UI with the received pagination data async paginationUISuccess(parsedData) { this.resetLinks(); this.database_data.offset = await parsedData.offset; this.total_pages = Math.ceil(this.database_data.total_count / this.database_data.per_page); /* Create the Display Links and add an event listener */ this.pages = [{}]; /* * Creating the array of page object(s) */ for (let x = 0; x < this.total_pages; x++) { this.pages[x] = {page: x + 1}; } this.pages.forEach(link_page => { const links = document.createElement('div'); links.className = 'links'; this.sidebar.appendChild(links); /* * Add event listener for the links */ links.addEventListener('click', () => { this.database_data.current_page = link_page.page; this.createRequest('portfolioPagination.php', this.paginationUISuccess, this.paginationUIError); }); const pageText = document.createElement('p'); pageText.className = 'linkStyle'; pageText.id = 'page_' + link_page.page; pageText.textContent = link_page.page; links.appendChild(pageText); if (this.database_data.current_page === link_page.page) { links.style.backgroundColor = "#00b28d"; } }) await this.createImageRequest('portfolioGetImages.php', this.categoryUISuccess, this.categoryUIError); } // Handle errors when fetching pagination data fails paginationUIError(error) { console.log("Database Table did not load", error); } // Send a request to the server async createRequest(url, succeed, fail) { try { const response = await fetch(url, { method: 'POST', // or 'PUT' body: JSON.stringify(this.database_data), }); this.handleErrors(response); const data = await response.json(); //console.log('count', data); succeed(data); } catch (error) { fail(error); } } // Send a request to get the total number of images in a category async updateTotalCountAndPagination() { await this.createRequest('getTotalCount.php', this.totalCountUISuccess.bind(this), this.totalCountUIError.bind(this)); } // Update the UI upon successfully fetching the total count totalCountUISuccess(parsedData) { this.database_data.total_count = parsedData.total_count; this.createRequest('portfolioPagination.php', this.paginationUISuccess.bind(this), this.paginationUIError.bind(this)); } // Handle errors when fetching the total count fails totalCountUIError(error) { console.log("Database Table did not load", error); } // Add event listeners to DOM elements bindEvents() { this.category.addEventListener('change', () => { this.database_data.current_page = 1; this.database_data.category = this.category.value; this.updateTotalCountAndPagination(); }); document.addEventListener('DOMContentLoaded', () => { this.createRequest('portfolioPagination.php', this.paginationUISuccess.bind(this), this.paginationUIError.bind(this)); }); } // Initialization function init() { this.addLightboxListener(); this.updateTotalCountAndPagination(); this.bindEvents(); } } const productManager = new ProductManager(); productManager.init(); and the main PHP file: <?php // Load the configuration settings and Composer's autoloader to manage dependencies. require_once __DIR__ . '/../config/clearwebconfig.php'; require_once "vendor/autoload.php"; // Import necessary classes from the clearwebconcepts namespace for error handling, database interaction, and image management. use clearwebconcepts\{ ErrorHandler, Database, ImageContentManager, }; // Create an instance of the ErrorHandler to handle exceptions throughout the script. $errorHandler = new ErrorHandler(); // Register the custom exception handler to delegate exception handling to the ErrorHandler class. set_exception_handler([$errorHandler, 'handleException']); // Initialize a Database instance and create a PDO connection for database access. $database = new Database(); $pdo = $database->createPDO(); // Placeholder for optional arguments that might be needed by the ImageContentManager. $args = []; // Create an instance of the ImageContentManager for managing image content in the specified portfolio gallery. $gallery = new ImageContentManager($pdo, $args, 'portfolio'); // Initialize an empty array to hold input data parsed from the request body. $database_data = []; try { /* * Attempt to retrieve and decode JSON input from the HTTP request body. * JSON_THROW_ON_ERROR ensures a JsonException is thrown in case of any decoding issues. */ $database_data = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR); } catch (JsonException $e) { // Handle decoding errors silently; optional logging can be added here. } /* * Retrieve paginated image content from the ImageContentManager. * This method takes the number of items per page, the offset, the gallery type ('portfolio'), * and an optional category filter from the decoded input data. */ $send = $gallery->page( (int)$database_data['per_page'], (int)$database_data['offset'], 'portfolio', $database_data['category'] ); // Output the resulting image data to the client in JSON format. output($send); /** * Outputs the given data as a JSON response with HTTP 200 status. * * @param mixed $output The data to be encoded and sent in the HTTP response body. */ function output($output): void { http_response_code(200); try { // Encode the output data as JSON and send it to the client. echo json_encode($output, JSON_THROW_ON_ERROR); } catch (JsonException) { // Fail silently on JSON encoding errors; optional error handling can be added here. } } and the page itself: https://www.clearwebconcepts.com/portfolio.php
  17. Every browser has a DOM built into it which represents the HTML elements and styles the browser has created from the underlying HTML/CSS and Javascript code. To manipulate the page, once the HTTP response from the server is complete, you need to use javascript. That is not inherently dangerous, given the limitations that are built into browsers, and standard security models like CORS which you can read more about here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS So yes, you want to use "ajax" which is a generalized term for using javascript functions (should use fetch at this point) to retrieve data, and from there to make updates to the DOM that is loaded.
  18. What specific commands are you running, and what specific error message(s) are you receiving?
  19. very nice.. correct that it will be similar like excel spreadsheet. it is because the user is not familiar yet with web application. I didn't think about that before. so, I will make a category_id column and it will be available in all tables. but I think I just need one table only if the category_id is used to split each product. I mean it will be option columns. Currently we have only 3 category products. but how to arrange it so that it can properly directly insert into the columns i.e. testx untul testx2 ?
  20. awesome.. i will try. thank you
  21. Use sprintf. You can convert the number to whatever format you want to enforce. $test3 = sprintf('%04d',$test3key);
  22. Let's say I want to construct some input fields using this for each loop : foreach($_POST['test3'] as $key => $test3key){ $test3 = $test3key; $test31 = $_POST['test31'][$key]; $test32 = $_POST['test32'][$key]; if (!empty($test3key) && !empty($test31) && !empty($test32)) { // insert sql } } The data for example is test3 = 0033, test31 = 1; test32 is 1,000 In this particular case, the test3 will get converted to just 33 in the database table column. The test3 column type in the database is text. I want to prevent the leading zero removal. How can I accomplish this?
  23. you are trying to store the data like it is in a spreadsheet, not a database. doing this makes all the code and queries to perform any action on the data overly complicated. it appears that each html table section is for a different type/category of products? within each type/category of product, the testx field is the item id, the testx1 field is the quantity, and the testx2 field is the total? if so, when you store the data in the detail table, you should have a category_id column (that indicates which html table section that data is for), an item_id column, a quantity column, and a total column.
  24. Here is the result of inserting multiple rows from separated tables in the database table. My goal is to put the data in one line together but not separated line of detail table. Can some one give an idea how to improve the php of my apps ?
  25. sorry I did not read your reply. I actually do not understand yet what context of this data is needed here. Instead, base on my understanding, you may be refer to the table columns, don't you. One of the table columns as follows: <label style="color:blue;">table #4</label> <br> <div class="table-responsive"> <table class="table table-striped" cellspacing="0" border="1" cellpadding="3"> <tbody id="calculation3"> <tr class="row"> <tr> <td> country </td> <td>country</td> <td>test5</td> <td>test51</td> <td id="myelement">price</td> <td>test52</td> <td>Del</td> </tr> <td><input class="underline-input" style="width: 10rem" type="text" id="country1" name="country1[0]" value="<?php echo $country; ?>" readonly = "readonly"> </td> <td><input class="underline-input" style="width: 10rem" type="text" id="test5" name="test5[0]" maxlength="1" pattern="\d{1}"/></td> <td><input class="underline-input multi" style="width: 10rem" type="number" id="test51" name="test51[0]" /></td> <td id="myelement"><input class="underline-input multi" style="width: 10rem" type="number" id="price" name="price[0]" value="<?php echo $priceclk; ?>"/></td> <td><input class="underline-input amount" style="width: 10rem" type="number" id="test52" name="test52[0]" readonly="readonly"/></td> <td><button type="button" class="del3">Del</button></td> </tr> <tr id="last3"> <td colspan="4" align="left"><button type="button" id="addRow3">Add</button></td> </tr> </tbody> <script> $(document).ready(function(){ $('#calculation3').on("keyup",".multi",function(){ var parent = $(this).closest('tr'); var quant= $(parent).find('#test51').val(); var price= $(parent).find('#price').val(); $(parent).find('#test52').val(quant* price); GrandTotal(); }); function GrandTotal(){ var sum=''; $('.amount').each(function(){ sum+=Number($(this).val()); }); $('#total').val(sum); } }); var template = ''; $(function(){ $("#addRow3").click(function(){ row = '<tr>'+ '<td><input class="underline-input" type="text" style="width: 10rem" id="country1" name="country1['+template+']" maxlength="4" value="<?php echo $country; ?>" readonly = "readonly"/></td>'+ '<td><input class="underline-input" type="text" style="width: 10rem" id="test5" maxlength="1" pattern="\\d{1}" name="test5['+template+']"/></td>'+ '<td><input class="underline-input multi" type="number" style="width: 10rem" id="test51" name="test51['+template+']"/></td>'+ '<td id="myelement"><input class="underline-input multi" type="number" style="width: 10rem" id="price" name="price[0]" name="price['+template+']" value="<?php echo $priceclk; ?>"/></td>'+ '<td><input class="underline-input amount" type="number" style="width: 10rem" id="test52" name="test52['+template+']"/></td>'+ '<td><button type="button" class="del3">Del</button></td>'+ '</tr>'; $(row).insertBefore("#last3"); i++; }); }); $(".del3").live('click', function(){ $(this).parent().parent().remove(); }); $("#calculation3").append(template); </script> </table> </div> our clients sell some number products to their customers. One product price is $SGP 0.2. The number is input in the test5 column. For this table #4, the user only can input one digit length number product. The other table can be 4 digits, 3 digits and 2 digits. The customer can also buy quantity of the product. the quantity is input in the test51 column. The test52 column is multiplication of test51 column and price column. I hide the price column. The customer can also buy more than one number product per each table. The header field is country. I also save the header field country to the detail table. So, that's why there is country column for all tables (table #1 to table #5). Total sales is the accumulation of each table amounts which column name for each table is test22, test32, until test52. I use JS to calculate it. Please kindly let me know if you need is difference with my explanation above. thank you
  26. I totally changed the php of my app. it is resolved by creating 5 difference foreach loops and 5 difference keys that gonna be used in the foreach loops. I did that because I have to have 5 separated tables to input different data but need to be inserted into one detail table and one header table. Thank you
  27. you still have not provided any context (meaning) of this data. name-numbered, labels and variables, are meaningless to us. if the mix of rows shown in the example picture is valid, i.e. you can have have any number of rows from each html table section, you should (probably) store the data from each row in each html table as a separate row in the detail database table, with an item_id column to indicate the meaning of each row of data. i have a recommendation for the dynamically added markup. don't write out the markup in the javascript yourself, where you have to keep it updated to match any changes or corrections (you are going to need to eliminate the use of duplicate ids) you make to the markup being output on the page. instead, define/store the output being output on the page in a php variable, so that you can echo it on the page and echo it as the markup inside the javascript. if you use back-ticks (template literals) around what you echo in the javascript, you can use the exact same markup in both cases. see this link - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
  28. Thanks for the 13 points from you. I have reviewed it and some of them is applied but i consider the previous answer that is using separate database tables to store the data from table #1 to table #5. Do you have any idea if I stil can use one table for all of data from all rows of the table #1 to table #5 ?
  1. Load more activity
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.