The point of the Islamic acts of worship

A question received on tumblr:

What are the importances of acts of worship Prayer, zakat and fasting etc

At the most basic level these acts reaffirm God’s important in our lives. We Muslims cannot ignore God, saying “we have faith” and then go for days without thinking about God. The prayers interrupt our lives five times a day. Fasting interrupts a whole month of the year.

As for zakat, it provides basic income to the poor. If the people of the United States paid zakat, it could amount to $100 to $500 billion dollars a year, meaning that within a few years there wouldn’t be a single homeless or poor person in the country, and every poor person (belonging to the bottom 50% of society) would get a monthly income of $1000 or more from zakat.

As far as I know no Muslim country properly applies the zakat system, which is why there is so much widespread poverty in countries like Egypt. Zakat has to be taken, it is not a voluntary act. Most rich people are not generous and would rather not pay 2.5% of their uninvested wealth to the poor every year, they would rather do as the Jews and Christians of America do, lending their wealth to the poor and charging them 5% or more interest.

In the zakat system, the poor charge interest on rich people’s uninvested wealth, the money they hoard in their bank accounts. In America’s usurious system, the rich charge interest on the poor, to the tune of more than a trillion dollars per year. American taxpayers paid upwards of $200 billion on money borrowed from usurers to pay for government expenditures, which is why the rich and powerful of America constantly want to increase the size of the military and to instigate new wars, such as with Iran and Russia. War requires spending, and the money for it has to be borrowed from the rich, and the interest on that money has to be paid by the average taxpayer.

For the rich, war always means money. Islam breaks this cycle of evil and destruction by prohibiting usury (all charging of interest) and enforcing zakat.

As for other acts of worship, they all have some wisdom if you look into them.

What to do when your spouse is less religious than you

A question I received recently:

I am in my early twenties and have married a woman who comes from a Muslim family. After marrying her, I have found that religion is not very important to her. I had wished to marry a woman who was my equal in faith, so that we could create a faithful family together. I feel like I have made a mistake in marrying her, and I don't know where to go from here. Why did God allow me to marry her?

My answer:

It is normal to start having doubts after marriage when you have no previous experience with it. Many ideas and assumptions about the other sex will be proven false or inaccurate once you are living the reality of marriage.

Women are generally more liberal than men and laxer when it comes to religion. I come from a conservative Muslim family but I’ve had trouble convincing close female relatives to stop engaging in negative gossip about people (i.e. backbiting, ghaibah). I know a woman who is a civil engineer (so she is educated and intelligent enough to know better), and even though she went to an Islamic boarding school where they recited Quran every night and sometimes stayed up all night for prayer, she continues to think it is her every right to gossip about people.

