fetch data from database for specific web pages

I am creating a website in which people can post some thing with expiry date. And i am storing all data in database with expiry date so on pages only valid data will be appeared and expired wont show on pages. Currently I am using this php script

    <?php
$servername = "******";
$username = "********";
$date=date("Y/m/d");
try {
    $conn = new PDO("mysql:host=$servername;dbname=******", $username, "*******");
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $query = "select id, item1, item2, item3, expirydate, description from table WHERE expirydate>= ?";
    $statement = $conn->prepare($query);
    $statement->execute(array($date));
        foreach($statement->fetchAll(PDO::FETCH_ASSOC) as $row){
            echo"<div class='col-md-12'>";
                echo"<div class='agent-item'>";
                    echo"<div class='row'>";
                        echo"<div class='col-md-3'>";
                            echo"<img src='img/uploads/$row[item1]' class='img-responsive' alt=''>";
                        echo"</div>";
                        echo"<div class='col-md-6'>";
                            echo"<h6 class='mb-xs'>Description</h6>";
                            echo"<p>'$row[item2]'</p>";
                        echo"</div>";
                        echo"<div class='col-md-3'>";
                            echo"<p>address</p>";
                        echo"</div>";
                    echo"</div>";
                echo"</div>";
            echo"</div>";
        }
    }
catch(PDOException $e)
    {
        echo "Connection failed: " . $e->getMessage();
    }
?>

The Problem is that fetchAll fetches all data which i really don't want. I want to show 10 items per pages so i want to fetch 10 items and when user clicks next page so on page 2 i want to fetch next 10 items and show them on page 2. I am struggling for 2 days to achieve this but i failed every time even though i tried only fetch() method as well but it iterates only once in foreach loop. Can some one help me out how can i fetch only 10 items and on next page how can i fetch 10 more items which should be start after previous 10 items.

Please note: to track the items, choosing the id is not best choice because expiry date vary, that's mean if id 2 user have expiry date after 1 week so id 3 user have expiry date before that.

Thanks in advance

