Story Builder V2.0 Documentation

in Docs on October 17, 2019

Story Builder V2.0 Documentation

In this guide, I will consider a fresh install. If you are updating from V1, please go through the mods and update your code accordingly with the missing parts.

First, to be able to use V2 you need to have the API updated to the latest version.

You might need to add the location fix too, you can find it here:

Once you have the API installed, you can begin with the mods

APP/CONTROLLERS/INSTAGRAMCONTROLLER.PHP

Is important to say that if you have any other Story mods, it may cause conflicts.

Find the following line of code:

} else if ($type == "story") {

You will need to replace anything inside up to this line:

 } else if ($type == "album") {

For the following code, please make sure not to delete the lines above:

$media = $media_data[$media_ids[0]];
$ext = strtolower(pathinfo($media->filename, PATHINFO_EXTENSION));
$file_path = $user_files_dir."/".$m->filename;

$caption = '';
$metadata = [];

$texts = json_decode($Post->get("story_texts"), true);

if ($texts) {
    foreach ($texts as $text) {
        $caption = $text['text'] . ' ' . $caption;
    }
}

$hashtags = json_decode($Post->get("story_hashtags"), true);

if($hashtags) {
    foreach ($hashtags as $hashtag) {
        $caption = '#' . $hashtag['tag_name'] . ' ' . $caption;
    }

    $metadata['caption'] = $caption;
    $metadata['hashtags'] = $hashtags;
}

$locations = json_decode($Post->get("story_locations"), true);

if($locations) {
    foreach ($locations as $location) {
            $location_object = @unserialize($location['location']);
            if (!$location_object || !($location_object instanceof \InstagramAPI\Response\Model\Location)) {
                    $location_object = null;
            } else {
                unset($location['location']);
                $location['location_id'] = $location_object->getExternalId();

                $metadata['location'] = $location_object;
                $metadata['location_sticker'] = $location;
            }
    }
}

$mentions = json_decode($Post->get("story_usertags"), true);

if($mentions) {
    foreach ($mentions as $key => $mention) {
        $caption = $mention['username'] . ' ' . $caption;
        unset($mentions[$key]['username']);
        $mentions[$key]['is_sticker'] = true;
    }

    $metadata['story_mentions'] = $mentions;
    $metadata['caption'] = $caption;
}

$questions = json_decode($Post->get("story_questions"), true);

if ($questions) {

    $profilePicUrl = $Instagram->account->getCurrentUser()->getUser()->getProfilePicUrl();

    foreach ($questions as $question) {
        $question['profile_pic_url'] = $profilePicUrl;
    }

    $metadata['story_questions'] = $questions;
}

$polls = json_decode($Post->get("story_polls"), true);

if($polls) {
    foreach ($polls as $poll) {
        foreach ($poll['tallies'] as $tallie) {
            $tallie['font_size'] = round($tallie['font_size'], 1);
        }

    }
    
    $metadata['story_polls'] = $polls;
}

$link = $Post->get("story_link");

if ($link) $metadata['link'] = $link;

if (in_array($ext, ["mp4"])) {
    $resp = $Instagram->story->uploadVideo($file_path, $metadata);
} else {
    $img = new \InstagramAPI\Media\Photo\InstagramPhoto($file_path, [
        "targetFeed" => \InstagramAPI\Constants::FEED_STORY,
        "operation" => \InstagramAPI\Media\InstagramMedia::CROP
    ]);

    $resp = $Instagram->story->uploadPhoto($img->getFile(), $metadata);

}

$Media = Controller::model("File", $media_ids[0]);

$Media->delete();

APP/CONTROLLERS/POSTCONTROLLER.PHP

In this file around like 278 you should find this block of code:

if ($is_new) {
    $create_date = date("Y-m-d H:i:s");
} else {
    $create_date = $Post->get("create_date");
    $old_post_id = $Post->get("id");
    $Post->remove();
}

After this block please add the following code:

$hashtags = Input::post('hashtags');
$locations = Input::post('locations');
$mentions = Input::post('usertags');
$polls = Input::post('polls');
$questions = Input::post('questions');
$texts = Input::post('texts');
$sliders = Input::post('sliders');
$link = Input::post('link');

Also, after adding the code above comes the create new post block, make sure you got these parameters:

->set("story_locations", $locations ? $locations : "")
->set("story_hashtags", $hashtags ? $hashtags : "")
->set("story_usertags", $mentions ? $mentions : "")
->set("story_polls", $polls ? $polls : "")
->set("story_questions", $questions ? $questions : "")
->set("story_sliders", $sliders ? $sliders : "")
->set("story_texts", $texts ? $texts : "")
->set("story_link", $link ? $link : "")

APP/MODELS/POSTMODEL.PHP

This file is pretty simple to update. We just need to make sure we have all the required parameters for the Post.

On the following block:

$defaults = array(

Make sure that you have the following parameters:

"story_locations" => "",
"story_hashtags" => "",
"story_usertags" => "",
"story_polls" => "",
"story_questions" => "",
"story_link" => "",
"story_texts" => "",
"story_sliders" => "",

On the Insert method, make sure that on the following block:

$id = DB::table(TABLE_PREFIX.TABLE_POSTS)
	->insert(array(

You have the following parameters:

"story_locations" => $this->get("story_locations"),
"story_hashtags" => $this->get("story_hashtags"),
"story_usertags" => $this->get("story_usertags"),
"story_polls" => $this->get("story_polls"),
"story_questions" => $this->get("story_questions"),
"story_texts" => $this->get("story_texts"),
"story_sliders" => $this->get("story_sliders"),
"story_link" => $this->get("story_link"),

Also, on the Update method inside the following block:

$id = DB::table(TABLE_PREFIX.TABLE_POSTS)
	->where("id", "=", $this->get("id"))
	->update(array(

It has the following parameters:

"story_locations" => $this->get("story_locations"),
"story_hashtags" => $this->get("story_hashtags"),
"story_usertags" => $this->get("story_usertags"),
"story_questions" => $this->get("story_questions"),
"story_polls" => $this->get("story_polls"),
"story_texts" => $this->get("story_texts"),
"story_sliders" => $this->get("story_sliders"),
"story_link" => $this->get("story_link"),

All done for this file

APP/VIEW/POST.PHP

After the following line:

<script type="text/javascript" src="<?= APPURL."assets/js/post.js?v=".VERSION ?>"></script>

Add this code:

<?php  $user_modules = $AuthUser->get("settings.modules");
            if (empty($user_modules)) {
                $user_modules = [];
            }

            if (in_array('story-builder', $user_modules)) {
        ?>
        <script>
                var trans = {};
                trans.title='<?= __("Story Builder") ?>'
                trans.notice = '<?= __("Add an photo to be able to use it.") ?>'
                trans.s1='<?= __("For now you can only use the story builder with Photos") ?>';
                trans.s2='<?= __("Select what kind of sticker you want to add below") ?>';

                trans.hashtag = '<?= __("Hashtag") ?>'
                trans.hashtagText = '<?= __("Enter the hashtag in the textfield below.") ?>'
                trans.addHashtag = '<?= __("Add Hashtag") ?>'

                trans.location = '<?= __("Location") ?>'
                trans.locationText = '<?= __("Enter the Location in the search field below and search it.") ?>'
                trans.search = '<?= __("Search") ?>'

                trans.usertag = '<?= __("Usertag") ?>'
                trans.usertagText = '<?= __("Enter the Username in the textfield below.") ?>'

                trans.poll = '<?= __("Poll") ?>'
                trans.pollText = '<?= __("The Answer block will get rendered by Instagram. This means that when you save it will not appear in the preview.") ?>'
                trans.askquestion = '<?= __("Ask a question") ?>'
                trans.yes = '<?= __("Yes") ?>'
                trans.no = '<?= __("No") ?>'
                trans.addPoll = '<?= __("Add Poll") ?>'
                trans.delete = '<?= __("Delete Sticker") ?>'
                trans.link = '<?= __("Link") ?>'
                trans.linkText ='<?= __("Enter the link below, it will be added automatically") ?>'
                trans.addLink ='<?= __("Add Link ...") ?>'
                
                trans.save = '<?= __("Save") ?>'
                trans.cancel = '<?= __("Cancel") ?>'
            </script>
    <script type="text/javascript" src="<?= APPURL."/inc/plugins/story-builder/assets/js/js.storage.js" ?>"></script>
    <script type="text/javascript" src="<?= APPURL."/inc/plugins/story-builder/assets/js/story-bundle.js?v=2.2" ?>"></script>
        <?php } ?>

ASSETS/JS/POST.JS

The following block of code around line 900 needs to be replaced:

$mini_preview.find(".item").each(function() {
    var file = $(this).data("file");
    media_ids.push(file.id);
});

With the next code:

$mini_preview.find(".item").each(function() {
    media_ids.push($(this).data("id"));
});

After the following line of code:

data.location_object = $form.find(":input[name='location']").val();

You need to add the following code:

var hashtags, locations, usertags, polls, questions, sliders, texts;

if(typeof(Storages) !== "undefined") {
    var storage = Storages.localStorage;

    if(!storage.isEmpty('hashtags')) {
        hashtags  = storage.get('hashtags');
    }
    if(!storage.isEmpty('locations')) {
        locations  = storage.get('locations');
    }
    if(!storage.isEmpty('usertags')) {
        usertags = storage.get('usertags');
    }
    if(!storage.isEmpty('polls')) {
        polls = storage.get('polls');
    }
    if(!storage.isEmpty('questions')) {
        questions = storage.get('questions');
    }
    if(!storage.isEmpty('sliders')) {
        sliders = storage.get('sliders');
    }
    if(!storage.isEmpty('texts')) {
        texts = storage.get('texts');
    }
}

data.locations = JSON.stringify(locations);
data.hashtags = JSON.stringify(hashtags);
data.usertags = JSON.stringify(usertags);
data.polls = JSON.stringify(polls);
data.link = $("input[story-link]").val();
data.questions = JSON.stringify(questions);
data.sliders = JSON.stringify(sliders);
data.texts = JSON.stringify(texts);

Lastly, on the updated API we need to modify one file

APP/VENDOR/MGP25/INSTAGRAM-PHP/SRC/UTILS.PHP

In about line 980, we can find the following block:

public static function throwIfInvalidStoryMentions(
    array $storyMentions)
{
    $requiredKeys = ['user_id'];

    foreach ($storyMentions as $mention) {
        // Ensure that all keys exist.
        $missingKeys = array_keys(array_diff_key(['user_id' => 1], $mention));
        if (count($missingKeys)) {
            throw new \InvalidArgumentException(sprintf('Missing keys "%s" for mention array.', implode(', ', $missingKeys)));
        }

        foreach ($mention as $k => $v) {
            switch ($k) {
                case 'user_id':
                    if (!ctype_digit($v) && (!is_int($v) || $v < 0)) {
                        throw new \InvalidArgumentException(sprintf('Invalid value "%s" for story mention array-key "%s".', $v, $k));
                    }
                    break;
            }
        }
        self::_throwIfInvalidStoryStickerPlacement(array_diff_key($mention, array_flip($requiredKeys)), 'story mentions');
    }
}

We need it to be replaced for the following code:

    array $storyMentions)
{
    $requiredKeys = ['user_id'];

    foreach ($storyMentions as $mention) {
        // Ensure that all keys exist.
        $missingKeys = array_keys(array_diff_key(['user_id' => 1, 'is_sticker' => 1], $mention));
        if (count($missingKeys)) {
            throw new \InvalidArgumentException(sprintf('Missing keys "%s" for mention array.', implode(', ', $missingKeys)));
        }

        foreach ($mention as $k => $v) {
            switch ($k) {
                case 'user_id':
                    if (!ctype_digit($v) && (!is_int($v) || $v < 0)) {
                        throw new \InvalidArgumentException(sprintf('Invalid value "%s" for story mention array-key "%s".', $v, $k));
                    }
                    break;
                case 'is_sticker':
                    if (!is_bool($v)) {
                        throw new \InvalidArgumentException(sprintf('Invalid value "%s" for story mention array-key "%s".', $v, $k));
                    }
                    break;

            }
        }
        self::_throwIfInvalidStoryStickerPlacement(array_diff_key($mention, array_flip($requiredKeys)), 'story mentions');
    }
}

All done, if you need help or want us to install it we can do it for you, you only need to purchase our installation service.

Note:

if you get any error during license validation then manully add your license in license.oraclecode file that is located in ./inc/plugins/story-builder/license.oraclecode . Also don’t forgot to add your site in your license manager dashboard ! Thank you

Categories: Docs