When dealing with women, always remember Imam al-Shafi`i’s saying: “Be harsh on yourself, easy on others.” You shouldn’t hold your wife to the same standards as yourself, and if she does the minimum that is requested of her by religion, you should be thankful for that.

I grew up knowing many great men in my extended family, highly religious, kind and observant men. But almost none of these men had wives who could match them in faith, and some had wives who only did the minimum and didn’t care about religion at all. This hasn’t stopped them from bringing up good religious families.

In a household, men and women are not equal when it comes to authority. The Quran gives men a degree of authority over women (Quran 2:228, 4:34), and perhaps part of the reason for that is that men are, in general, more observant and more conservative, though a minority of women can be found who are like this too. It is a man’s duty to keep standards high in his household, preventing lax behaviors like not praying, not fasting or eating what is not halal, though he must do this with love and kindness, not with authoritarianism:

"Invite to the way of your Lord with wisdom and good advice, and debate with them in the best possible manner."1

If your wife does the obligatory deeds (praying, fasting, etc.) and avoids haram (alcohol, interest, etc.), then this is the most you can expect of her, and leave it to her as a free-willed human being to make up her mind to do more if she wants. If she doesn’t do the obligatory deeds or engages in haram, then you have a clear right to give her an ultimatum, for her to come back to the Straight Path and do the minimum of what’s requested of her in Islam. If she doesn’t, then in effect she is refusing to do what the Quran asks of her, meaning that she is denying its truth, and in a way she is a non-believer. There is no obligation for you to stay married to her in such a case.

If she does the minimum required of her, then the Quran encourages you to be patient and to rely on God to steer your destiny for you. The Quran says in 4:128 that when a (devoutly Muslim) husband and wife are in disagreement, making peace is always the best option, and warns them to be wary of their ego’s greedy desire for better things.

One of the companions of the Prophet didn’t like his wife. The Prophet told him to fear God and keep her, this advice of the Prophet to him is recorded in the Quran in verse 33:37. The companion (Zayd, the only companion mentioned by name in the Quran) ultimately decided to divorce her. So, while Islam teaches that a man should hold onto his wife, a man’s right of freedom of choice is respected.

A man’s role in life is to acquire worth, marry a woman, have children, take care of his family, and in this way continue Islamic civilization. For this to be successfully done, it is not necessary for the woman to be as religious as the man. Ideally, of course, that’s what we want, but in reality, the nature of men and the nature of women is different, and you will have a very hard time finding women who cares about religion as much as you do.

It is better to be practical. To be thankful for what God has given you and to try to make the best of it. Do your best to be kind, generous, patient and forgiving, rather than judgmental and demanding. Some men mistakenly try to force their women to become what they want, only to give up after years of futile effort. You must learn to trust God and leave it to Him to steer your destiny. If you do separate in the end, you should be able to say “I did my best to make things work, but it didn’t work out.”

I am not saying to be like a feather in the wind, going wherever life throws you. You must rather always face God, working to please Him. You must not face your wife constantly trying to change her. She is only a small part of the big picture. You are a servant of God and you were made to serve Him. He recommends that you try to make your marriage work even if you are not pleased with your wife. Since you are facing God and aiming to please Him, you will be kind, generous and non-judgmental toward your wife as long as she does the minimum that Islam asks of her. Whether you think she deserves this lenient treatment or not, you are not doing it for her, but for God, and you expect your reward from God.

Having an unsatisfactory wife is a difficult test since you might be thinking that maybe this is how things will be for the rest of your life. You do not want to be stuck with someone who doesn’t live up to your standards. You probably wish to get in charge of your destiny, get rid of her and get a far better woman in her place.

The problem with this is that 1. It is not your job to manage your destiny and 2. No matter how good the imaginary new woman is, assuming you can find her and marry her, you could run into new and unexpected problems that could make your life with her miserable, she may develop an illness, she may suffer an accident and go blind, she may have a bad family who constantly interfere with your life.

As a Muslim, you believe that God is the King of the universe, and that He has the power to do anything He wills. He had the power to prevent your marriage from taking place. He had the power to make you marry the perfect woman. But He didn’t. And today He has the power to swiftly end your marriage with little effort on your part, and He has the power to give you the type of woman you desire. But He doesn’t.

It is God who manages your destiny, taking you from one stage of life to another, testing you, helping you learn, helping you grow in wisdom, understanding and kindness. Your focus should be on God, He can take your life anywhere He wants, and He has the power to do it this instant if He wanted to. Since He is not doing it, that should tell you something. You must do your best in the current test you are in, you must follow His advice that trying to make your marriage work is better than separation, and the Prophet’s advice to fear God and hold onto your wife, and leave it to God to change your situation if and when He wants. You must expect only from God and ask only of Him.

You could of course ask, “What if this test is not intended for me? What if I will needlessly suffer for nothing?” If you put your focus on God, since you know that He has the power to take you out of any unwanted situation, then you will know that there is no such thing as needlessly suffering. If you keep your wife for the sake of God, God will reward you for it, both in this life and the next. And if He doesn’t want you to keep her, He will make it easy to separate.

If your marriage somehow naturally falls apart, with both of you, or at least you, trying your best to keep it together through non-judgmentalism, forgiveness and generosity, and you reach an agreement to separate without any negative emotions, without guilt and without fearing that you might be doing the wrong thing, then you can take that as a sign that God approves of the separation.

But if things go along normally, if things are good enough, if the thought of separation contains tremendous amounts of uncertainty, guilt and fear, then that is your sign that it is not time to separate, that if you were to work toward separation, you’d be going against the flow of the destiny God has chosen for you. You can do it, like Zayd did, since God respects your freedom. But it is better for you to accept it and do your best, constantly asking God for forgiveness and betterment. If you reject this test, God will give you an equally demanding test, because God will never stop testing you.

Until the day you die, if God loves you, He will constantly give you new opportunities to prove your patience, your generosity, your worth. If He gave you the perfect life, you’d have no opportunity to prove these things.

What I would do in your situation is this: I would do my best to improve myself as a Muslim, reading as much Quran as I can, praying tahajjud and constantly asking for God’s forgiveness. I would do my best to be kind and forgiving toward my wife no matter how distasteful I find her behavior. I would do more than what is strictly necessary to make the marriage work, for God’s sake, even if it displeases me to do this. I would always try to be the bigger person. I would put my focus on God, recognizing His power to change my wife and my life in any way He wishes, recognizing that all good things come from Him, not from my own efforts.

And if after all of this, I receive a clear sign that my marriage should end (she decides she wants divorce and is intent upon it), then I would do what is necessary in that situation. Maybe you will stay married to her for the next ten years, and after that separate to enjoy the type of life you desire. Or maybe in some years she will change into someone with as much faith as yourself, and then you may be glad that you stayed with her.

So my advice is the Prophet’s advice, : Fear God and keep her.

And leave it to God to take care of your destiny. Trying to steer your destiny is a heavy and exhausting burden. Free yourself from that burden. Enjoy the life that God has given you, do your best, constantly ask for God’s forgiveness, and know that God can put you in a better place anytime He decides. If you want to speed this process up, you can do it through worship, asking for forgiveness, and avoidance of sin.

To improve your situation in life, raise your status in God’s eye, and He will do it for you better than you ever could. Trying to improve your situation in life through your own efforts, rather than through God, will always lead to new situations that are as equally difficult as the one you left.

Patience means to go against your desire for the sake of God. If you patiently keep your wife despite your wishes, you will be rewarded for your patience. Patience might possibly the greatest virtue of a believer. The angels commend the believers on their patience when they are about to enter Paradise, as the Quran describes in Surat al-Ra`d:

22. And those who patiently seek the presence of their Lord, and pray regularly, and spend from Our provisions to them, secretly and openly, and repel evil with good. These will have the Ultimate Home.

23. Everlasting Gardens, which they will enter, along with the righteous among their parents, and their spouses, and their descendants. And the angels will enter upon them from every gate.

24. “Peace be upon you, because you endured patiently. How excellent is the Final Home.”

And do not try to push your wife to change for the better, or to buy her Islamic books, forward her Islamic articles or make her go to lectures hoping she will be better guided. Calling people to Islam should never be inflicted on people. They must seek Islam themselves.

It is God Who guides people, it is not people who guide people. Therefore no matter how hard we try or wish that someone was guided, our efforts and wishes may never come true.

You cannot guide whom you love, but God guides whom He wills, and He knows best those who are guided.2

God will not leave all the tests to you and neglect your wife. He will continue testing her too to help her grow and to guide her, but the stage she is in could be very different than yours, and the types of lessons she needs could be nothing like you imagine.

Leave it to God to guide her, He will do it in the best way possible.

On the evolution of language

Languages evolve or devolve until they reach the state of minimum energy consumption necessary for its speakers to conduct their affairs.

Low IQ descendants of speakers of English will quickly lose most of their vocabulary and complex grammatical structures if they end up on an isolated island for generations. While the complexity of the language will increase if there is a general rise in IQ as the population of speakers is held steady or increases.

The way of speaking of the upper class seems unnecessarily complicated and pretentious to the average person. Some of the upper class do make their speech more complex to show off and differentiate themselves from those below them, but since the upper class has a higher IQ than the lower classes, their speech will always be more complex.

Some people who are desperate to enter the upper class, or who are already there and have nothing better to do with their sad lives, go out of their way to use rare and unnecessarily complex words and structures to impress others with similarly sad lives, because it is apparently a mark of intelligence to use ten words when five would do.

An actually good and intelligent speaker (like George Orwell) will use the minimum number of words necessary, and the simplest available, to express their ideas. The writing’s complexity only increases when the ideas demand it. Complexity is never used when simplicity would do just as well. While a pretentious speaker, like so many philosophy professors, will use a thousand words when a single sentence would do.

A guide to adding Google Drive (and OneDrive) upload functionality to Froala

Froala is a great JavaScript editor until you try to extend its functionality. Its documentation is horrible and there is little extra functionality you can add without having to do a lot of reverse-engineering and reading of GitHub comments.

Below is a guide to my solution for adding a Google Drive button to the Froala editor.

Here is the custom black and white icon I use for Google Drive to match the style of the rest of the Froala icons. The icon is from a free icons website and doesn’t require attribution.

Setting Up the Froala Google Drive Plugin

Place the following code inside a file that is included on the page along with the rest of the plugins you use (such as the file upload plugin). You can call it froala_google_drive_plugin.js:

$.FroalaEditor.DefineIcon('googleDriveIcon', {
    SRC: '/some/path/google_drive_bw.png',
    ALT: 'Google Drive', template: 'image'
});