1 answer

  • answered 2018-04-17 04:49 Rohit Chauhan

    First if you want to fetch only 10 records then add Limit in query like this

    select id, item1, item2, item3, expirydate, description from table WHERE expirydate >= ? Limit 10 ;
    

    It will fetch only 10 record that are matching Check whether your query works proper or not

    Next Take a loot at here to create pagination for webage

    https://www.w3schools.com/howto/howto_css_pagination.asp

  • Redirect to a View instead of returning a Response to jQuery ajax $.post

    I'm trying to validate a form using jQuery and submitting it after successful validation.

    My controller looks like:

    [HttpPost]
    public ActionResult Calculator(FormCollection data)
    {
        var report = ; // getting it from database
        return RedirectToAction("Report", report);
    }
    

    And my jQuery ajax call looks like this:

    $("#btnCalculateScore").click(function (e) {
       if (validateData()) {
          var $frm = $("#frmCalculator");
          var url = $frm.prop("action");
          $.post(url, $frm.serialize(), function (data) {
                    //do something with response from server
          });
       }
    });
    

    Since, I am using a jQuery ajax call here, my controller post method returning a response back to my ajax call instead of redirecting to Report View().

    How can I redirect to Report View with data after ajax post call? please help me in this.

  • post function in django formview not called when jquery post is used

    I have to call SearchView when "search" button is clicked. With a few print statements, I could see that SearchView is being called but post function in the SearchView is not called.

    Below is the code I have used in SearchView:

        class SearchView(FormView):
            template_name = 'search.html'
            #form_class = SearchForm
            success_url = '/mypage/downloadresult'
            print(" i am inside SearchView")
    
            def post(self, request, *args, **kwargs):
                # form = self.form_class(request.POST)
                form_class =SearchForm
                form = self.get_form(form_class)
                # form_class = self.get_form_class()
                # form = self.get_form(form_class)
                print(" i am inside post")
    
                if form.is_valid():
                    if self.request.is_ajax():
                       // handle form and generate result
    

    Below is the display view for my form:

        class DisplayView(FormView):
            template_name = 'search.html'
            form_class = SearchForm
            print(" i am inside displayview")
            success_url = '/sampleapp/search'
    

    When the form is displayed using the DisplayView above, once the user clicks on "search" button, SearchView is called on successful form post.

    Url patterns in sample app:

        urlpatterns = [
            #url('', SearchView.as_view()),
            #url('', SearchView.as_view()),
            url('', displayformview.DisplayView.as_view(), name='displayview'),
            url(r'^search/$', SearchView.as_view(), name='search'),
            url(r'^downloadresult/$', downloadresultview.DownloadResultView.as_view(), name='downloadresult')
        ]
    
        urlpatterns = [
            url(r'^admin/', admin.site.urls),
            url(r'^', include(‘sampleapp.urls')),
        ]
    

    Below is the jquery i am using:

     $('#search').click(function(){
        $.post('/sampleapp/search', $(this).serialize(), function(){
            //alert("submit called")
        })
        .done(function(){
            alert("done")
        })
    })
    

    I am not sure if the above jquery is acutally sending the form data. If someone can help me understand how to send the form data using jquery and successfully call the post function, it will be really helpful.

    I tried debugging using print statement. I could see that post function in SearchView is never called and "I am inside post" is never printed in console".

  • Testing Send endpoint for Gmail API with Postman

    I am trying to send emails with the Gmail API. I am trying to use Postman to test my requests and get the proper code to use in my web application, but I keep getting this error:

    {
      "error": {
        "errors": [
            {
                "domain": "global",
                "reason": "invalidArgument",
                "message": "Recipient address required"
            }
        ],
        "code": 400,
        "message": "Recipient address required"
       }
    }
    

    I'm using the following link to make a POST request:

    https://www.googleapis.com/upload/gmail/v1/users/me/messages/send
    

    In my header, I have the following:

    Authorization: Bearer ya29.xxxxxxxxx
    Content-Type: message/rfc822
    

    In my request body:

    {
    
    "raw" : "RnJvbTogQWxleCBCdWhzZSA8YWxleGJ1aHNlMUBnbWFpbC5jb20-IApUbzogQWxleCBCdWhzZSA8a29vX29saW9AaG90bWFpbC5jb20-IApTdWJqZWN0OiBTYXlpbmcgSGVsbG8geW8KRGF0ZTogRnJpLCAyMSBOb3YgMTk5NyAwOTo1NTowNiAtMDYwMApDb250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD11dGYtOA=="
    
    }
    

    I have tested the request with through the API testing sidebar on Google's own documentation:

    https://developers.google.com/gmail/api/v1/reference/users/messages/send
    

    but I seem to not be having any luck with using it in Postman. I'm using Postman and not the javascript that Google provides because I want to get the proper formatted code for making an AJAX call. I was wondering if anyone has worked with Postman and the Gmail API that may be able to help?

  • Keep getting told the value is null

    here is my code:

    var Ribbon = /** @class */ (function () {
        function Ribbon(svg) {
            this.rootPos = Math.random() * 100;
            this.states = {
                start: {
                    type: 'start',
                    start: { thickness: 0, top: 60, left: 0 },
                    end: { thickness: 0, top: 60, left: 100 },
                    wave: { amplitude: 0, frequency: 0.008, transitionSpeed: 0.5 }
                },
                home: {
                    type: 'home',
                    start: { thickness: 30, top: 50, left: 0 },
                    end: { thickness: 15, top: 60, left: 100 },
                    wave: { amplitude: 40, frequency: 0.015, transitionSpeed: -0.5 }
                },
                selected: {
                    type: 'selected',
                    start: { thickness: 15, top: 80, left: 0 },
                    end: { thickness: 24, top: 25, left: 100 },
                    wave: { amplitude: 50, frequency: 0.004, transitionSpeed: 0.5 }
                }
            };
            this.size = { svg: { width: window.innerWidth, height: window.innerHeight } };
            this.currentState = JSON.parse(JSON.stringify(this.states.start));
            this.rows = 3;
            this.lines = [];
            this.blocks = [];
            this.defaultRestSpeed = 0.009;
            this.speed = {
                changeState: 2,
                rest: 1
            };
            this.waveLineAttr = {
                fill: 'none',
                stroke: 'white',
                strokeWidth: 1
            };
            this.svg = svg;
        }
        Ribbon.prototype.init = function () {
            var _this = this;
            this.blocks = [
                {
                    type: 'menu',
                    id: '1',
                    title: 'Products',
                    position: { current: 105, target: 5, home: 5 },
                    width: 20,
                    row: 2
                },
                {
                    type: 'menu',
                    id: '2',
                    title: 'Blog',
                    position: { current: 137, target: 37, home: 37 },
                    width: 10,
                    row: 3
                },
                {
                    type: 'menu',
                    title: 'About Us',
                    id: '3',
                    position: { current: 147, target: 47, home: 47 },
                    width: 20,
                    row: 1
                },
                {
                    type: 'menu',
                    id: '4',
                    title: 'Contact',
                    position: { current: 175, target: 75, home: 75 },
                    width: 15,
                    row: 2
                },
                {
                    type: 'back',
                    id: 'back',
                    title: '<-- Back',
                    position: { current: -100, target: -100, home: -100 },
                    width: 10,
                    row: 1
                }
            ];
            this.ribbon = this.svg.polygon().attr({
                fill: 'red',
                stroke: 'none'
            });
            // this.topWaveGuideLine = this.svg.path().attr(this.waveLineAttr);
            // this.bottomWaveGuideLine = this.svg.path().attr(this.waveLineAttr);
            this.resizeSVG();
            this.tick(0);
            this.updateRibbon();
            setTimeout(function () {
                _this.setState(_this.states.home);
            }, 1000);
        };
        Ribbon.prototype.updateRibbon = function () {
            var _this = this;
            var freq = this.currentState.wave.frequency;
            var pos = this.rootPos;
            var amp = this.currentState.wave.amplitude;
            var x1 = (this.size.svg.width / 100) * this.currentState.start.left;
            var y1 = ((this.size.svg.height / 100) * this.currentState.start.top);
            var x2 = (this.size.svg.width / 100) * this.currentState.end.left;
            var y2 = (this.size.svg.height / 100) * this.currentState.end.top;
            var t1 = ((this.size.svg.height / 100) * this.currentState.start.thickness) / 2;
            var t2 = ((this.size.svg.height / 100) * this.currentState.end.thickness) / 2;
            this.guidePath = this.getGuidePath(freq, pos, amp, x1, y1, x2, y2);
            var topPathPoints = this.getPathOffset(this.guidePath, -t1, -t2);
            this.paths = [topPathPoints];
            if (this.rows > 1) {
                var startHeightSpace = ((this.size.svg.height / 100) * this.currentState.start.thickness);
                var endHeightSpace = ((this.size.svg.height / 100) * this.currentState.end.thickness);
                for (var i_1 = 1; i_1 < this.rows; i_1++) {
                    var startOffset = (0 - (startHeightSpace / 2)) + ((startHeightSpace / this.rows) * i_1);
                    var endOffset = (0 - (endHeightSpace / 2)) + ((endHeightSpace / this.rows) * i_1);
                    var path = this.getPathOffset(this.guidePath, startOffset, endOffset);
                    this.paths.push(path);
                    if (!this.lines[i_1 - 1])
                        this.lines.push(this.svg.path().attr(this.waveLineAttr));
                    this.lines[i_1 - 1].attr({ d: this.getWavePathString(path) });
                }
            }
            var bottomPath = this.getPathOffset(this.guidePath, t1, t2);
            this.paths.push(bottomPath);
            this.ribbon.attr({ points: this.getWavePolygon(topPathPoints, bottomPath.slice(0).reverse()) });
            for (var i = 0; i < this.blocks.length; i++) {
                var block = this.blocks[i];
                var startX = (this.size.svg.width / 100) * block.position.current;
                var endX = (this.size.svg.width / 100) * (block.position.current + block.width);
                if (startX > this.size.svg.width)
                    startX = this.size.svg.width;
                else if (startX < 0)
                    startX = 0;
                if (endX > this.size.svg.width)
                    endX = this.size.svg.width;
                else if (endX < 0)
                    endX = 0;
                var path1 = this.paths[block.row - 1];
                var path2 = this.paths[block.row];
                var chunk1 = path1.slice(startX, endX);
                var chunk2 = path2.slice(startX, endX);
                if (chunk1.length > 1 && chunk2.length > 1) {
                    var textPaddingX = 20;
                    var textPaddingY = 10;
                    var fontSize = this.getBlockFontSize(chunk1, chunk2, textPaddingY);
                    var boxPolyPoints = this.getWavePolygon(chunk1, chunk2.reverse());
                    if (!block.svg) {
                        block.svg = {};
                        block.svg.group = this.svg.group().attr({ "class": 'block', id: block.id });
                        block.svg.group.click(function (e) { _this.onBlockClick(e); });
                        block.svg.box = block.svg.group.polygon().attr({ fill: 'white', stroke: 'none' });
                        block.svg.mask = this.svg.polygon().attr({ fill: 'white', stroke: 'none' }).toDefs();
                        block.svg.textpath = block.svg.group.path().attr({ fill: 'none', stroke: 'white' }).toDefs();
                        block.svg.text = block.svg.group.text(0, 0, block.title).attr({ textpath: block.svg.textpath, mask: block.svg.mask });
                    }
                    block.svg.box.attr({ points: boxPolyPoints });
                    block.svg.mask.attr({ points: boxPolyPoints });
                    block.svg.text.attr({ fontSize: fontSize });
                    if (endX - startX > textPaddingX * 2) {
                        var newPath = this.getPathOffset(path2.slice(startX + textPaddingX, endX - textPaddingX), -textPaddingY, -textPaddingY);
                        if (newPath.length > 2) {
                            var newPathString = this.getWavePathString(newPath);
                            block.svg.textpath.attr({ d: newPathString });
                        }
                    }
                }
                else {
                    if (block.svg) {
                        block.svg.group.remove();
                        block.svg.mask.remove();
                        block.svg = null;
                    }
                }
            }
        };
        Ribbon.prototype.getGuidePath = function (freq, pos, amp, x1, y1, x2, y2) {
            var points = [];
            var width = x2 - x1;
            var x = x1;
            var y = y1;
            var yChange = y2 - y1;
            while (x++ <= width) {
                y = Math.sin(x * freq + pos);
                points.push([x, (y1 + ((width - (width - x)) * (yChange / width)) + (y * amp / 2 + amp / 2))]);
            }
            return points;
        };
        Ribbon.prototype.getPathOffset = function (points, offsetStart, offsetEnd) {
            if (points.length) {
                var x1 = points[0][0];
                var y1 = points[0][1];
                var x2 = points[points.length - 1][0];
                var y2 = points[points.length - 1][1];
                var yChange = offsetStart - offsetEnd;
                var width = x1 - x2;
                var newPoints = [];
                for (var i = 0; i < points.length; i++) {
                    var newPoint = [points[i][0], points[i][1]];
                    newPoint[1] += offsetStart + ((width - (width - i)) * (yChange / width));
                    newPoints.push(newPoint);
                }
                return newPoints;
            }
            return [];
        };
        Ribbon.prototype.getBlockFontSize = function (topPoints, bottomPoints, padding, maxSize, minSize) {
            if (maxSize === void 0) { maxSize = 40; }
            if (minSize === void 0) { minSize = 10; }
            var startHeight = Math.abs(topPoints[0][1] - bottomPoints[0][1]);
            var endHeight = Math.abs(topPoints[topPoints.length - 1][1] - bottomPoints[bottomPoints.length - 1][1]);
            var space = startHeight < endHeight ? startHeight : endHeight;
            space -= padding * 2;
            if (space < minSize)
                space = minSize;
            if (space > maxSize)
                space = maxSize;
            return space;
        };
        Ribbon.prototype.getWavePathString = function (points) {
            // if(points.length < 2) return '';
            var mapped = _.map(points, function (d) {
                return d.join(',');
            });
            return 'M' + mapped.join(' ');
        };
        Ribbon.prototype.getWavePolygon = function (topPoints, bottomPoints) {
            var allPoints = topPoints.concat(bottomPoints);
            var polyString = '';
            for (var i = 0; i < allPoints.length; i++) {
                polyString += allPoints[i].join(' ') + ' ';
            }
            return polyString;
        };
        Ribbon.prototype.onBlockClick = function (e) {
            var selectedBlock = null;
            for (var i = 0; i < e.path.length; i++) {
                if (e.path[i].nodeName == 'g') {
                    selectedBlock = e.path[i].id;
                    break;
                }
            }
            if (selectedBlock)
                this.selectBlock(selectedBlock);
        };
        Ribbon.prototype.resizeSVG = function () {
            this.svg.attr({
                width: this.size.svg.width,
                height: this.size.svg.height
            });
        };
        Ribbon.prototype.onResize = function (event) {
            this.size.svg.width = event.target.innerWidth;
            this.size.svg.height = event.target.innerHeight;
            if (this.svg)
                this.resizeSVG();
        };
        Ribbon.prototype.tick = function (c) {
            var _this = this;
            if (c % 2 == 0) {
                // render 30fps
                this.rootPos += this.speed.rest;
                this.updateRibbon();
            }
            requestAnimationFrame(function () {
                _this.tick(c + 1);
            });
        };
        Ribbon.prototype.toogleState = function () {
            this.setState(this.currentState.type == 'home' ? this.states.selected : this.states.home);
        };
        Ribbon.prototype.selectBlock = function (blockId) {
            if (blockId === 'back')
                return this.deselectBlock();
            var selectedBlockPosition = 100;
            for (var i in this.blocks) {
                if (this.blocks[i].id === blockId || this.blocks[i].type === 'back') {
                    selectedBlockPosition = this.blocks[i].position.current;
                    this.blocks[i].position.target = this.blocks[i].type === 'back' ? 10 : 75;
                }
                else {
                    this.blocks[i].position.target = this.blocks[i].position.current < selectedBlockPosition ? this.blocks[i].position.home - 100 : this.blocks[i].position.home + 100;
                }
            }
            this.setState(this.states.selected);
        };
        Ribbon.prototype.deselectBlock = function () {
            for (var i in this.blocks) {
                this.blocks[i].position.target = this.blocks[i].type == 'menu' ? this.blocks[i].position.home : -100;
            }
            this.setState(this.states.home);
        };
        Ribbon.prototype.setState = function (newState) {
            var transitionSpeed = 2;
            var ease = Power2.easeInOut;
            this.currentState.type = newState.type;
            TweenMax.to(this.currentState.start, this.speed.changeState, { top: newState.start.top, left: newState.start.left, thickness: newState.start.thickness, ease: ease });
            TweenMax.to(this.currentState.end, this.speed.changeState, { top: newState.end.top, left: newState.end.left, thickness: newState.end.thickness, ease: ease });
            TweenMax.to(this.currentState.wave, this.speed.changeState, { amplitude: newState.wave.amplitude, frequency: newState.wave.frequency, ease: ease });
            if (this.currentState.wave.transitionSpeed > this.speed.rest) {
                TweenMax.to(this.speed, this.speed.changeState / 2, { rest: newState.wave.transitionSpeed, ease: Power2.easeIn });
                TweenMax.to(this.speed, this.speed.changeState / 2, { rest: this.defaultRestSpeed, delay: this.speed.changeState / 2, ease: Power2.easeOut });
            }
            else {
                TweenMax.to(this.speed, this.speed.changeState, { rest: this.defaultRestSpeed, ease: ease });
            }
            for (var i = 0; i < this.blocks.length; i++) {
                var block = this.blocks[i];
                if (block.position.current !== block.position.target)
                    TweenMax.to(block.position, this.speed.changeState, { current: block.position.target, ease: ease });
            }
        };
        return Ribbon;
    }());
    var ribbon = new Ribbon(Snap('#svg'));
    ribbon.init();
    @import 'https://fonts.googleapis.com/css?family=Catamaran';
    
    html, body
    {
    	width: 100%;
    	height: 100%;
    	margin: 0;
    	padding: 0;
    	font-family: 'Catamaran', sans-serif;
    }
    
    body {
      background: #eee;
      background: linear-gradient(to left, #ddd , #eee);
    }
    
    .container
    {
    	margin: 0;
    	padding: 0;
    	height: 100%;
    	width: 100%;
    }
    
    svg
    {
    	z-index: 10;
    }
    
    .block
    {
        cursor: pointer;
    
        text
        {
            fill: white;
        }
    
        polygon
        {
            fill: white;
            opacity: 0.3;
            transition: opacity 0.3s ease;
        }
    
        &:hover
        {
            polygon
            {
                opacity: 0.5;
            }
        }
    }
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
        <meta charset="utf-8"/>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.4.1/snap.svg-min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
        <links href="style.css" type="text/css" rel="stylesheet">
      </head>
      <body>
        <div class="container">
          <script src="script.js"></script>
        	<svg id="svg"></svg>
        </div>
      </body>
    </html>

    And for some reason it does work here but Firefox dev edition tells me the following TypeError: this.svg is null. script.js:85:9 and I can't seem to work anything out. for anyone wondering my friend came up with this and for him it's working perfectly fine but he also has no idea what I could do. When answering please do keep in mind that I'm new so go easy on me in case it's really stupid.

  • macOS WebView Download a HTML5 Blob file

    I'm using the HTML5 Blob API to download a file from a JavaScript client in a WebView based macOS application:

    /**
     * Save a text as file using HTML <a> temporary element and Blob
     * @author Loreto Parisi
    */
    var saveAsFile = function(fileName,fileContents) {
        if(typeof(Blob)!='undefined') { // using Blob
            var textFileAsBlob = new Blob([fileContents], { type: 'text/plain' });
            var downloadLink = document.createElement("a");
            downloadLink.download = fileName;
            if (window.webkitURL != null) {
                downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
            }
            else {
                downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
                downloadLink.onclick = document.body.removeChild(event.target);
                downloadLink.style.display = "none";
                document.body.appendChild(downloadLink);
            }
            downloadLink.click();
        } else {
            var pp = document.createElement('a');
            pp.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(fileContents));
            pp.setAttribute('download', fileName);
            pp.onclick = document.body.removeChild(event.target);
            pp.click();
        }
    }//saveAsFile
    

    When the Blob is not supported it uses the standard DOM way. When I run my application within MacGap2 running this code called let's say like saveAsFile('out.json',jsonString);

    it will lead to this error:

    2018-04-23 19:35:08.270857+0200 sendMessageWithDictionary: Failed to get remote object proxy: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.apple.rtcreportingd" UserInfo={NSDebugDescription=connection to service named com.apple.rtcreportingd}
    

    So I have configured the App Sandbox for Outgoing Connections (Client), I have also tried to intercept the link click through the PolicyDelegate:

    - (void)webView:(WebView *)webView decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id < WebPolicyDecisionListener >)listener
    {
        if (WebNavigationTypeLinkClicked == [[actionInformation objectForKey:WebActionNavigationTypeKey] intValue])
        {
            NSLog(@"CLICKED %@", [request URL]);
        }
        [[NSWorkspace sharedWorkspace] openURL:[request URL]];
        [listener ignore];
    }
    
    
    - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation
            request:(NSURLRequest *)request
            frame:(WebFrame *)frame
            decisionListener:(id<WebPolicyDecisionListener>)listener
    {
        if (WebNavigationTypeLinkClicked == [[actionInformation objectForKey:WebActionNavigationTypeKey] intValue])
        {
            NSLog(@"CLICKED %@", [request URL]);
        }
        [listener use]; // Say for webview to do it work...
    }
    

    At this point I can get the Blob url clicked in the latter delegate, so, in the Objective-C / Cocoa Realm, I have approached the following (that currently works on macOS High Sierra / Xcode 9.3 / macOS 10.13

    NSLog(@"CLICKED %@", [request URL]);
            NSString *needle = @"blob:";
            if( [[[request URL] absoluteString] hasPrefix:needle] ) {
                // create a download link from blob url
                NSRange blobRange = [[[request URL] absoluteString] rangeOfString:needle];
                NSString * blobURL = [[[request URL] absoluteString] substringFromIndex:blobRange.location + needle.length];
                NSURLRequest *downloadURLRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:blobURL]];
                NSLog(@"BLOB URL:%@", [[downloadURLRequest URL] absoluteString]);
                NSURLSessionDownloadTask *downloadTask = [[NSURLSession sharedSession] downloadTaskWithRequest:downloadURLRequest
                                                                                             completionHandler:^(NSURL *location, __unused NSURLResponse *response, NSError *error) {
                    if (location) {
    
                        // get download folders
                        NSArray *docDirs = NSSearchPathForDirectoriesInDomains(NSDownloadsDirectory,
                                                                               NSUserDomainMask, YES);
                        NSString *destinationFilename = [docDirs objectAtIndex:0];
                        if (destinationFilename) {
                            destinationFilename = [destinationFilename stringByAppendingPathComponent:@"out.json"];
                            NSLog(@"LOCATION %@ DOWNLOAD %@", [location absoluteString], destinationFilename);
                            NSFileManager *fileManager = [NSFileManager defaultManager];
                            NSError *anError = nil;
                            NSString *fromPath = [location path];
                            if ([fileManager fileExistsAtPath:destinationFilename])
                                [fileManager removeItemAtPath:destinationFilename error:&anError];
                            BOOL fileCopied = [fileManager moveItemAtPath:fromPath toPath:destinationFilename error:&anError];
                            if (fileCopied == NO) {
    
                            } else {
                                NSLog(@"Downloaded!");
                            }
                        }
                    } else {
                        NSLog(@"Error:%@", [error description]);
                    }
                }];
                [downloadTask resume];
                return;
            }
    

    To enable file download I had to additionally enable the Download folders read/write policy in the App Sandbox. Basically now I can intercept the blob: urls that is a typical HTML5 Blob url (blob:https://myserver/BLOB_ID), and I try to download, but - of course 😁 it does not work because that url it seems not be a valid url, so I get an error back from the file server - of course

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    <title>Error</title>
    </head>
    <body>
    <pre>Cannot GET /57de17ae-92bc-4553-a9d8-ac1b0f1f6c4f</pre>
    </body>
    </html>
    

    So despite the fact that the code above is generally working fine for real files (i.e. having a valid URI), I was wrong about the Blob files, since these files are not actual files, so there must be a different way to handle client side Blob urls in a macOS WebView...

  • Disable autoplay on flashplayer embedded video

    I had this html code:

          <iframe class="videoEmb" src="http://player.cntv.cn/flashplayer/players/htmls/smallwindow.html?pid=563b4bb3dd6e41f88390ab46f7f45578" width="854" height="480" frameborder="0" play="false" webkitallowfullscreen mozallowfullscreenallowfullscreen></iframe>
    

    The problem is that this video autoplays, and I already try a lot of options, nothing disabled the autoplay, the video is from a chinese webpage(I have all the permissions over the video), but they have their own player this is the link of the video perhaps you can find a better way to tr the video, thanks you.

  • Can not connect to Db- Dump using codeception

    I am struggling to use the db functionality of codeception framework. The error i am getting is

    Db: could not find mysql driver while creating PDO connection

    actor: AcceptanceTester
    modules:
          enabled: [Db, PhpBrowser]
          config:
               Db:
                  dsn: "mysql:host=localhost;dbname=my_db"
                  user: 'root'
                  password:
                  populate: true
                  cleanup: true
                  dump: 'tests/_data/Dump20180423.sql'
    
               PhpBrowser:
                  url : 
    
    1. My acceptance.suite.yaml file is set like this.
    2. Also my dump file has the CREATE TABLE command inside.
    3. The path for Mysql is already set in the environmental variables path.
    4. The pdo extensions are set inside my php.ini file

    I guess it's a problem with the dsn as it fails before validating my user credentials. Also my mysql works fine. I have projects that i use PDO connection and they work without any issue.

    I tried every solution i could find but still getting the same error. Thank you in advance for any help!!!

  • delete not working with pdo

    The following code is not working even though I've tested it by putting this on the page alone. To make this clear just after this query I'm doing a select query to display all the user in the DB.

    $db->query("DELETE FROM Projet_Client WHERE username = '$_GET[d]'");
    echo "<div class='alert alert-success text-middle'><strong>Succès</strong>, le 
    client a été supprimé.</div>";
    

    Here is the "echo" of the query to show you how it looks like :

    DELETE FROM Projet_Client 
    WHERE 
    username = 'a75ea99ce47306ec259d4c905bb9c3f762a531ee'
    

    (I'm using my sql). Thank you.

    I changed the code ant it looks like this :

        $db->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
        try {
            $stmt = $db->prepare('DELETE FROM Projet_Client WHERE username= :username');
            $stmt->bindParam(':username', $_GET['d']); 
            $stmt->execute();
    
        } catch(Exception $e){
                echo 'Exception -> ';
                var_dump($e->getMessage());
        }
    

    However no exception are being throw.

    The problem has been solved. I had to change the constraint with the foreign key : ON DELETE = CASCADE

  • How to simplify/customize this query?

    I have a table that contains all the columns called user records , I'm using a query that contain some aliases :

    SELECT
        Id,
        Home Phone,
        Cell Phone,
        .. etc ,    
    
    
        //First Alias "User Status"
        If(
            user_Approved Is Null or user_Approved="", If( .. ), "User Approved"
        ) AS User Status,
    
    
    
    
        //Second Alias Permit Status.
        If(
            /*User Status alias goes here*/ ="User Approved", If( .. ) 
        )AS Permit Status,
    
    
    
        //Some More Similar Aliases.
    
    
    FROM users records 
    WHERE ..
    ORDER BY ..
    

    You can find the whole query here:
    https://www.db-fiddle.com/f/nooPsnsW1CthE5rx5f8SZR/1

    Right now to get what I want , I copy the first alias and paste it into the second one like in the link above (at the first line of the second alias), And now the query is very long.

    I want to simplify it and make it much better and maybe just use couple of words to insert the first alias into the second one.