Javascript popup flash mp3 player -- stupid IE

Discussion in 'Web Design and Development' started by Brendon Bauer, Jan 26, 2009.

  1. Brendon Bauer macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #1
    So my problem, as usual, lies with Internet Explorer. I have a link that when clicked is supposed to open a new little window and have a flash payer embedded in it that will play an mp3 file.

    Example link:
    Code:
    <a href="http://www.summitnorthwest.org/sermons/2009/01.17.09.mp3" onclick="javascript:BatmoAudioPop('Puddleglum\'s Perspective',this.href,'1'); return false" target="_blank">Listen to Sermon</a>
    The javascript that takes care of the onclick (and is linked to in the header):
    Code:
    function BatmoAudioPop(filedesc,filepath,WindowNumber) 
    {
        PlayerWin = window.open('',WindowNumber,'width=320,height=230,top=75,left=75,screenX=75,screenY=75,resizable=0,scrollbars=0,titlebar=0,toolbar=0,menubar=0,status=0,directories=0');
    
        PlayerWin.focus();
        PlayerWin.document.writeln("<html><head><title>Audio Sermon Player</title></head>");
        PlayerWin.document.writeln("<body bgcolor='#000000'>"); // specify background img if desired
        PlayerWin.document.writeln("<div align='center'><img src='http://www.summitnorthwest.org/sermons/summitlogosmall.jpg'><br />");
        PlayerWin.document.writeln("<b style ='font-size:18px;color:#d5d5d5;font-family:Lucida,sans-serif;line-height:1.6'>" + filedesc + "</b><br />");
        PlayerWin.document.writeln("<object type='application/x-shockwave-flash' data='http://www.summitnorthwest.org/sermons/mp3player.swf' width='250' height='20'>");
        PlayerWin.document.writeln("<param name='movie' value='http://www.summitnorthwest.org/sermons/mp3player.swf'>");
        PlayerWin.document.writeln("<param name='wmode' value='transparent'>");
        PlayerWin.document.writeln("<param name='FlashVars' value='mp3=" + filepath + "&width=250&autoplay=1&showvolume=1&showloading=always&volumewidth=50&volumeheight=8&loadingcolor=B4B6B3&sliderovercolor=0052B6&buttonovercolor=0052B6&sliderwidth=12'>");
        PlayerWin.document.writeln("</object></div>");
        PlayerWin.document.writeln("<p style='font-size:12px;color:#d5d5d5;font-family:Lucida,sans-serif;text-align:center'><a href='" + filepath +"'>Download this Sermon</a> <span style='font-size:10px;color:#d5d5d5;'>(right-click)</span></p>");
        PlayerWin.document.writeln("<form><div align='center'><input type='button' value='Close this window' onclick='javascript:window.close();'></div></form>");
        PlayerWin.document.writeln("</body></html>");
    
        PlayerWin.document.close();
    }
    In every browser and operating system, except IE, this works perfectly. It opens a popup window and plays the mp3 through the flash player. In IE, one of two things happens. If windows media player is set to play your filetypes, it opens the mp3 in windows media player. If not, it opens a normal sized window and just tries to load the mp3 which takes forever. Why the heck does it do this? Why would WMP take over a .swf playing mp3s?

    EDIT: Solved by removing href link and replacing with #. Stupid IE :\
     
  2. SrWebDeveloper macrumors 68000

    SrWebDeveloper

    Joined:
    Dec 7, 2007
    Location:
    Alexandria, VA, USA
    #2
    Code:
    <a href="http://www.summitnorthwest.org/sermons/2009/01.17.09.mp3" onclick="javascript:BatmoAudioPop('Puddleglum\'s Perspective',this.href,'1'); return false" target="_blank">Listen to Sermon</a>
    Change that to:

    Code:
    <a href="#" onclick="BatmoAudioPop('Puddleglum\'s Perspective','/sermons/2009/01.17.09.mp3','1'); return false" target="_blank">Listen to Sermon</a>
    There are a many variations of "mp3player.swf" so send me the link to the documentation for that specific player and I'll see if one of the parameters is missing or wrong. At this point because the file being passed is an MP3, MSIE is spawning the default Windows MIME association for MP3's, the media player. As to why...

    I don't see anything wrong with your object code which clearly loads the .swf but I need to see the docs to be sure to help you find out!!

    If this swf supports an XML playlist, try it as an experiment and see if Windows loads Adobe Flash properly. I mention this as that's how I used it in one of my pages, never had an issue with WMP. Anyway, I changed the anchor link not to resolve said issue, but because it's more efficient javascript syntax plus the locally hosted MP3 file will load faster since I switched it to a relative path. It's not critical to change the references to your domain in the BatmoAudioPop function since the .swf is very small in size, but... wouldn't hurt. (Side issue, better to use relative paths).

    -jim
     
  3. Brendon Bauer thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #3
    As much as I'd love to do that, I can't :). The main two reasons are: 1) My podcast, through feedburner, only detects the mp3s if I also link to the mp3 in the href portion and 2) I have one post for every week all the way back to 2006. That's a lot of links to change, heh. And it has worked for so long (even in IE) but it seems like just in the last few months it stopped working...

    This is the mp3 player I am using: http://flash-mp3-player.net/players/maxi/

    The idea behind my javascript came from http://digitalmedia.oreilly.com/pub...1/build-a-better-web-audio-player.html?page=2 but I have modified the script he provides by getting rid of mime types etc because I'm not using QuickTime/WMP. All I kept was the javascript function to pass the file desc and file path, and the script to open up the new window (but added the mp3 player embedded in it).

    So, maybe it makes sense now? :D Thanks for your help! I just can't figure it out...
     
  4. SrWebDeveloper macrumors 68000

    SrWebDeveloper

    Joined:
    Dec 7, 2007
    Location:
    Alexandria, VA, USA
    #4
    At this point all you can do is send us the Javascript and we'll see if we can improve. But we also need a feed to test it if you want a for sure fix.
     
  5. Brendon Bauer thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #5
    Location I use this: http://www.summitnorthwest.org/sermonaudio/
    Feed located at: http://feeds.feedburner.com/summitsermonpodcast

    Call to JS file between head tags in wordpress:
    Code:
    <script src="http://www.summitnorthwest.org/sermons/mp3player.js" type="text/javascript"></script>
    Example post code from latest wordpress post:
    Code:
    Speaker: Amy Heald <br />
    Date: 01/17/09 <br />
    Comments: How Can We Believe in a God Who Kills Innocent Children? <br />
    <table><tr><td><img src="http://www.summitnorthwest.org/sermons/mp3.png" width="30" /></td><td valign="middle"><a href="http://www.summitnorthwest.org/sermons/2009/01.17.09.mp3" onclick="javascript:BatmoAudioPop('Puddleglum\'s Perspective',this.href,'1'); return false" target="_blank">Listen to Sermon</a></td></tr></table>
    The actual mp3player.js file:
    Code:
    function BatmoAudioPop(filedesc,filepath,WindowNumber) 
    {
        PlayerWin = window.open('',WindowNumber,'width=320,height=230,top=75,left=75,screenX=75,screenY=75,resizable=0,scrollbars=0,titlebar=0,toolbar=0,menubar=0,status=0,directories=0');
    
        PlayerWin.focus();
        PlayerWin.document.writeln("<html><head><title>Audio Sermon Player</title></head>");
        PlayerWin.document.writeln("<body bgcolor='#000000'>"); // specify background img if desired
        PlayerWin.document.writeln("<div align='center'><img src='http://www.summitnorthwest.org/sermons/summitlogosmall.jpg'><br />");
        PlayerWin.document.writeln("<b style ='font-size:18px;color:#d5d5d5;font-family:Lucida,sans-serif;line-height:1.6'>" + filedesc + "</b><br />");
        PlayerWin.document.writeln("<object type='application/x-shockwave-flash' data='http://www.summitnorthwest.org/sermons/mp3player.swf' width='250' height='20'>");
        PlayerWin.document.writeln("<param name='movie' value='http://www.summitnorthwest.org/sermons/mp3player.swf'>");
        PlayerWin.document.writeln("<param name='wmode' value='transparent'>");
        PlayerWin.document.writeln("<param name='FlashVars' value='mp3=" + filepath + "&width=250&autoplay=1&showvolume=1&showloading=always&volumewidth=50&volumeheight=8&loadingcolor=B4B6B3&sliderovercolor=0052B6&buttonovercolor=0052B6&sliderwidth=12'>");
        PlayerWin.document.writeln("</object></div>");
        PlayerWin.document.writeln("<p style='font-size:12px;color:#d5d5d5;font-family:Lucida,sans-serif;text-align:center'><a href='" + filepath +"'>Download this Sermon</a> <span style='font-size:10px;color:#d5d5d5;'>(right-click)</span></p>");
        PlayerWin.document.writeln("<form><div align='center'><input type='button' value='Close this window' onclick='javascript:window.close();'></div></form>");
        PlayerWin.document.writeln("</body></html>");
    
        PlayerWin.document.close(); // "Finalizes" new window
    }
    Shouldn't that be all you need? Again, thanks for taking a look at this.
     
  6. SrWebDeveloper macrumors 68000

    SrWebDeveloper

    Joined:
    Dec 7, 2007
    Location:
    Alexandria, VA, USA
    #6
    Oops, I wrote that in the wrong topic. That was help for some RSS stuff, I had an alzheimers moment and posted in the wrong tab in FFox. That was not for you.

    My bad, my sincere apologies.

    I already corrected some of YOUR javascript, see my first reply for that. I know you still need to do this because you re-posted the same code with the link the user clicks on to initiate the player.

    Anyway, I looked at the documentation and short of the javascript changes I suggested, you did everything right.

    I'm stumped and it only reminds me why I hate Windows so, so much.

    Anyone else wanna try a crack at this?
     
  7. Brendon Bauer thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #7
    No problem :) I was wondering why you asked that.

    As far as changing each link:
    I'm not even sure if it's possible to update the database or something to change all those links at once... And even if it was, I think my podcast may stop working with feedburner because the mp3's won't be linked. Essentially the reason it was linked straight to the mp3 was for a fall-back in case javascript was disabled or something, but in this case it sounds like that is what is interfering with IE? Is it possible to pass something to IE saying "stop screwing with it and do what it says" lol? Like override the mime types or something? So irritating...
     
  8. Brendon Bauer thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #8
    So I took your advice and tried it and, of course, it works :). Replacing the href portion of the link with # makes it so IE does what it's supposed to. To get the feedburner feed working, though, I have to add a download link next to it with the direct link to the mp3. My only problem now is getting the last 2 years worth of posts working... There are probably around 120 posts total... Is there an easy way to intelligently update the posts? I'm not super experienced in mysql so I'm afraid I'd screw something up. And I don't know how to work with wildcards and whatnot.

    I want to turn this:
    Code:
    <a href="http://www.summitnorthwest.org/sermons/2009/01.17.09.mp3" onclick="javascript:BatmoAudioPop('Puddleglum\'s Perspective',this.href,'1'); return false" target="_blank">Listen to Sermon</a>
    into this:
    Code:
    <a href="#" onclick="javascript:BatmoAudioPop('Puddleglum\'s Perspective','http://www.summitnorthwest.org/sermons/2009/01.17.09.mp3','1'); return false" target="_blank">Listen to Sermon</a> | <a href="http://www.summitnorthwest.org/sermons/2009/01.17.09.mp3">Download</a> <font size="1"><i>(right-click)</i></font>
    Where of course the filepath (year/mm.dd.yy) portion will be different in each post.

    Any tips?
     
  9. SrWebDeveloper macrumors 68000

    SrWebDeveloper

    Joined:
    Dec 7, 2007
    Location:
    Alexandria, VA, USA
    #9
    Okay! Progress.

    As to your other question, to accomplish this you'd write some code, probably PHP, that queries your data and then loop through the result set embedding the proper data into your PHP code which generates each links. You said you're not familiar with MySQL, but that's mostly standard SQL so are you familiar with SQL in general even in other database formats? If the former - start learning, right here.

    I could create some real PHP code that does all that if YOU can somehow tell me the table name and field names involved. But if, for example, the table was named "posts" and there are 2 fields, "filepath" and "posted_on" (datetime field) a query could be as simple as (untested generic code for demo purposes only, highly simplified):

    PHP:

    // This scripts assumes you've already connected to a database via PHP
    // Create a mysql query, get last two years of data...

    $sql="select distinct filepath, posted_on from posts 
    where YEAR(posted_on) >= YEAR(NOW())-2 
    order by posted_on desc"


    // Run the query and get result 

    $result mysql_query($sql) or die(mysql_error());

    // Loop through the result set which now is passed to an associative array where the
    // the field names become key names in the array, conveniently...

    while($row mysql_fetch_assoc($result)){

    // Based on the posted_on date, get the year and full date (matching
    // the filename syntax as you posted here on MacRumors)...

    $year=date("Y",strtotime($row['posted_on'])); // i.e. "2007"
    $full_date=date("d.j.y",strtotime($row['posted_on'])); // i.e. "mm.dd.yy"

    // Embed our variables into a print statement that generates each link...

    print"
    <a href=\"#\" onclick="
    javascript:BatmoAudioPop('Puddleglum\'s Perspective','http://www.summitnorthwest.org/{$row['filepath']}
    /$year/$full_date.mp3'
    ,'1'); return false\" target="_blank">Listen to Sermon Added on $full_date.mp3</a> ";

    }

    Get the idea?

    -jim
     
  10. Brendon Bauer thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #10
    Well this is all done through wordpress so there is no individual fields for specific things. It's just one longtext field containing the entire post.

    The table name is: wp_2posts
    The field name is: post_content

    We have sort of a template in wordpress and just edit the dates/speaker/mp3 file. So it all goes into one field. That's why I am wondering how I can do this. Like it will have to search for href="ABC" where ABC is the link to the mp3 with wildcards and then delete ABC and replace it with a #, and then somehow append after the link to play a download link directed towards ABC. See where I'm getting? I didn't really think about using PHP for it. I was thinking I'd have to run it as sql in myphpadmin. I am much more familiar with php, but I don't know what exactly I'd do for this since I've never done anything like this.

    Again, thanks for your time!

    An example post_content from the latest post that I fixed (before I fixed the problem):
    Code:
    Speaker: Amy Heald <br />
    Date: 01/17/09 <br />
    Comments: How Can We Believe in a God Who Kills Innocent Children? <br />
    <table><tr><td><img src="http://www.summitnorthwest.org/sermons/mp3.png" width="30" /></td><td valign="middle"><a href="http://www.summitnorthwest.org/sermons/2009/01.17.09.mp3" onclick="javascript:BatmoAudioPop('Puddleglum\'s Perspective',this.href,'1'); return false" target="_blank">Listen to Sermon</a></td></tr></table>
     
  11. SrWebDeveloper macrumors 68000

    SrWebDeveloper

    Joined:
    Dec 7, 2007
    Location:
    Alexandria, VA, USA
    #11
    I follow and know exactly what you need and will do it in one simple PHP script for ya, but please do me a favor and use phpMyAdmin to select that table, then in the structure tab use the "Print View" feature. Please copy/paste all the "auth" stuff (field information) here so I can see all the fields and create the best query which is important to my scripting.

    Thanks!

    -jim
     
  12. Brendon Bauer thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #12
    Ok, this should be it. The longtext field is the one that needs working with :)
     

    Attached Files:

  13. SrWebDeveloper macrumors 68000

    SrWebDeveloper

    Joined:
    Dec 7, 2007
    Location:
    Alexandria, VA, USA
    #13
    Okay, I got the table structure, thanks.

    Now I need to see how all those fields in that table are set for an actual record - as an example. Do a search or browse in phpMyAdmin to find a typical record with an MP3 in the post_body, but include all fields in the results, then print view and attach, please (just one record).

    And just to clarify, overall you want to query the database to find any post within the last 2 years that includes MP3 stuff in the post_body, then extract the path and filename of the MP3 and generate only the full mp3player link for each? Is this right?

    -jim
     
  14. Brendon Bauer thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #14
    I want to make this:
    Code:
    Speaker: Amy Heald <br />
    Date: 01/17/09 <br />
    Comments: How Can We Believe in a God Who Kills Innocent Children? <br />
    <table><tr><td><img src="http://www.summitnorthwest.org/sermons/mp3.png" width="30" /></td><td valign="middle"><a href="http://www.summitnorthwest.org/sermons/2009/01.17.09.mp3" onclick="javascript:BatmoAudioPop('Puddleglum\'s Perspective',this.href,'1'); return false" target="_blank">Listen to Sermon</a></td></tr></table>
    Turn into this:
    Code:
    Speaker: Amy Heald <br />
    Date: 01/17/09 <br />
    Comments: How Can We Believe in a God Who Kills Innocent Children? <br />
    <table><tr><td><img src="http://www.summitnorthwest.org/sermons/mp3.png" width="30" /></td><td valign="middle"><a href="#" onclick="javascript:BatmoAudioPop('Puddleglum\'s Perspective','http://www.summitnorthwest.org/sermons/2009/01.17.09.mp3','1'); return false" target="_blank">Listen to Sermon</a> | <a href="http://www.summitnorthwest.org/sermons/2009/01.17.09.mp3">Download</a> <font size="1"><i>(right-click)</i></font></td></tr></table>
    The changes above include:
    1) remove linktosermon.mp3 in href portion of Listen to Sermon link and replace with #.
    2) The javascript initially passed this.href. It should now pass 'linktosermon.mp3'
    3) append some text and a second link
    Code:
     | <a href="http://www.summitnorthwest.org/sermons/2009/01.17.09.mp3">Download</a> <font size="1"><i>(right-click)</i></font>
    after the Listen to Sermon link that would link directly to the mp3 using the linktosermon.mp3 from step 1.


    Attached is a pdf of what you asked for (I think). The one at the top is one I have fixed manually to be what I want. The 2nd and the rest on down are ones that are examples of what needs to be fixed. The only changes occur in the field post_content.
     

    Attached Files:

  15. Brendon Bauer thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
  16. SrWebDeveloper macrumors 68000

    SrWebDeveloper

    Joined:
    Dec 7, 2007
    Location:
    Alexandria, VA, USA
    #16
    Brendon, a little patience, next time? I told you I'd knock this out for you, why else would I ask for the SQL data? ;)

    I've written and tested a complete solution for you (meaning I setup a tiny table, actually ran the script). :cool:

    All you need to do is create a PHP script with the following code. I wrote it as a class since I knew you'd be configuring it for your own needs, plus classes are super cool for things like this. The top part initiates the class and allows you to set all the options including database stuff, and the rest is the class. Most of it is about setting options and making sure MySQL connects properly with complete error trapping, and the function named "GetUpdatedPosts" near the bottom of the class does all the searching and replacing of links to make the output just the way you specified. I added in an option to include any HTML you want as a separator between each post. You mentioned you knew PHP so I didn't comment it for novices, it's pretty self explanatory.

    Create a PHP file as follows and edit the arguments passed to the various object methods to work on your system:

    PHP:
    // Extract posts within last x years from WordPress2 database and re-format MP3Player links.
    // Initiative the class as an object then call various methods to set important runtime criteria.

    $obj=new ExtractPosts();
    $obj->SetYearsBack("2");
    $obj->SetSeparatorHTML("<hr size='1' width='100%' color='black' noshade='noshade' />");
    $obj->SetDatabase("wordpress");
    $obj->SetTable("wp_2posts");
    $obj->SetHost("localhost");
    $obj->SetUser("username");
    $obj->SetPassword("password");

    // Output
    print $obj->GetUpdatedPosts();

    // The End - what follows below is the class which I put in the same script for simplicity sake.
    // In the real world save the class as a separate PHP file and using PHP's require_once to load it.

    //////////////////////////////////
    // DO NOT EDIT BELOW THIS LINE //
    ////////////////////////////////

    /*
        * @class   ExtractPosts 
        * @version 1.0
        * @author  Jim Goldbloom
        * @date    1/29/2009
        * @desc    Extract posts within last x years from WordPress2 database and re-format MP3Player links
        * @access  public
    */

    class ExtractPosts {
        
            var 
    $YearsBack=2;
            var 
    $sqltable="wp_2posts";
            var 
    $separatorHTML;
            var 
    $sqldb;
            var 
    $sqlhost;
            var 
    $sqluser;
            var 
    $sqlpass;
            var 
    $sqlconnection_id;
            var 
    $sqllink_id;
            
            function 
    DBConnect() {
            
                
    $this->sqlconnection_id mysql_connect($this->sqlhost$this->sqluser$this->sqlpass)
                                       or 
    $this->DisplayError("Database connection error<br />•".mysql_error());

                
    $this->sqllink_id mysql_select_db($this->sqldb,$this->sqlconnection_id
                                       or 
    $this->DisplayError("Database selection error<br />• ".mysql_error());
            }
            
            function 
    ProcessQuery() {
                    
                
    $sql="select post_content from {$this->sqltable} 
                      where YEAR(post_date) >= YEAR(NOW())-
    {$this->YearsBack}
                      and post_category='0'
                      and post_status='publish'
                      and lower(post_content) like '%.mp3%' 
                      order by post_date desc"
    ;
                      
                
    $result mysql_query($sql
                        or 
    $this->DisplayError("Query processing error<br />• Query [$sql]<br />• ".mysql_error());
                return 
    $result;

            }

            function 
    SetDatabase ($sqldbdata) {
            
                if (!empty(
    $sqldbdata)) {$this->sqldb=$sqldbdata;}
                else {
    $this->DisplayError("The database name was not defined using \$obj->SetDatabase(\"name\");");}
            
            }

            function 
    SetTable ($sqltabledata) {
            
                if (!empty(
    $sqltabledata)) {$this->sqltable=$sqltabledata;}
                else {
    $this->DisplayError("The table name was not defined using \$obj->SetTable(\"name\");");}
            
            }

            function 
    SetHost ($sqlhostdata) {
            
                if (!empty(
    $sqlhostdata)) {$this->sqlhost=$sqlhostdata;}
                else {
    $this->DisplayError("The host name was not defined using \$obj->SetHost(\"hostname\");");}
            
            }

            function 
    SetUser ($sqluserdata) {
            
                if (!empty(
    $sqluserdata)) {$this->sqluser=$sqluserdata;}
                else {
    $this->DisplayError("The user name was not defined using \$obj->SetUser(\"username\");");}
            
            }

            function 
    SetPassword ($sqlpassdata) {
            
                if (!empty(
    $sqlpassdata)) {$this->sqlpass=$sqlpassdata;}
                else {
    $this->DisplayError("The password was not defined using \$obj->SetPassword(\"password\");");}
            
            }

            function 
    SetYearsBack ($YearsBackData) {
            
                
    $YearsBackData=abs(intval($YearsBackData));
                if (
    $YearsBackData<|| $YearsBackData>30) {
                    
    $this->DisplayError("The years back value must be between 1 and 30");
                }
                else {
    $this->YearsBack=$YearsBackData;}
                
            }

            function 
    SetSeparatorHTML ($separatorHTMLdata) {
            
                if (!empty(
    $separatorHTMLdata)) {$this->separatorHTML=$separatorHTMLdata;}
            
            }
            
            function 
    GetUpdatedPosts() {
            
                
    $this->DBConnect();
                
    $resultset=$this->ProcessQuery();
                
    $buffer='';
                
    $counter=0;
                
                while(
    $row mysql_fetch_assoc($resultset)) {
                
                    
    $counter++;
                    
    $post=trim($row['post_content']);
                    
                    
    preg_match("/href=\"(.*).mp3\"/",$post,$matches);
                    
    $post=preg_replace("/href=\"(.*).mp3\"/","href=\"#\"",$post);
                    
    $post=preg_replace("/this.href/","'{$matches[1]}.mp3'",$post);
                    
    $post=preg_replace("/<\/td><\/tr><\/table>/"," | <a href=\"{$matches[1]}.mp3\">Download</a> <font size=\"1\"><i>(right-click)</i></font></td></tr></table>",$post);
                
                    
    $buffer.=$post;
                    if (
    $counter mysql_num_rows($resultset)) {$buffer.=$this->separatorHTML;}

                    unset (
    $matches,$post);
                
                }
                
                return 
    $buffer;
        
            }
            
            function 
    DisplayError($msg) {
            
                print 
    "<br />• Critical error in class ExtractPosts: $msg<br />• Aborting...<br />";
                exit(
    1);
        
            }

        } 
    // end class
    Pretty darned cool, huh?

    -jim
     
  17. Brendon Bauer thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #17
    Wow I feel like a jerk. Sorry for being impatient... You went to a lot of work! :eek: I don't know how to say thank you enough... Parts of it are definitely a little above my knowledge of php but I understand the gist of it. I just couldn't write that on my own without referencing every 5 seconds and trial and error for about 2 weeks :p. Or at all lol.

    I have one question though. I was looking back at the oldest posts I have and I noticed one thing that might mess it up. The last preg_replace looks for
    Code:
    </td></tr></table>
    which is what every post after October 2007 ends with. I just realized that from October 2007 and before there is a dumb tbody tag...
    Code:
    </td></tr></tbody></table>
    I honestly don't even know why I used that tag because I don't even know what it is. So I assume we can do one of two things: 1) search for the 'td tr table' string OR the 'td tr tbody table' string and then replace based on which it is or 2) remove both the beginning and end tbody tags in each post before continuing with the script you wrote. I would prefer option number 2 because the tbody tag is not even necessary and doesn't change anything when you delete it and because it seems like that would be easier to do.

    Again, thank you for all the work you have done. It amazes me how nice people are :).

    Here is an example of a post with the tbody tag:
    Code:
    Speaker: Ron Hessel<br />
    Date: 10/20/07<br />
    Comments: Part of the sermon series Summit Northwest at Nick@Night: God's Top Ten List.<br />
    <table><tbody><tr><td><img src="http://www.summitnorthwest.org/sermons/mp3.png" width="30" /></td><td valign="middle"><a href="http://www.summitnorthwest.org/sermons/2007/10.20.07.mp3" target="_blank" onclick="javascript:BatmoAudioPop('Liar, Liar, Pants on Fire',this.href,'1'); return false">Listen to Sermon</a></td></tr></tbody></table>
    PS: I plan on backing up the database of course, but I'm a little unclear as to what I need to do with your script:

    Do I just copy the entire script you gave me into one php file, modify user/pass and whatnot, and include_once it? Or do the variables at the top go in a .php file which then include_once's a php page that contains the rest of it? I assume it shouldn't matter as long as it all gets run together.

    Also, where do I run this from? Does it need to be the wordpress directory, or can it be from anywhere on my server? I just upload the file to my server and point my browser there to initiate it?

    I'll wait to hear from you regarding the tbody problem and my questions above before I do anything dumb ;)
     
  18. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #18
    Just a FYI on the tbody tag. As the name insinuates, it's for the body of the table. There's also a thead for the header region, and a tfoot for the footer region of the table. These tags let you make your table more semantic and using tbody in the table is required in certain cases for validity reasons and doing some actions in JavaScript on tables that work cross-browser. The thead and tfoot are also handy because when you print a table that spans across multiple pages the thead and tfoot will be printed at the top and bottom of each page (not supported in all browsers).
     
  19. Brendon Bauer thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #19
    So is it recommended to keep those tags? I really don't remember putting them in there because I haven't ever used them before. Could they have been put there automatically by WordPress when it was parsed? Like when I had an older version of wordpress back then?

    (good to see you around angelwatt--you've been a big help in the past too:rolleyes:)
     
  20. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #20
    It may have been from WordPress. At this point it's not necessary to add it, but wouldn't hurt if you want to. Since you have other issues you're working out I wouldn't worry about it.
     
  21. SrWebDeveloper macrumors 68000

    SrWebDeveloper

    Joined:
    Dec 7, 2007
    Location:
    Alexandria, VA, USA
    #21
    Relax, this is easy to work around. Also, I write lots of classes, I stole all the DB code from my other class templates, so it didn't take as long as you think.

    Find (near the end):

    PHP:
    $post=preg_replace("/<\/td><\/tr><\/table>/"," | <a href=\"{$matches[1]}.mp3\">Download</a> <font size=\"1\"><i>(right-click)</i></font></td></tr></table>",$post);
    Insert directly below that line the following NEW single line of code (copy/paste to avoid errors):

    PHP:
    $post=preg_replace("/<\/td><\/tr><\/tbody><\/table>/"," | <a href=\"{$matches[1]}.mp3\">Download</a> <font size=\"1\"><i>(right-click)</i></font></td></tr></tbody></table>",$post);
    Simple as that. PHP's preg_replace returns the original subject if no match is found, so each line will take care of each situation and not affect the other.

    To install:

    Keep it as a single file for simplicity. Edit the MySQL database, host, username, password stuff at the top, same settings WordPress uses in its config -- i.e. if your database is named wordpress2, use $obj->SetDatabase("wordpress2"); and if your MySQL username is "bob", use $obj->SetUser("bob"); at the top of the script. Do the same for the rest, using your values.

    Don't forget to add <?php on the first line and ?> on the last line so your web server parses the PHP correctly. I did not add those here on the forum. Name it ExtractPost.php, save it to the sermonaudio folder (suggestion). Then to display it select whatever existing PHP file you want it to appear (i.e. your home page in the "sermonaudio" folder, assuming your home page is index.php) or any *.php page or even any template that might support PHP commands (if applicable), and simply add one of the following command at the exact position you want it to show up:

    Example same folder as the PHP script in which it is called: include_once "ExtractPost.php";
    Example FULL physical path: include_once $_SERVER['DOCUMENT_ROOT']."/path/to/ExtractPost.php"; and adjust the /path/to accordingly.
    Example relative path: include_once "../ExtractPost.php"; // i.e. one level up, use ../../ if two levels up, etc., use folder/ if in folder which is a child of the current directory

    Help on the "include" PHP command can be found here. The require command is identical in terms of path, it just throws an error when you get the path wrong. Where you end up saving this is up to you.
    Help learning about PHP object oriented programming (classes) - check it out when you have time. It's the method I used here.

    That should do it, Brendon. Cheers.

    -jim
     
  22. Brendon Bauer thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #22
    So I did exactly as you told me to and it didn't change them. When I loaded the page that contained the include_once it outputted all of the posts on the screen in their fixed format, but when I go to the wordpress page and hit refresh it is no different? I must have goofed something up...

    1) I copied your script into ExtractPost.php in the sermonaudio file.
    2) I added the line to take care of the tbody tag.
    3) I modified the database, username, password and # of years to exactly what was in wp-config.php.
    4) I created runExtractPost.php which was a simple page with the include_once line (in php tags of course).
    5) I pointed my browser to runExtractPost.php and it outputted very quickly the entire list of posts in their fixed formats. The progress bar was no longer running after this point. In a different tab I looked to see if the changes took place but nothing has changed.

    Here's a screenshot for the heck of it. It screwed up the latest post because I had already fixed it but thats fine :). http://dl.getdropbox.com/u/145201/Screenshot 1.jpg

    Any idea what happened? I'm afraid to close the tab with runExtractPost.php lol
     
  23. SrWebDeveloper macrumors 68000

    SrWebDeveloper

    Joined:
    Dec 7, 2007
    Location:
    Alexandria, VA, USA
    #23
    Brendon, this is just a minor misunderstanding - when I said "query" and "find" when clarifying to you what the script should do, that meant you'd want what most people would request -- find posts in WP then fix/show those posts imported into your own web page -- not actually update the WP database (a hack of sorts). Combine that with me seeing your own code to spawn the player with no mention of modifying WP data in your original post, you see where my mind was. My apologies, toss the old script.

    Okay, NO problem at all! Honest! ;)

    I will modify it to be a simple utility script that you will run as standalone (i.e. save it in /sermonaudio and run it by typing into your browser www.summitnorthwest.org/sermonaudio/ExtractPosts.php and it'll update all affected posts in the WP database for you with the link changes. When it's done it'll tell you how many records were updated, simple as that.

    I'll add in a query constraint to make sure it skips any posts you changed manually in the database. The config options at the top of the script will be the same as before.

    ETA is the same as before, patience please, I'll re-post it here when done - just it'll do what you want this time! To all others wishing to help, I got this one covered.

    -jim
     
  24. SrWebDeveloper macrumors 68000

    SrWebDeveloper

    Joined:
    Dec 7, 2007
    Location:
    Alexandria, VA, USA
    #24
    All done.

    Here is the complete source...

    PHP:
    <?php

    // Extract and update posts within last x years in WordPress2 database and re-format posts with MP3Player links.
    // Initiative the class as an object then call various methods to set important runtime criteria.

    $obj=new ExtractPosts();
    $obj->SetYearsBack("2");
    $obj->SetDatabase("wordpress");
    $obj->SetTable("wp_2posts");
    $obj->SetHost("localhost");
    $obj->SetUser("user");
    $obj->SetPassword("password");

    // Output
    print $obj->GetUpdatedPosts();

    // The End - what follows below is the class which I put in the same script for simplicity sake.

    //////////////////////////////////
    // DO NOT EDIT BELOW THIS LINE //
    ////////////////////////////////

    /*
        * @class   ExtractPosts and Update
        * @version 1.1
        * @author  Jim Goldbloom
        * @date    1/30/2009
        * @desc    Extract and update posts within last x years in WordPress2 database
        * @access  public
    */

    class ExtractPosts {
        
            var 
    $YearsBack=2;
            var 
    $sqltable="wp_2posts";
            var 
    $sqldb;
            var 
    $sqlhost;
            var 
    $sqluser;
            var 
    $sqlpass;
            var 
    $sqlconnection_id;
            var 
    $sqllink_id;
            
            function 
    DBConnect() {
            
                
    $this->sqlconnection_id mysql_connect($this->sqlhost$this->sqluser$this->sqlpass)
                                       or 
    $this->DisplayError("Database connection error<br />•".mysql_error());

                
    $this->sqllink_id mysql_select_db($this->sqldb,$this->sqlconnection_id
                                       or 
    $this->DisplayError("Database selection error<br />• ".mysql_error());
            }
            
            function 
    ProcessQuery($sql) {
                      
                
    $result mysql_query($sql
                        or 
    $this->DisplayError("Query processing error<br />• Query [$sql]<br />• ".mysql_error());
                return 
    $result;

            }

            function 
    SetDatabase ($sqldbdata) {
            
                if (!empty(
    $sqldbdata)) {$this->sqldb=$sqldbdata;}
                else {
    $this->DisplayError("The database name was not defined using \$obj->SetDatabase(\"name\");");}
            
            }

            function 
    SetTable ($sqltabledata) {
            
                if (!empty(
    $sqltabledata)) {$this->sqltable=$sqltabledata;}
                else {
    $this->DisplayError("The table name was not defined using \$obj->SetTable(\"name\");");}
            
            }

            function 
    SetHost ($sqlhostdata) {
            
                if (!empty(
    $sqlhostdata)) {$this->sqlhost=$sqlhostdata;}
                else {
    $this->DisplayError("The host name was not defined using \$obj->SetHost(\"hostname\");");}
            
            }

            function 
    SetUser ($sqluserdata) {
            
                if (!empty(
    $sqluserdata)) {$this->sqluser=$sqluserdata;}
                else {
    $this->DisplayError("The user name was not defined using \$obj->SetUser(\"username\");");}
            
            }

            function 
    SetPassword ($sqlpassdata) {
            
                if (!empty(
    $sqlpassdata)) {$this->sqlpass=$sqlpassdata;}
                else {
    $this->DisplayError("The password was not defined using \$obj->SetPassword(\"password\");");}
            
            }

            function 
    SetYearsBack ($YearsBackData) {
            
                
    $YearsBackData=abs(intval($YearsBackData));
                if (
    $YearsBackData<|| $YearsBackData>30) {
                    
    $this->DisplayError("The years back value must be between 1 and 30");
                }
                else {
    $this->YearsBack=$YearsBackData;}
                
            }

            function 
    GetUpdatedPosts() {

                
    // Create HTML...
                
    $buffer="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
                \"http://www.w3.org/TR/html4/loose.dtd\">
                <html>
                <head>
                <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">
                <title>Wordpress2 Extract and Update Utility</title>
                </head>
                <body>
                
                <strong><span style='text-decoration: underline'>
                Utility to Extract and Update WordPress2 Posts with proper MP3Player Links
                </span><br /><br />Working, please wait...</strong>
                "
    ;
            
                
    // Connect to DB and extract posts including post ID for later update...
                
    $this->DBConnect();

                
    // Query to extract unmodified posts
                
    $sql="select ID, post_content, post_title, post_date from {$this->sqltable} 
                      where YEAR(post_date) >= YEAR(NOW())-
    {$this->YearsBack}
                      and post_category='0'
                      and post_status='publish'
                      and lower(post_content) like '%.mp3%' 
                      and lower(post_content) like '%this.href%' 
                      order by ID asc"
    ;

                
    $resultset=$this->ProcessQuery($sql);
                
                if (
    mysql_num_rows($resultset)) {
                
                    
    $counter=0;
                    
    $buffer.="<br /><br />";
        
                    
    // Begin processing of each post...            
                    
    while($row mysql_fetch_assoc($resultset)) {
                    
                        
    $counter++;
                        
    $id=$row['ID'];
                        
    $post=trim($row['post_content']);
                        
    $title=trim(stripslashes($row['post_title']));
        
                        
    // Change links within post...                
                        
    preg_match("/href=\"(.*).mp3\"/",$post,$matches);
                        
    $post=preg_replace("/href=\"(.*).mp3\"/","href=\"#\"",$post);
                        
    $post=preg_replace("/this.href/","'{$matches[1]}.mp3'",$post);
                        
    $post=preg_replace("/<\/td><\/tr><\/table>/"," | <a href=\"{$matches[1]}.mp3\">Download</a> <font size=\"1\"><i>(right-click)</i></font></td></tr></table>",$post);
                        
    $post=addslashes($post);
        
                        
    // Update database with modified post...
                        
    $sql="update {$this->sqltable} set post_content='$post' where ID='$id'";
                        
    $this->ProcessQuery($sql);
        
                        
    // Set update status and display information for this post...
                        
    $status=(mysql_affected_rows) ? "<span style='color: green'>Updated</span>" "<span style='color: red'>Failed to Update</span>";
                        
    $buffer.="Processing Post ID: $id Title: $title Status: $status<br />";
        
                        
    // Memory cleanup...
                        
    unset ($matches,$post,$id,$title,$status);
                    
                    }
                    
                    
    // End of report and HTML page...
                    
    $buffer.="<br /><strong>Finished!</strong><br />
                    <br /><strong>Total Posts Updated: 
    $counter</strong>";
                }
                
                
    // If no posts found during query...
                
    else {
                
                    
    $buffer.="<strong>Finished!</strong><br />
                    <br /><span style='color: red'><strong>** Either you ran this utility earlier or no posts were found that need to be updated! **</strong></span>"
    ;
            
                }
                    
                
    $buffer.="</body></html>";
                
                return 
    $buffer;
        
            }
            
            function 
    DisplayError($msg) {
            
                print 
    "<br />• Critical error in class ExtractPosts: $msg<br />• Aborting...<br />";
                exit(
    1);
        
            }

        } 
    // end class

    ?>
    Don't forget to re-configure the top stuff like you did in the other script and then save it as ExtractPost.php in your /sermonaudio folder and run it by typing into your browser "www.summitnorthwest.org/sermonaudio/ExtractPosts.php". Enjoy! :) :) :)

    -jim
     
  25. Brendon Bauer thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #25
    To fix the ones with the tbody tag I still need to add this line, same as before right?
     

Share This Page