$.FroalaEditor.RegisterCommand('googleDriveUpload', {
    title: 'Insert File From Google Drive',
    icon: 'googleDriveIcon',
    focus: false,
    undo: false,
    refreshAfterCallback: false,
    callback: function () {
        util.saveFroalaUserPlace(); // will be covered down below
    }
});

The above code registers an icon, then registers a Froala button that uses the icon. The callback function does nothing besides storing the user’s place in the editor (or the user’s selection, if they have selected any text right before clicking the Google Drive icon), otherwise their place will be lost once we insert the file, and the file would end up at the bottom of the editor. The user’s place in the editor is saved as a Range object. This will be covered down below.

Getting the Google Drive icon to show up

On the page where you have the Froala editor, your Froala initialization code may look something like this:

var froala_buttons = ['bold', 'italic', ...];
var froala_options = {
...
toolbarButtons: froala_buttons
};

$('#froala_editor_container').froalaEditor(froala_options);

To get the Google Drive icon to show up, add its command name to the buttons array. The command name is whatever name you used as the first argument to the RegisterCommand() function above.

var froala_buttons = ['bold', 'italic', ... , 'googleDriveUpload', ...];

A new way to initialize Froala

Above, I showed the usual way of initializing Froala:

$('#froala_editor_container').froalaEditor(froala_options);

That will have to be changed to this:

$('#froala_editor_container').on('froalaEditor.initialized', function (e, editor) {
    util.initFroalaGoogleDriveUpload(editor);
}).froalaEditor(froala_options);

Here we attach an event listener to the Froala container that is called as soon as Froala is done initializing. The event listener calls a custom function util.initFroalaGoogleDriveUpload(editor) that will set up the Google Drive buttons functionality. We pass the function the editor object. This is the Froala object, giving us access to the editor and its options, which we will use for various purposes. By using the editor object, we are able to handle having multiple Froala editors on the same page without issue, being able to insert files and images into the correct editor.

The Google Drive initialization function

Below is the function that is called when Froala loads, it binds a bunch of functionality to the Google Drive button.

window.util = {
    initFroalaGoogleDriveUpload: function (editor) {
        // get the icon object from the editor using jQuery find()
        var icon_el = editor.$box.find('[id^=googleDrive]')[0];

        // add a class to the button, to use for styling
        $(icon_el).addClass('google-drive-icon');

        // get the URL to use to handle the upload, here we use the same URL
        // as the one used by the file upload plugin
        var upload_handler_url = editor.opts.fileUploadURL;

        // The function that is called right after a user selects a file in the Google Drive picker
        var pick_callback = function (file) {
            util.storeGoogleDriveFileOnServer(file, upload_handler_url, util.froalaAjaxCallback, editor); // covered down below
        };


        util.initGoogleDrivePicker(icon_el, pick_callback); // covered down below
    },
    ...
}

Handling the Google Client

Please see my blog post A guide to using PHP to download Google Drive files selected by users in the Google Drive Picker for an overview of how the Google Drive picker works. Here I will use the same methods with some changes.

Since the binding of the Google Drive icon to the Google library has to be done after the library has loaded, the library is included in this way:


function googleClientHasLoaded() {
    util.google_client_loaded = true;
}
//I  have added slashes to the HTML tags in the code snippets here
// as this article was appearing 
//broken due to the browser trying to interpret the code
<\script src="https://apis.google.com/js/client.js?onload=googleClientHasLoaded">

The util.initGoogleDrivePicker() function

This function is called once, soon after page load, to bind the Google Drive picker library to the Froala icon. It uses a timeout to detect if the Google library has loaded. If not, it waits 500 milliseconds and tries again.

The callback is the pick_callback() function that was defined in util.initFroalaGoogleDriveUpload() above. When a user selects a file in the Google Drive picker, the onSelect() function is called, which extracts information from the file object, creates a new object from it, and passes that object to pick_callback().

window.util = {
...,
google_client_loaded = false,

// I use the library at https://gist.github.com/Daniel15/5994054
// to interface with the Google Drive Picker.
initGoogleDrivePicker: function (button_el, callback) {
        if (!util.google_client_loaded) {
            setTimeout(function () {
                util.initGoogleDrivePicker(button_el, callback);
            }, 500);
            return;
        }
        var picker = new FilePicker({
            apiKey: api_key,
            clientId: client_id,
            buttonEl: button_el,
            onSelect: function (file) {
                    callback({
                        id: file.id,
                        name: file.title,
                        extension: file.fileExtension,
                        mime_type: file.mimeType,
                        access_token: gapi.auth.getToken().access_token,
                    });
            }
        });
    },

Storing the file on the server

As you remember, or perhaps don’t, the pick_callback() function is as below:

var pick_callback = function (file) {
    util.storeGoogleDriveFileOnServer(file, upload_handler_url, util.froalaAjaxCallback, editor); 
};

The util.storeGoogleDriveFileOnServer() function is as below. It sends the file’s information to the server, the server stores the file (see the blog post I linked above for the details of storing the file). The server echoes out the download URL of the file, the link that users can go to to download the file. That download url, along with the file object and the editor, are passed to the callback. The callback is util.froalaAjaxCallback(), mentioned above in the pick_callback() function and covered down below.

    storeGoogleDriveFileOnServer: function (file, handler_url, callback, editor) {
        var data = {
            file: file,
            command: 'store-google-drive-file',
        }

        $.ajax({
            url: handler_url,
            type: 'post',
            data: data,
            error: function (data) {
            },
            success: function (download_url) {
                    callback(file, download_url, editor);
            }
        });
    },

Inserting the image or link into Froala with util.froalaAjaxCallback()

At this point, the Google Drive file is stored on our local server and we have a link to it that users can go to download the file. Now we need to insert that link into the editor.

   ...,
    froalaAjaxCallback: function (file, path, editor) {
        // restore the user's place in the editor, covered down below
        util.restoreFroalaUserPlace();


        // if the user has selected some text in the editor, insert a link to the file
        // and make the selected text the link text
        if (editor.selection.text().length) {
            var link_text = editor.selection.text();
        }
        else {
            var link_text = file.name;
        }

        // if the file has an image extension in its link, insert the file as an image
        if (/[.](png|jpg|gif|jpeg|svg)/.test(path)) {
            // if user has selected text in the editor, preserve the text, otherwise it will be
            // overwritten by the image
            if (editor.selection.text().length) {
                editor.html.insert(editor.selection.text() + '<\img id="fr-inserted-file" class="fr-image" src="' + path + '" />');
            }
            else {
                editor.html.insert('<\img id="fr-inserted-file" class="fr-image" src="' + path + '" />');
            }
        }
        else { // if not an image, insert a link to the file
            editor.html.insert('<\a id="fr-inserted-file" class="fr-file" href="' + path + '">' + link_text + '');
        }

        // Get the file.
        var $file = editor.$el.find('#fr-inserted-file');

        $file.removeAttr('id');

        editor.undo.saveStep();
    },

On saving and restoring the user’s place in the editor

Below is the code used to save and restore a user’s place in the editor, and any text they may have selected, as the Google Drive picker will make them lose their place/selection. The getSelection() and restoreSelection() functions are from a StackOverflow answer.

window.util {
        ...,
        froala_user_place = false;
        saveFroalaUserPlace() {
            util.froala_user_place = util.getSelection();
        },

        restoreFroalaUserPlace() {
            util.restoreSelection(util.froala_user_place);
        },

        getSelection: function () {
            if (window.getSelection) {
                sel = window.getSelection();
                if (sel.getRangeAt && sel.rangeCount) {
                    return sel.getRangeAt(0);
                }
            } else if (document.selection && document.selection.createRange) {
                return document.selection.createRange();
            }
            return null;
        },

        restoreSelection: function (range) {
            if (range) {
                if (window.getSelection) {
                    sel = window.getSelection();
                    sel.removeAllRanges();
                    sel.addRange(range);
                } else if (document.selection && range.select) {
                    range.select();
                }
            }
        },
}

OneDrive

The above solution should be easy to extend to support OneDrive as well. See these two guides of mine if you need help with the OneDrive picker: How to get a demo of the OneDrive File Picker JavaScript SDK to work on a local development server, A guide to using PHP to download OneDrive files selected by users in the OneDrive Picker.

Conclusion

I think that’s it. Some of the code above is from memory, so it may not compile. I throw everything into the util object for demo purposes, in my actual setup things are separated out into different objects and files.

The Point

/ No Comments on The Point

The point is that there is no point.
The stars will burn out.
Our deeds will turn to dust.
Our names will be forgotten.
And the names of our children.
And the names of their children.
And the names of all humans that ever lived.

And Earth will join the Sun.
Joined in the dark, in a darkening galaxy.

All will be darkness.
There will be no sound. 
No movement. No light.
Darkness everywhere.
Darkness all around.

The point is that there is no point.
There is no need to worry about success.
There is no need to worry about where your life is going.
It is not going anywhere.

Soon, there will be no “where” for it to go to.

The point is that there is no point.
Empty are our words,
Empty are our deeds.
Our lives are going nowhere.


This is what life feels like to me without God—if there is no God to preserve our genes and deeds and resurrect us at some point in the future. Written on May 27, 2016. Also a reminder of the emptiness of all deeds and accomplishments other than those that benefit the afterlife.

A guide to using PHP to download OneDrive files selected by users in the OneDrive Picker

In my previous blog post  I described how to get the OneDrive picker to work on a local development server. In this post I will describe the second piece of the puzzle, downloading the file to a local server using PHP after the user selects it:

First, below is the JavaScript/jQuery used to open the file picker:

$(function() {
    $('.onedrive-button').click(function() {
        openOneDrivePicker();
    });
});

function openOneDrivePicker() {
    var odOptions = {
        clientId: client_id,
        action: "download",
        advanced: {
            redirectUri: redirect_uri,
        },
        multiSelect: true,
        openInNewWindow: true,
        success: function (files) { /* success handler */
            var files_array = files.value;
            for(var i in files_array) {
                window.processOneDriveFile(files_array[i]);
            }
        },
        cancel: function () { /* cancel handler */
        },
        error: function (e) { /* error handler */
        }
    }
    OneDrive.open(odOptions);
}

The success method goes through the file or files selected and calls a function called processOneDriveFile() on each one of the file objects.

Below is the code to the processOneDriveFile() function, which submits the file to a PHP handler file called file_handler.php:

// this function automatically submits the file to the server as soon
// as the user picks a file from the OneDrive picker. You may
// instead want to store the files in a variable and only submit when
// the user clicks some "Submit" button somewhere in your app.
function processOneDriveFile(file) {
    var file_name = file.name;
    var file_size = file.size;
    var download_url = file['@microsoft.graph.downloadUrl'];

    var data = {
        file_name : file_name,
        file_size : file_size,
        download_url : download_url,
        command : 'handle-onedrive-file',
    };
    
    $.ajax({
        url: '/path/to/file_handler.php',
        type: 'post',
        data: data,
        error: function (data) {
            console.debug(data);
        },
        success: function (data) {
            // success message
        }
    });
}

And here is the code for file_handler.php:

// bootstrap code

$command = $_POST['command'];

if('handle-onedrive-file' === $command) {
 $file_name = $_POST['file_name'];
 $file_size = $_POST['file_size'];
 $download_url = $_POST['download_url'];

 $ch = curl_init($download_url);
 curl_setopt($ch, CURLOPT_HEADER, 0);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);

 $data = curl_exec($ch);
 $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
 $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
 $error = curl_errno($ch);
 curl_close($ch);
 
 // A file with the same name may exist, that must be handled.
 $file_save_path = '/some/path/' . $file_name;

 file_put_contents($file_save_path, $data);
 
 echo 'File successfully retrieved and stored!';
}

That’s all. Make sure that the curl PHP library is installed and enabled (it is not sufficient to have the Linux curl utility, the code above uses the PHP library for it).

A guide to using PHP to download Google Drive files selected by users in the Google Drive Picker

Let’s say you’ve managed to get the Google Drive JavaScript Picker API to work, and have also managed to coerce your users into logging into the Picker and selecting one of their files:

And you have verified that the onSelect function works properly:

function initGoogleDrivePicker() {
    var picker = new FilePicker({
        apiKey: api_key,
        clientId: client_id,
        buttonEl: document.getElementsByClassName('google-drive-button')[0],
        onSelect: function (file) {
            console.debug(file);
        }
    });
}

Where to go from here to send the file to the server and have it saved there?

First, we’ll create a function called processGoogleDriveFile(file), which will be added to the onSelect function of the picker:

function initGoogleDrivePicker() {
    var picker = new FilePicker({
        apiKey: api_key,
        clientId: client_id,
        buttonEl: document.getElementsByClassName('google-drive-button')[0],
        onSelect: function (file) {
            processGoogleDriveFile(file);
        }
    });
}

The function will be as follows. It will extract the file’s information, then use a jQuery AJAX request to send it to a PHP file called file_handler.php:

// this function automatically submits the file to the server as soon
// as the user picks a file from the Google Drive picker. You may
// instead want to store the files in a variable and only submit when
// the user clicks some "Submit" button somewhere in your app.
function processGoogleDriveFile(file) {
    var data = {
        file_id : file.id,
        file_name : file.title,
        extension: file.fileExtension,
        mime_type : file.mimeType,
        // the function below is provided by the library
        // from https://gist.github.com/Daniel15/5994054
        access_token : gapi.auth.getToken().access_token,
        command : 'handle-google-drive-file',
    };
    
    $.ajax({
        url: '/path/to/file_handler.php',
        type: 'post',
        data: data,
        error: function (data) {
            console.debug(data);
        },
        success: function (data) {
            // success message
        }
    });
}

On the back-end side, in file_handler.php, we have the following code:

// bootstrap code

$command = $_POST['command'];

if('handle-google-drive-file' === $command) {
    $file_id = $_POST['file_id'];
    $file_name = $_POST['file_name'];
    $extension = $_POST['extension'];
    $mime_type = $_POST['mime_type'];
    $access_token = $_POST['access_token'];
    
    // if this is a Google Docs file type (Google Docs, 
    // Spreadsheets, Presentations, etc.) we convert it
    // to a PDF using the export function of the API before saving it.
    // we could convert it to other file types that are also supported
    // by the API.
    if (stripos($mime_type, 'google')) {
        $getUrl = 'https://www.googleapis.com/drive/v2/files/' . $file_id .
        '/export?mimeType=application/pdf';
        $authHeader = 'Authorization: Bearer ' . $access_token;
        $file_name = $file_name . " (converted)";
        $extension = 'pdf';
        $file_mime_type = 'application/pdf';
    }
    else { // otherwise we download it the normal way
        $getUrl = 'https://www.googleapis.com/drive/v2/files/' . $file_id . 
        '?alt=media';
        $authHeader = 'Authorization: Bearer ' . $access_token;
    }

    $ch = curl_init($getUrl);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [$authHeader]);


    $data = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error = curl_errno($ch);
    curl_close($ch);

    // 1. the file name could already have an extension in some cases,
    // that must be handled if needed.
    // 2. A file with the same name may exist, that must be handled.
    $file_save_path = '/some/path/' . $file_name . '.' . $extension;

    file_put_contents($file_save_path, $data);
    
    echo 'File successfully retrieved and stored!';
}

That’s all that is needed. Not all of Google’s proprietary MIME types can be converted to PDF. You must add a check to the onSelect or processGoogleDriveFile() JavaScript functions to check whether this is a MIME type you want to support. If it not, you can alert the user to choose another file.

Make sure that the curl PHP library is installed and enabled (it is not sufficient to have the Linux curl utility, the code above uses the PHP library for it).

How to get a demo of the OneDrive File Picker JavaScript SDK to work on a local development server

After getting the Google Drive file picker working on the page of a project I’m working on within just a few hours, I was faced with the task of getting the OneDrive JavaScript Picker to work, which I almost abandoned because of Microsoft’s brain-dead documentation. After hours of watching Microsoft videos and piecing together documentation, I finally got it to work.

Through it all, I was often reminded of this good old joke:

A helicopter was flying around above Seattle when an electrical malfunction disabled all of the aircraft's electronic navigation and communications qquipment. Due to the clouds and haze, the pilot could not determine the helicopter's position and course to fly to the airport. The pilot saw a tall building, flew toward it, circled, drew a handwritten sign, and held it in the helicopter's window. The pilot's sign said "WHERE AM I?" in large letters. People in the tall building quickly responded to the aircraft, drew a large sign and held it in a building window. Their sign read: "YOU ARE IN A HELICOPTER." The pilot smiled, waved, looked at her map, determined the course to steer to SEATAC airport, and landed safely. After they were on the ground, the co-pilot asked the pilot how the "YOU ARE IN A HELICOPTER" sign helped determine their position. The pilot responded "I knew that had to be the Microsoft building because, like their technical support, online help and product documentation, the response they gave me was technically correct, but completely useless."

So here is how to actually get their amazing picker to work. I will assume you’ve already created your app in the App Portal.

1. Enabling SSL

You must first enable SSL on your demo server if you don’t have it. To do that quickly and for free, create a self-signed certificate and install it. Here is a guide on creating a self-signed SSL certificate.

When creating the certificate, don’t forget to use the Fully Qualified Domain Name for your local server. I use the fake domain myproject.dev as the domain name for my project, and put www.myproject.dev as the FQDN.

After you have generated your .key and .crt files, put them in /etc/ssl/crt/ or some such similar place.

With that done, create an SSL virtual host that uses the files you created, as follows (this is for a PHP website). The following code will have to be added wherever you have your VirtualHosts, it could be apache2.conf, or in a new file (such as ssl_vhost.conf) placed inside the sites-available directory (/etc/apache2/sites-available). If you put it in sites-available, you will have to run the command a2endsite /etc/apache2/sites-available/the_file_name_I_used.conf to enable the vhost.


ServerName default

## Vhost docroot
DocumentRoot "/var/www/html"
SSLEngine on
SSLCertificateFile /etc/ssl/crt/myproject.crt
SSLCertificateKeyFile /etc/ssl/crt/myproject.key

## Directories, there should at least be a declaration for /var/www/html

Options Indexes FollowSymlinks MultiViews
AllowOverride All
Require all granted


Require all granted
SetHandler proxy:fcgi://127.0.0.1:9000
## Logging
ErrorLog "/var/log/apache2/default_vhost_error.log"
ServerSignature Off
CustomLog "/var/log/apache2/default_vhost_access.log" combined

## Custom fragment

2. Creating the URI Redirect File

Somewhere in your file structure, for example in /var/www/html, create a file called onedrive_picker_redirect.html (or any other name you choose). The file has to load the OneDrive JavaScript SDK, it doesn’t have to do anything else. Here is the contents of the file (note that I’m using version 7.0 of the SDK, use whichever one you want to use for your project):

3. Add a link to the redirect file in the Microsoft App Portal

Put the full SSL link to the redirect file (such as https://www.myproject.dev/onedrive_picker_redirect.html) in the App portal, as shown in the screenshot below. You can keep the Logout URL blank.

4. Add the redirect file to the OneDrive picker launcher using the “advanced” parameter

We now get to the easy part. On the file from which you want to launch the picker, add the following code to launch the picker, or modify your existing code to match below. Notice the redirectUri parameter, which has to exactly match the one you used in step 3.

5. Go to your demo page using the HTTPS URL

The picker will not work if you try to launch it from a non-https page. If you were doing your development on a non-https URL earlier, you will now have to go to the same page under https. If earlier the page was at www.myproject.dev/onedrive_picker_demo.php, now go to https://www.myproject.dev/onedrive_picker_demo.php.

6. Now try it out

Now click the button to launch the picker. You will get a login prompt. After logging in, you will get the picker. Click on any file you want and click “Open”.

7. Look at the console

To verify that everything is working properly, open the console, and if you used the picker code above that I used, you should see an object that contains the information for the file you picked:

8. Go back to square one

Now that we have gotten Microsoft’s limitless supply of self-absorbed ineptitude out of the way, we can get to do some actual coding to interface with their horrible products and discover entirely new and never-before-experienced ways of suffering.

If you want to send the file info to a server to store it there, see my blog post on using PHP to download OneDrive files picked from the picker.

Chronic fatigue update: Naps and the failure of vitamin D3 and zinc

This is an update that applies to my chronic fatigue treatment program.

A week ago I started having 2000 IU vitamin D3 and 25 mg zinc sulfate with my 3 PM meals. This helped my mind feel active and willing to learn in the evenings. I was finally able to finish Plato’s Republic and read through half of The Canterbury Tales.

Unfortunately, I experienced worsening fatigue during the day, which culminated in my not being able to get any work done at all for the past three days. Yesterday I realized that the new addition of the vitamin D3 / zinc supplements might be culprit, so I didn’t have any yesterday.

Today I feel like I’m recovering. I’m able to work again, but I have headache-like feeling in my head, like I’m recovering from brain damage, probably due to toxicity from high levels of calcium (caused by D3) and zinc sulfate.

Therefore I’m going back to my old solution for having a functioning brain in the evenings: To lie down for 45 minutes before I eat. Therefore I will be lying down from 3:00 PM to 3:45 PM, listening to an old audiobook (as new audiobooks require too much attention and will prevent proper rest).

This can be called a nap, but it is not necessary to fall asleep. I don’t like doing it since I don’t enjoy it, and I don’t feel good at the end of it, but it works. I am able to listen to new audiobooks in the evenings after doing this.

Napping after the meal doesn’t work for whatever reason.

Napping for less than 45 minutes doesn’t work. I have tried 30 minutes and didn’t get anything like the benefits of napping for 45 minutes.

Vitamin K2

It is possible that taking high doses of MK4 (a type of vitamin K2) will prevent the damaging effects of vitamin D3. 25 mg zinc is still too high and lower doses should be tried. I have run out of MK4, maybe I will try this out in a month or two.

Page 27 of 32
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32