diff --git a/Api/Data/ItemInterface.php b/Api/Data/ItemInterface.php index 87dd6f1..66578e8 100644 --- a/Api/Data/ItemInterface.php +++ b/Api/Data/ItemInterface.php @@ -2,6 +2,9 @@ namespace GhoSter\AutoInstagramPost\Api\Data; +/** + * Interface ItemInterface + */ interface ItemInterface { diff --git a/Api/Data/ItemSearchResultInterface.php b/Api/Data/ItemSearchResultInterface.php index bd3702c..12541c6 100644 --- a/Api/Data/ItemSearchResultInterface.php +++ b/Api/Data/ItemSearchResultInterface.php @@ -4,6 +4,9 @@ use Magento\Framework\Api\SearchResultsInterface; +/** + * Interface ItemSearchResultInterface + */ interface ItemSearchResultInterface extends SearchResultsInterface { diff --git a/Api/ItemRepositoryInterface.php b/Api/ItemRepositoryInterface.php index 12c4eb7..e06c293 100644 --- a/Api/ItemRepositoryInterface.php +++ b/Api/ItemRepositoryInterface.php @@ -5,6 +5,9 @@ use Magento\Framework\Api\SearchCriteriaInterface; use GhoSter\AutoInstagramPost\Api\Data\ItemInterface; +/** + * Interface ItemRepositoryInterface + */ interface ItemRepositoryInterface { diff --git a/Api/WorkerInterface.php b/Api/WorkerInterface.php index 8761bf6..cbc7e0d 100644 --- a/Api/WorkerInterface.php +++ b/Api/WorkerInterface.php @@ -5,6 +5,9 @@ use Magento\Catalog\Model\Product; use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; +/** + * Interface WorkerInterface + */ interface WorkerInterface { diff --git a/Block/Adminhtml/Product.php b/Block/Adminhtml/Product.php index 2a3f589..ed60680 100644 --- a/Block/Adminhtml/Product.php +++ b/Block/Adminhtml/Product.php @@ -5,8 +5,9 @@ use Magento\Eav\Setup\EavSetup; /** + * Product Widget Container + * * Class Product - * @package GhoSter\AutoInstagramPost\Block\Adminhtml */ class Product extends \Magento\Backend\Block\Widget\Container { diff --git a/Block/Adminhtml/System/Config/Hashtag.php b/Block/Adminhtml/System/Config/Hashtag.php index b4d4ca0..db5f465 100644 --- a/Block/Adminhtml/System/Config/Hashtag.php +++ b/Block/Adminhtml/System/Config/Hashtag.php @@ -6,8 +6,9 @@ use GhoSter\AutoInstagramPost\Block\Adminhtml\System\Config\Hashtag\Activation; /** + * Hashtag Field + * * Class Hashtag - * @package GhoSter\AutoInstagramPost\Block\Adminhtml\System\Config */ class Hashtag extends AbstractFieldArray { diff --git a/Block/Adminhtml/System/Config/Hashtag/Activation.php b/Block/Adminhtml/System/Config/Hashtag/Activation.php index 1a89022..93dca31 100644 --- a/Block/Adminhtml/System/Config/Hashtag/Activation.php +++ b/Block/Adminhtml/System/Config/Hashtag/Activation.php @@ -7,8 +7,9 @@ use Magento\Config\Model\Config\Source\Enabledisable; /** + * Activation Select Element + * * Class Activation - * @package GhoSter\AutoInstagramPost\Block\Adminhtml\System\Config\Hashtag */ class Activation extends Select { diff --git a/Block/Adminhtml/System/Config/TestConnection.php b/Block/Adminhtml/System/Config/TestConnection.php index 6ffb405..fa9eb13 100644 --- a/Block/Adminhtml/System/Config/TestConnection.php +++ b/Block/Adminhtml/System/Config/TestConnection.php @@ -7,8 +7,9 @@ use Magento\Framework\Data\Form\Element\AbstractElement; /** + * TestConnection Field + * * Class TestConnection - * @package GhoSter\AutoInstagramPost\Block\Adminhtml\System\Config */ class TestConnection extends Field { diff --git a/Controller/Adminhtml/Manage/Index.php b/Controller/Adminhtml/Manage/Index.php index ec0c2c3..34de98c 100644 --- a/Controller/Adminhtml/Manage/Index.php +++ b/Controller/Adminhtml/Manage/Index.php @@ -9,8 +9,9 @@ use Magento\Backend\Model\View\Result\Page; /** + * Manager Index Controller + * * Class Index - * @package GhoSter\AutoInstagramPost\Controller\Adminhtml\Manage */ class Index extends ProductController { diff --git a/Controller/Adminhtml/Manage/MassPost.php b/Controller/Adminhtml/Manage/MassPost.php index 59eea5b..52a5a57 100644 --- a/Controller/Adminhtml/Manage/MassPost.php +++ b/Controller/Adminhtml/Manage/MassPost.php @@ -12,8 +12,9 @@ use GhoSter\AutoInstagramPost\Model\Config as InstagramConfig; /** + * Manager MassPost Controller + * * Class MassPost - * @package GhoSter\AutoInstagramPost\Controller\Adminhtml\Manage */ class MassPost extends Action { diff --git a/Controller/Adminhtml/Manage/Post.php b/Controller/Adminhtml/Manage/Post.php index 84fba0e..029ef6f 100644 --- a/Controller/Adminhtml/Manage/Post.php +++ b/Controller/Adminhtml/Manage/Post.php @@ -11,8 +11,9 @@ use GhoSter\AutoInstagramPost\Model\Instagram\Worker as InstagramWorker; /** + * Manager Post Controller + * * Class Post - * @package GhoSter\AutoInstagramPost\Controller\Adminhtml\Manage */ class Post extends Action { diff --git a/Controller/Adminhtml/System/Config/TestConnection.php b/Controller/Adminhtml/System/Config/TestConnection.php index 8dab4dd..6186d1a 100644 --- a/Controller/Adminhtml/System/Config/TestConnection.php +++ b/Controller/Adminhtml/System/Config/TestConnection.php @@ -11,8 +11,9 @@ use Psr\Log\LoggerInterface; /** + * Test Connection Controller + * * Class TestConnection - * @package GhoSter\AutoInstagramPost\Controller\Adminhtml\System\Config */ class TestConnection extends Action { @@ -93,7 +94,9 @@ public function execute() $responseData = [ 'success' => $status, - 'message' => $status ? __('Connection Success') : __('Unauthorized Instagram Account, check your user/password settings') + 'message' => $status + ? __('Connection Success') + : __('Unauthorized Instagram Account, check your user/password settings') ]; } else { diff --git a/Cron/SchedulePost.php b/Cron/SchedulePost.php index fe23c2d..808b173 100644 --- a/Cron/SchedulePost.php +++ b/Cron/SchedulePost.php @@ -9,8 +9,9 @@ use Psr\Log\LoggerInterface; /** + * Cron for SchedulePost + * * Class SchedulePost - * @package GhoSter\AutoInstagramPost\Cron */ class SchedulePost { diff --git a/Helper/Data.php b/Helper/Data.php index 2bb2f6d..2725cbf 100644 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -17,8 +17,9 @@ use GhoSter\AutoInstagramPost\Model\Config as InstagramConfig; /** + * AutoInstagramPost Data Helper + * * Class Data - * @package GhoSter\AutoInstagramPost\Helper */ class Data extends AbstractHelper { @@ -265,7 +266,7 @@ public function getInstagramPostDescription($product) $html = ''; $stringTemplate = $this->config->getInstagramPostTemplate(); - if (preg_match_all("~\{\{\s*(.*?)\s*\}\}~", $stringTemplate, $matches)) { + if (preg_match_all("~{{\s*(.*?)\s*}}~", $stringTemplate, $matches)) { if (isset($matches[1]) && is_array($matches[1])) { foreach ($matches[1] as $key => $match) { $addOnSpace = $key !== 0 ? self::SPACE_STRING : ''; diff --git a/Model/Config.php b/Model/Config.php index 5349cef..1432df4 100644 --- a/Model/Config.php +++ b/Model/Config.php @@ -14,8 +14,9 @@ use GhoSter\AutoInstagramPost\Model\Serialize\Serializer; /** + * AutoInstagramPost Config + * * Class Config - * @package GhoSter\AutoInstagramPost\Model */ class Config { @@ -24,6 +25,7 @@ class Config const XML_PATH_INSTAGRAM_PASSWORD = 'auto_instagram_post/general/password'; const XML_PATH_DEFAULT_IMAGE = 'auto_instagram_post/general/upload_image_id'; const XML_PATH_ENABLE_OBSERVER = 'auto_instagram_post/general/enabled_observer'; + const XML_PATH_ENABLE_DEBUG = 'auto_instagram_post/general/enable_debug'; const XML_PATH_COMMENT_ENABLED = 'auto_instagram_post/comment_hashtag/enabled'; const XML_PATH_COMMENT_PRODUCT_DESCRIPTION = 'auto_instagram_post/comment_hashtag/product_description'; @@ -184,11 +186,9 @@ public function getDefaultImage($store = null) return ''; } - $imagePath = $this->directoryList->getPath('media') + return $this->directoryList->getPath('media') . DIRECTORY_SEPARATOR . $uploadDir . DIRECTORY_SEPARATOR . $image; - - return $imagePath; } /** @@ -199,13 +199,26 @@ public function getDefaultImage($store = null) */ public function isObserverEnabled($store = null) { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( self::XML_PATH_ENABLE_OBSERVER, ScopeInterface::SCOPE_STORE, $store ); } + /** + * @param null $store + * @return bool + */ + public function isDebugEnabled($store = null) + { + return $this->scopeConfig->isSetFlag( + self::XML_PATH_ENABLE_DEBUG, + ScopeInterface::SCOPE_STORE, + $store + ); + } + /** * Check if Hashtag was enabled * diff --git a/Model/Config/Backend/Cron.php b/Model/Config/Backend/Cron.php index c90f13b..cb347fb 100644 --- a/Model/Config/Backend/Cron.php +++ b/Model/Config/Backend/Cron.php @@ -9,8 +9,9 @@ use GhoSter\AutoInstagramPost\Model\Config as InstagramConfig; /** + * Config Value for Cron + * * Class Cron - * @package GhoSter\AutoInstagramPost\Model\Config\Backend */ class Cron extends ConfigValue { diff --git a/Model/Config/Backend/Hashtag.php b/Model/Config/Backend/Hashtag.php index 92e6bb9..ad12577 100644 --- a/Model/Config/Backend/Hashtag.php +++ b/Model/Config/Backend/Hashtag.php @@ -5,8 +5,9 @@ use Magento\Config\Model\Config\Backend\Serialized\ArraySerialized; /** + * Config Value for Hashtag + * * Class Hashtag - * @package GhoSter\AutoInstagramPost\Model\Config\Backend */ class Hashtag extends ArraySerialized { diff --git a/Model/Config/Backend/Image.php b/Model/Config/Backend/Image.php index 58e04b0..35603b1 100644 --- a/Model/Config/Backend/Image.php +++ b/Model/Config/Backend/Image.php @@ -3,8 +3,9 @@ namespace GhoSter\AutoInstagramPost\Model\Config\Backend; /** + * Config Value for Image + * * Class Image - * @package GhoSter\AutoInstagramPost\Model\Config\Backend */ class Image extends \Magento\Config\Model\Config\Backend\Image { diff --git a/Model/ImageProcessor.php b/Model/ImageProcessor.php index 3922c63..672bb31 100644 --- a/Model/ImageProcessor.php +++ b/Model/ImageProcessor.php @@ -10,8 +10,9 @@ use GhoSter\AutoInstagramPost\Model\Config as InstagramConfig; /** + * AutoInstagramPost ImageProcessor + * * Class ImageProcessor - * @package GhoSter\AutoInstagramPost\Model */ class ImageProcessor { diff --git a/Model/Instagram.php b/Model/Instagram.php index 7e9a48d..ad7ce25 100644 --- a/Model/Instagram.php +++ b/Model/Instagram.php @@ -2,43 +2,97 @@ namespace GhoSter\AutoInstagramPost\Model; -use Magento\Framework\App\Filesystem\DirectoryList; +use Exception; use GhoSter\AutoInstagramPost\Model\Config as InstagramConfig; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Exception\FileSystemException; use Psr\Log\LoggerInterface; /** - * Class Instagram - * - * Rewrite Code From : https://github.com/mgp25/Instagram-API - * - * @package GhoSter\AutoInstagramPost\Model + * Class Instagram API to communicate with Instagram + * @SuppressWarnings(PHPMD.TooManyFields) + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + * @SuppressWarnings(PHPCS.Magento2.Files.LineLength.MaxExceeded) */ -//@codingStandardsIgnoreFile class Instagram { + const API_DOMAIN = 'https://i.instagram.com/'; const API_URL = 'https://i.instagram.com/api/v1/'; const USER_AGENT = 'Instagram 8.2.0 Android (18/4.3; 320dpi; 720x1280; Xiaomi; HM 1SW; armani; qcom; en_US)'; const IG_SIG_KEY = '55e91155636eaa89ba5ed619eb4645a4daf1103f2161dbfe6fd94d5ea7716095'; + /** + * phpcs:disable Generic.Files.LineLength.TooLong + */ const EXPERIMENTS = 'ig_android_progressive_jpeg,ig_creation_growth_holdout,ig_android_report_and_hide,ig_android_new_browser,ig_android_enable_share_to_whatsapp,ig_android_direct_drawing_in_quick_cam_universe,ig_android_huawei_app_badging,ig_android_universe_video_production,ig_android_asus_app_badging,ig_android_direct_plus_button,ig_android_ads_heatmap_overlay_universe,ig_android_http_stack_experiment_2016,ig_android_infinite_scrolling,ig_fbns_blocked,ig_android_white_out_universe,ig_android_full_people_card_in_user_list,ig_android_post_auto_retry_v7_21,ig_fbns_push,ig_android_feed_pill,ig_android_profile_link_iab,ig_explore_v3_us_holdout,ig_android_histogram_reporter,ig_android_anrwatchdog,ig_android_search_client_matching,ig_android_high_res_upload_2,ig_android_new_browser_pre_kitkat,ig_android_2fac,ig_android_grid_video_icon,ig_android_white_camera_universe,ig_android_disable_chroma_subsampling,ig_android_share_spinner,ig_android_explore_people_feed_icon,ig_explore_v3_android_universe,ig_android_media_favorites,ig_android_nux_holdout,ig_android_search_null_state,ig_android_react_native_notification_setting,ig_android_ads_indicator_change_universe,ig_android_video_loading_behavior,ig_android_black_camera_tab,liger_instagram_android_univ,ig_explore_v3_internal,ig_android_direct_emoji_picker,ig_android_prefetch_explore_delay_time,ig_android_business_insights_qe,ig_android_direct_media_size,ig_android_enable_client_share,ig_android_promoted_posts,ig_android_app_badging_holdout,ig_android_ads_cta_universe,ig_android_mini_inbox_2,ig_android_feed_reshare_button_nux,ig_android_boomerang_feed_attribution,ig_android_fbinvite_qe,ig_fbns_shared,ig_android_direct_full_width_media,ig_android_hscroll_profile_chaining,ig_android_feed_unit_footer,ig_android_media_tighten_space,ig_android_private_follow_request,ig_android_inline_gallery_backoff_hours_universe,ig_android_direct_thread_ui_rewrite,ig_android_rendering_controls,ig_android_ads_full_width_cta_universe,ig_video_max_duration_qe_preuniverse,ig_android_prefetch_explore_expire_time,ig_timestamp_public_test,ig_android_profile,ig_android_dv2_consistent_http_realtime_response,ig_android_enable_share_to_messenger,ig_explore_v3,ig_ranking_following,ig_android_pending_request_search_bar,ig_android_feed_ufi_redesign,ig_android_video_pause_logging_fix,ig_android_default_folder_to_camera,ig_android_video_stitching_7_23,ig_android_profanity_filter,ig_android_business_profile_qe,ig_android_search,ig_android_boomerang_entry,ig_android_inline_gallery_universe,ig_android_ads_overlay_design_universe,ig_android_options_app_invite,ig_android_view_count_decouple_likes_universe,ig_android_periodic_analytics_upload_v2,ig_android_feed_unit_hscroll_auto_advance,ig_peek_profile_photo_universe,ig_android_ads_holdout_universe,ig_android_prefetch_explore,ig_android_direct_bubble_icon,ig_video_use_sve_universe,ig_android_inline_gallery_no_backoff_on_launch_universe,ig_android_image_cache_multi_queue,ig_android_camera_nux,ig_android_immersive_viewer,ig_android_dense_feed_unit_cards,ig_android_sqlite_dev,ig_android_exoplayer,ig_android_add_to_last_post,ig_android_direct_public_threads,ig_android_prefetch_venue_in_composer,ig_android_bigger_share_button,ig_android_dv2_realtime_private_share,ig_android_non_square_first,ig_android_video_interleaved_v2,ig_android_follow_search_bar,ig_android_last_edits,ig_android_video_download_logging,ig_android_ads_loop_count_universe,ig_android_swipeable_filters_blacklist,ig_android_boomerang_layout_white_out_universe,ig_android_ads_carousel_multi_row_universe,ig_android_mentions_invite_v2,ig_android_direct_mention_qe,ig_android_following_follower_social_context'; const SIG_KEY_VERSION = '4'; const STATUS_OK = 'ok'; const STATUS_FAIL = 'fail'; - protected $username; // Instagram username - protected $password; // Instagram password - protected $debug; // Debug - - protected $uuid; // UUID - protected $deviceId; // Device ID - protected $usernameId; // Username ID - protected $token; // _csrftoken - protected $isLoggedIn = false; // Session status - protected $rankToken; // Rank token - protected $IGDataPath; // Data storage path + /** + * @var string + */ + protected $username; + + /** + * @var string + */ + protected $password; + + /** + * @var bool + */ + protected $debug; + + /** + * @var string + */ + protected $uuid; + + /** + * @var string + */ + protected $deviceId; + + /** + * @var string + */ + protected $usernameId; + + /** + * @var string + */ + protected $token; + + /** + * @var bool + */ + protected $isLoggedIn = false; + + /** + * @var string + */ + protected $rankToken; + + /** + * @var string + */ + protected $IGDataPath; + + /** + * @var DirectoryList + */ protected $directoryList; + + /** + * @var Config + */ protected $config; - protected $logger; + /** + * @var LoggerInterface + */ + protected $logger; /** * Default class constructor. @@ -47,6 +101,7 @@ class Instagram * @param InstagramConfig $config * @param LoggerInterface $logger * @param array $data + * @throws FileSystemException */ public function __construct( DirectoryList $directoryList, @@ -63,40 +118,25 @@ public function __construct( $this->directoryList = $directoryList; + $this->debug = $this->config->isDebugEnabled(); $this->IGDataPath = $this->directoryList->getPath('var') . DIRECTORY_SEPARATOR; - } + /** + * @return string + */ public function generateDeviceId() { - // This has 10 million possible hash subdivisions per clock second. + // phpcs:disable Magento2.Security.InsecureFunction $megaRandomHash = md5(number_format(microtime(true), 7, '', '')); return 'android-' . substr($megaRandomHash, 16); } - /** - * Checks whether supplied UUID is valid or not. - * - * @param string $uuid UUID to check. - * - * @return bool - */ - public static function isValidUUID( - $uuid - ) { - if (!is_string($uuid)) { - return false; - } - return (bool)preg_match('#^[a-f\d]{8}-(?:[a-f\d]{4}-){3}[a-f\d]{12}$#D', $uuid); - } - /** * Set the user. Manage multiple accounts. * - * @param string $username - * Your Instagram username. - * @param string $password - * Your Instagram password. + * @param string $username Your Instagram username. + * @param string $password Your Instagram password. */ public function setUser($username, $password) { @@ -105,17 +145,28 @@ public function setUser($username, $password) $this->uuid = $this->generateUUID(true); + // phpcs:ignore Magento2.Functions.DiscouragedFunction if ((file_exists($this->IGDataPath . "$this->username-cookies.dat")) + // phpcs:ignore Magento2.Functions.DiscouragedFunction && (file_exists($this->IGDataPath . "$this->username-userId.dat")) + // phpcs:ignore Magento2.Functions.DiscouragedFunction && (file_exists($this->IGDataPath . "$this->username-token.dat")) ) { $this->isLoggedIn = true; + // phpcs:ignore Magento2.Functions.DiscouragedFunction $this->usernameId = trim(file_get_contents($this->IGDataPath . "$username-userId.dat")); $this->rankToken = $this->usernameId . '_' . $this->uuid; + // phpcs:ignore Magento2.Functions.DiscouragedFunction $this->token = trim(file_get_contents($this->IGDataPath . "$username-token.dat")); } } + /** + * phpcs:disable Magento2.Functions.DiscouragedFunction + * + * @param bool $keepDashes + * @return string|string[] + */ public function generateUUID($keepDashes = true) { $uuid = sprintf( @@ -129,6 +180,7 @@ public function generateUUID($keepDashes = true) mt_rand(0, 0xffff), mt_rand(0, 0xffff) ); + return $keepDashes ? $uuid : str_replace('-', '', $uuid); } @@ -137,13 +189,15 @@ public function generateUUID($keepDashes = true) */ public function isLoggedIn() { - $account = $this->config->getAccountInformation(); $username = isset($account['username']) ? ($account['username']) : null; if (!empty($username)) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction if ((file_exists($this->IGDataPath . "$username-cookies.dat")) + // phpcs:ignore Magento2.Functions.DiscouragedFunction && (file_exists($this->IGDataPath . "$username-userId.dat")) + // phpcs:ignore Magento2.Functions.DiscouragedFunction && (file_exists($this->IGDataPath . "$username-token.dat")) ) { $this->isLoggedIn = true; @@ -156,18 +210,20 @@ public function isLoggedIn() /** * Login to Instagram. * - * @param bool $force - * Force login to Instagram, this will create a new session + * @param bool $force Force login to Instagram, this will create a new session * * @return bool - * Login data - * @throws \Exception + * @throws Exception */ public function login($force = false) { if (!$this->isLoggedIn || $force) { - $fetch = $this->request('si/fetch_headers/?challenge_type=signup&guid=' . $this->generateUUID(false), null, - true); + $fetch = $this->request( + 'si/fetch_headers/?challenge_type=signup&guid=' . $this->generateUUID(false), + null, + true + ); + preg_match('#Set-Cookie: csrftoken=([^;]+)#', $fetch[0], $token); $data = [ @@ -182,16 +238,18 @@ public function login($force = false) $login = $this->request('accounts/login/', $this->generateSignature(json_encode($data)), true); - if ($login[1]['status'] === 'fail') { + if ($login[1]['status'] === self::STATUS_FAIL) { return false; } $this->isLoggedIn = true; $this->usernameId = $login[1]['logged_in_user']['pk']; + // phpcs:ignore Magento2.Functions.DiscouragedFunction file_put_contents($this->IGDataPath . $this->username . '-userId.dat', $this->usernameId); $this->rankToken = $this->usernameId . '_' . $this->uuid; preg_match('#Set-Cookie: csrftoken=([^;]+)#', $login[0], $match); $this->token = $match[1]; + // phpcs:ignore Magento2.Functions.DiscouragedFunction file_put_contents($this->IGDataPath . $this->username . '-token.dat', $this->token); $this->syncFeatures(); @@ -212,16 +270,20 @@ public function login($force = false) } /** + * + * phpcs:disable Magento2.Functions.DiscouragedFunction + * * @param $endpoint * @param null $post * @param bool $login * @return array - * @throws \Exception + * @throws Exception */ protected function request($endpoint, $post = null, $login = false) { if (!$this->isLoggedIn && !$login) { - throw new \Exception("Not logged in\n"); + //phpcs:ignore Magento2.Exceptions.DirectThrow + throw new Exception("Not logged in"); } $headers = [ @@ -260,10 +322,9 @@ protected function request($endpoint, $post = null, $login = false) if ($this->debug) { $this->logger->critical("REQUEST: $endpoint\n"); - if (!is_null($post)) { + if (!empty($post)) { if (!is_array($post)) { $this->logger->critical('DATA: ' . urldecode($post) . "\n"); - } } $this->logger->critical("RESPONSE: $body\n\n"); @@ -285,7 +346,7 @@ public function generateSignature($data) /** * @return mixed - * @throws \Exception + * @throws Exception */ public function syncFeatures() { @@ -300,11 +361,19 @@ public function syncFeatures() return $this->request('qe/sync/', $this->generateSignature($data))[1]; } + /** + * @return mixed + * @throws Exception + */ protected function autoCompleteUserList() { return $this->request('friendships/autocomplete_user_list/')[1]; } + /** + * @return mixed + * @throws Exception + */ protected function timelineFeed() { return $this->request('feed/timeline/')[1]; @@ -314,322 +383,103 @@ protected function timelineFeed() * Login to Instagram. * * @return bool - * Returns true if logged out correctly + * @throws Exception */ public function logout() { $logout = $this->request('accounts/logout/'); - - if ($logout === 'ok') { - return true; - } else { - return false; - } - } - - /** - * Upload Video - * - * @param $video - * @param null $caption - * @return mixed|void - * @throws \Exception - */ - public function uploadVideo($video, $caption = null) - { - $videoData = file_get_contents($video); - - $endpoint = self::API_URL . 'upload/video/'; - $boundary = $this->uuid; - $upload_id = round(microtime(true) * 1000); - $bodies = [ - [ - 'type' => 'form-data', - 'name' => 'upload_id', - 'data' => $upload_id, - ], - [ - 'type' => 'form-data', - 'name' => '_csrftoken', - 'data' => $this->token, - ], - [ - 'type' => 'form-data', - 'name' => 'media_type', - 'data' => '2', - ], - [ - 'type' => 'form-data', - 'name' => '_uuid', - 'data' => $this->uuid, - ], - ]; - - $data = $this->buildBody($bodies, $boundary); - $headers = [ - 'Connection: keep-alive', - 'Accept: */*', - 'Host: i.instagram.com', - 'Content-type: multipart/form-data; boundary=' . $boundary, - 'Accept-Language: en-en', - ]; - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $endpoint); - curl_setopt($ch, CURLOPT_USERAGENT, self::USER_AGENT); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_HEADER, true); - curl_setopt($ch, CURLOPT_VERBOSE, false); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - curl_setopt($ch, CURLOPT_COOKIEFILE, $this->IGDataPath . "$this->username-cookies.dat"); - curl_setopt($ch, CURLOPT_COOKIEJAR, $this->IGDataPath . "$this->username-cookies.dat"); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $data); - - $resp = curl_exec($ch); - $header_len = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - - $body = json_decode(substr($resp, $header_len), true); - - $uploadUrl = $body['video_upload_urls'][3]['url']; - $job = $body['video_upload_urls'][3]['job']; - - $request_size = floor(strlen($videoData) / 4); - - $lastRequestExtra = (strlen($videoData) - ($request_size * 4)); - - for ($a = 0; $a <= 3; $a++) { - $start = ($a * $request_size); - $end = ($a + 1) * $request_size + ($a == 3 ? $lastRequestExtra : 0); - - $headers = [ - 'Connection: keep-alive', - 'Accept: */*', - 'Host: upload.instagram.com', - 'Cookie2: $Version=1', - 'Accept-Encoding: gzip, deflate', - 'Content-Type: application/octet-stream', - 'Session-ID: ' . $upload_id, - 'Accept-Language: en-en', - 'Content-Disposition: attachment; filename="video.mov"', - 'Content-Length: ' . ($end - $start), - 'Content-Range: ' . 'bytes ' . $start . '-' . ($end - 1) . '/' . strlen($videoData), - 'job: ' . $job, - ]; - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $uploadUrl); - curl_setopt($ch, CURLOPT_USERAGENT, self::USER_AGENT); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_HEADER, true); - curl_setopt($ch, CURLOPT_VERBOSE, false); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - curl_setopt($ch, CURLOPT_COOKIEFILE, $this->IGDataPath . "$this->username-cookies.dat"); - curl_setopt($ch, CURLOPT_COOKIEJAR, $this->IGDataPath . "$this->username-cookies.dat"); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, substr($videoData, $start, $end)); - - $result = curl_exec($ch); - $header_len = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - $body = substr($result, $header_len); - $array[] = [$body]; - } - $resp = curl_exec($ch); - $header_len = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - $header = substr($resp, 0, $header_len); - $upload = json_decode(substr($resp, $header_len), true); - - curl_close($ch); - - if ($upload['status'] === 'fail') { - throw new \Exception($upload['message']); - } - - if ($this->debug) { - $this->logger->critical('RESPONSE: ' . substr($resp, $header_len) . "\n\n"); - - } - - $configure = $this->configureVideo($upload_id, $video, $caption); - $this->expose(); - - return $configure; - } - - /** - * @param $bodies - * @param $boundary - * @return string - */ - protected function buildBody($bodies, $boundary) - { - $body = ''; - foreach ($bodies as $b) { - $body .= '--' . $boundary . "\r\n"; - $body .= 'Content-Disposition: ' . $b['type'] . '; name="' . $b['name'] . '"'; - if (isset($b['filename'])) { - $ext = pathinfo($b['filename'], PATHINFO_EXTENSION); - $body .= '; filename="' . 'pending_media_' . number_format(round(microtime(true) * 1000), 0, '', - '') . '.' . $ext . '"'; - } - if (isset($b['headers']) && is_array($b['headers'])) { - foreach ($b['headers'] as $header) { - $body .= "\r\n" . $header; - } - } - - $body .= "\r\n\r\n" . $b['data'] . "\r\n"; - } - $body .= '--' . $boundary . '--'; - - return $body; - } - - /** - * @param $upload_id - * @param $video - * @param string $caption - * @return mixed - * @throws \Exception - */ - protected function configureVideo($upload_id, $video, $caption = '') - { - $this->uploadPhoto($video, $caption, $upload_id); - - $size = getimagesize($video)[0]; - - $post = json_encode([ - 'upload_id' => $upload_id, - 'source_type' => '3', - 'poster_frame_index' => 0, - 'length' => 0.00, - 'audio_muted' => false, - 'filter_type' => '0', - 'video_result' => 'deprecated', - 'clips' => [ - 'length' => $this->getSeconds($video), - 'source_type' => '3', - 'camera_position' => 'back', - ], - 'extra' => [ - 'source_width' => 960, - 'source_height' => 1280, - ], - 'device' => [ - 'manufacturer' => 'Xiaomi', - 'model' => 'HM 1SW', - 'android_version' => 18, - 'android_release' => '4.3', - ], - '_csrftoken' => $this->token, - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - 'caption' => $caption, - ]); - - $post = str_replace('"length":0', '"length":0.00', $post); - - return $this->request('media/configure/?video=1', $this->generateSignature($post))[1]; + return $logout === self::STATUS_OK; } /** * Upload photo to Instagram. * * @param string $photo - * Path to your photo * @param string $caption - * Caption to be included in your photo. - * + * @param null $uploadId * @return array - * Upload data - * @throws \Exception + * @throws Exception */ - public function uploadPhoto($photo, $caption = null, $upload_id = null) + public function uploadPhoto($photo, $caption = null, $uploadId = null) { - $endpoint = self::API_URL . 'upload/photo/'; - $boundary = $this->uuid; + $endpoint = self::API_DOMAIN . 'rupload_igphoto/'; - if (!is_null($upload_id)) { + if (!empty($uploadId)) { $fileToUpload = $this->createVideoIcon($photo); } else { - $upload_id = number_format(round(microtime(true) * 1000), 0, '', ''); - $fileToUpload = file_get_contents($photo); - } - - $bodies = [ - [ - 'type' => 'form-data', - 'name' => 'upload_id', - 'data' => $upload_id, - ], - [ - 'type' => 'form-data', - 'name' => '_uuid', - 'data' => $this->uuid, - ], - [ - 'type' => 'form-data', - 'name' => '_csrftoken', - 'data' => $this->token, - ], - [ - 'type' => 'form-data', - 'name' => 'image_compression', - 'data' => '{"lib_name":"jt","lib_version":"1.3.0","quality":"70"}', - ], - [ - 'type' => 'form-data', - 'name' => 'photo', - 'data' => $fileToUpload, - 'filename' => 'pending_media_' . number_format(round(microtime(true) * 1000), 0, '', '') . '.jpg', - 'headers' => [ - 'Content-Transfer-Encoding: binary', - 'Content-type: application/octet-stream', - ], - ], + $uploadId = number_format(round(microtime(true) * 1000), 0, '', ''); + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $fileToUpload = file_get_contents($photo, FILE_BINARY); + } + + $uploadName = "fb_uploader_" . $uploadId; + $endpoint = $endpoint . $uploadName; + + $uploadParams = [ + 'retry_context' => '{"num_step_auto_retry":0,"num_reupload":0,"num_step_manual_retry":0}', + 'media_type' => '1', + 'xsharing_user_ids' => '[]', + 'upload_id' => $uploadId, + 'image_compression' => json_encode( + ['lib_name' => 'moz', 'lib_version' => '3.1.m', 'quality' => '80'] + ) ]; - $data = $this->buildBody($bodies, $boundary); $headers = [ - 'Connection: close', - 'Accept: */*', - 'Content-type: multipart/form-data; boundary=' . $boundary, - 'Content-Length: ' . strlen($data), - 'Cookie2: $Version=1', - 'Accept-Language: en-US', 'Accept-Encoding: gzip', + 'X-Instagram-Rupload-Params: ' . json_encode($uploadParams), + 'X_FB_PHOTO_WATERFALL_ID: ' . $this->generateUUID(true), + 'X-Entity-Type: image/jpeg', + 'Offset: 0', + 'X-Entity-Name: ' . $uploadName, + 'X-Entity-Length: ' . strlen($fileToUpload), + 'Content-Type: application/octet-stream', ]; + // phpcs:ignore Magento2.Functions.DiscouragedFunction $ch = curl_init(); + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_setopt($ch, CURLOPT_URL, $endpoint); + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_setopt($ch, CURLOPT_USERAGENT, self::USER_AGENT); + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_setopt($ch, CURLOPT_HEADER, true); + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_setopt($ch, CURLOPT_VERBOSE, $this->debug); + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_setopt($ch, CURLOPT_COOKIEFILE, $this->IGDataPath . "$this->username-cookies.dat"); + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_setopt($ch, CURLOPT_COOKIEJAR, $this->IGDataPath . "$this->username-cookies.dat"); + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + // phpcs:ignore Magento2.Functions.DiscouragedFunction + curl_setopt($ch, CURLOPT_POSTFIELDS, $fileToUpload); + // phpcs:ignore Magento2.Functions.DiscouragedFunction $resp = curl_exec($ch); - $header_len = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - $header = substr($resp, 0, $header_len); - $upload = json_decode(substr($resp, $header_len), true); + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $headerLength = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + $upload = json_decode(substr($resp, $headerLength), true); + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_close($ch); - if ($upload['status'] === 'fail') { + if ($upload['status'] === self::STATUS_FAIL) { return []; } if ($this->debug) { - $this->logger->critical('RESPONSE: ' . substr($resp, $header_len) . "\n\n"); + $this->logger->critical('RESPONSE: ' . substr($resp, $headerLength) . "\n\n"); } $configure = $this->configure($upload['upload_id'], $photo, $caption); @@ -640,36 +490,39 @@ public function uploadPhoto($photo, $caption = null, $upload_id = null) /** * Creating a video icon/thumbnail - * @param string $file - * path to the video file - * @return image - * icon/thumbnail for the video + * phpcs:disable Generic.PHP.NoSilencedErrors + * phpcs:disable Magento2.Security.InsecureFunction + * + * @param string $file path to the video file + * @return false|string */ - - function createVideoIcon($file) + public function createVideoIcon($file) { - /* should install ffmpeg for the method to work successfully */ $ffmpeg = $this->checkFFMPEG(); if ($ffmpeg) { - //generate thumbnail + //phpcs:ignore Magento2.Security.InsecureFunction $preview = sys_get_temp_dir() . '/' . md5($file) . '.jpg'; + // phpcs:disable Magento2.Functions.DiscouragedFunction.Discouraged @unlink($preview); - //capture video preview $command = $ffmpeg . ' -i "' . $file . '" -f mjpeg -ss 00:00:01 -vframes 1 "' . $preview . '" 2>&1'; @exec($command); return $this->createIconGD($preview); } + + return false; } /** * Check for ffmpeg/avconv dependencies - * @return string/boolean - * name of the library if present, false otherwise + * + * phpcs:disable Generic.PHP.NoSilencedErrors + * phpcs:disable Magento2.Security.InsecureFunction + * + * @return string|boolean name of the library if present, false otherwise */ - - function checkFFMPEG() + public function checkFFMPEG() { @exec('ffmpeg -version 2>&1', $output, $returnvalue); if ($returnvalue === 0) { @@ -686,13 +539,12 @@ function checkFFMPEG() /** * Implements the actual logic behind creating the icon/thumbnail * - * @param string $file - * path to the file name + * @param string $file path to the file name * - * @return image - * icon/thumbnail for the video + * @param int $size + * @return string|false icon/thumbnail for the video */ - function createIconGD($file, $size = 100, $raw = true) + public function createIconGD($file, $size = 100) { list($width, $height) = getimagesize($file); if ($width > $height) { @@ -720,6 +572,13 @@ function createIconGD($file, $size = 100, $raw = true) return $i; } + /** + * @param $upload_id + * @param $photo + * @param string $caption + * @return mixed + * @throws Exception + */ protected function configure($upload_id, $photo, $caption = '') { $size = getimagesize($photo)[0]; @@ -757,7 +616,7 @@ protected function configure($upload_id, $photo, $caption = '') } /** - * @throws \Exception + * @throws Exception */ protected function expose() { @@ -771,1122 +630,4 @@ protected function expose() $this->request('qe/expose/', $this->generateSignature($data))[1]; } - - /** - * Length of the file in Seconds - * - * @param string $file - * path to the file name - * - * @return integer - * length of the file in seconds - */ - - function getSeconds($file) - { - $ffmpeg = $this->checkFFMPEG(); - if ($ffmpeg) { - $time = exec("$ffmpeg -i " . $file . " 2>&1 | grep 'Duration' | cut -d ' ' -f 4"); - $duration = explode(':', $time); - $seconds = $duration[0] * 3600 + $duration[1] * 60 + round($duration[2]); - - return $seconds; - } - - return mt_rand(15, 300); - } - - /** - * @param $media_id - * @param $recipients - * @param null $text - */ - public function direct_share($media_id, $recipients, $text = null) - { - if (!is_array($recipients)) { - $recipients = [$recipients]; - } - - $string = []; - foreach ($recipients as $recipient) { - $string[] = "\"$recipient\""; - } - - $recipeint_users = implode(',', $string); - - $endpoint = self::API_URL . 'direct_v2/threads/broadcast/media_share/?media_type=photo'; - $boundary = $this->uuid; - $bodies = [ - [ - 'type' => 'form-data', - 'name' => 'media_id', - 'data' => $media_id, - ], - [ - 'type' => 'form-data', - 'name' => 'recipient_users', - 'data' => "[[$recipeint_users]]", - ], - [ - 'type' => 'form-data', - 'name' => 'client_context', - 'data' => $this->uuid, - ], - [ - 'type' => 'form-data', - 'name' => 'thread_ids', - 'data' => '["0"]', - ], - [ - 'type' => 'form-data', - 'name' => 'text', - 'data' => is_null($text) ? '' : $text, - ], - ]; - - $data = $this->buildBody($bodies, $boundary); - $headers = [ - 'Proxy-Connection: keep-alive', - 'Connection: keep-alive', - 'Accept: */*', - 'Content-type: multipart/form-data; boundary=' . $boundary, - 'Accept-Language: en-en', - ]; - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $endpoint); - curl_setopt($ch, CURLOPT_USERAGENT, self::USER_AGENT); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_HEADER, true); - curl_setopt($ch, CURLOPT_VERBOSE, $this->debug); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - curl_setopt($ch, CURLOPT_COOKIEFILE, $this->IGDataPath . "$this->username-cookies.dat"); - curl_setopt($ch, CURLOPT_COOKIEJAR, $this->IGDataPath . "$this->username-cookies.dat"); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $data); - - $resp = curl_exec($ch); - $header_len = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - $header = substr($resp, 0, $header_len); - $upload = json_decode(substr($resp, $header_len), true); - - curl_close($ch); - } - - /** - * Edit media. - * - * @param string $mediaId - * Media id - * @param string $captionText - * Caption text - * - * @return array - * edit media data - */ - public function editMedia($mediaId, $captionText = '') - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - '_csrftoken' => $this->token, - 'caption_text' => $captionText, - ]); - - return $this->request("media/$mediaId/edit_media/", $this->generateSignature($data))[1]; - } - - /** - * Remove yourself from a tagged media. - * - * @param string $mediaId - * Media id - * - * @return array - * edit media data - */ - public function removeSelftag($mediaId) - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - '_csrftoken' => $this->token, - ]); - - return $this->request("usertags/$mediaId/remove/", $this->generateSignature($data))[1]; - } - - /** - * Media info - * - * @param string $mediaId - * Media id - * - * @return array - * delete request data - */ - public function mediaInfo($mediaId) - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - '_csrftoken' => $this->token, - 'media_id' => $mediaId, - ]); - - return $this->request("media/$mediaId/info/", $this->generateSignature($data))[1]; - } - - /** - * Delete photo or video. - * - * @param string $mediaId - * Media id - * - * @return array - * delete request data - */ - public function deleteMedia($mediaId) - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - '_csrftoken' => $this->token, - 'media_id' => $mediaId, - ]); - - return $this->request("media/$mediaId/delete/", $this->generateSignature($data))[1]; - } - - /** - * Comment media. - * - * @param string $mediaId - * Media id - * @param string $commentText - * Comment Text - * - * @return array - * comment media data - */ - public function comment($mediaId, $commentText) - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - '_csrftoken' => $this->token, - 'comment_text' => $commentText, - ]); - - return $this->request("media/$mediaId/comment/", $this->generateSignature($data))[1]; - } - - /** - * Delete Comment. - * - * @param string $mediaId - * Media ID - * @param string $commentId - * Comment ID - * - * @return array - * Delete comment data - */ - public function deleteComment($mediaId, $captionText, $commentId) - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - '_csrftoken' => $this->token, - 'caption_text' => $captionText, - ]); - - return $this->request("media/$mediaId/comment/$commentId/delete/", $this->generateSignature($data))[1]; - } - - /** - * Sets account to public. - * - * @param string $photo - * @return bool - */ - - public function changeProfilePicture($photo) - { - if (is_null($photo)) { - $this->logger->critical("Photo not valid\n\n"); - return false; - } - - $uData = json_encode([ - '_csrftoken' => $this->token, - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - ]); - - $endpoint = self::API_URL . 'accounts/change_profile_picture/'; - $boundary = $this->uuid; - $bodies = [ - [ - 'type' => 'form-data', - 'name' => 'ig_sig_key_version', - 'data' => self::SIG_KEY_VERSION, - ], - [ - 'type' => 'form-data', - 'name' => 'signed_body', - 'data' => hash_hmac('sha256', $uData, self::IG_SIG_KEY) . $uData, - ], - [ - 'type' => 'form-data', - 'name' => 'profile_pic', - 'data' => file_get_contents($photo), - 'filename' => 'profile_pic', - 'headers' => [ - 'Content-type: application/octet-stream', - 'Content-Transfer-Encoding: binary', - ], - ], - ]; - - $data = $this->buildBody($bodies, $boundary); - $headers = [ - 'Proxy-Connection: keep-alive', - 'Connection: keep-alive', - 'Accept: */*', - 'Content-type: multipart/form-data; boundary=' . $boundary, - 'Accept-Language: en-en', - 'Accept-Encoding: gzip, deflate', - ]; - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $endpoint); - curl_setopt($ch, CURLOPT_USERAGENT, self::USER_AGENT); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_HEADER, true); - curl_setopt($ch, CURLOPT_VERBOSE, $this->debug); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - curl_setopt($ch, CURLOPT_COOKIEFILE, $this->IGDataPath . "$this->username-cookies.dat"); - curl_setopt($ch, CURLOPT_COOKIEJAR, $this->IGDataPath . "$this->username-cookies.dat"); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $data); - - $resp = curl_exec($ch); - $header_len = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - $header = substr($resp, 0, $header_len); - $upload = json_decode(substr($resp, $header_len), true); - - curl_close($ch); - } - - /** - * Remove profile picture. - * - * @return array - * status request data - */ - public function removeProfilePicture() - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - '_csrftoken' => $this->token, - ]); - - return $this->request('accounts/remove_profile_picture/', $this->generateSignature($data))[1]; - } - - /** - * Sets account to private. - * - * @return array - * status request data - */ - public function setPrivateAccount() - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - '_csrftoken' => $this->token, - ]); - - return $this->request('accounts/set_private/', $this->generateSignature($data))[1]; - } - - /** - * Sets account to public. - * - * @return array - * status request data - */ - public function setPublicAccount() - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - '_csrftoken' => $this->token, - ]); - - return $this->request('accounts/set_public/', $this->generateSignature($data))[1]; - } - - /** - * Get personal profile data. - * - * @return array - * profile data - */ - public function getProfileData() - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - '_csrftoken' => $this->token, - ]); - - return $this->request('accounts/current_user/?edit=true', $this->generateSignature($data))[1]; - } - - /** - * Edit profile. - * - * @param string $url - * Url - website. "" for nothing - * @param string $phone - * Phone number. "" for nothing - * @param string $first_name - * Name. "" for nothing - * @param string $email - * Email. Required. - * @param int $gender - * Gender. male = 1 , female = 0 - * - * @return array - * edit profile data - */ - public function editProfile($url, $phone, $first_name, $biography, $email, $gender) - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - '_csrftoken' => $this->token, - 'external_url' => $url, - 'phone_number' => $phone, - 'username' => $this->username, - 'full_name' => $first_name, - 'biography' => $biography, - 'email' => $email, - 'gender' => $gender, - ]); - - return $this->request('accounts/edit_profile/', $this->generateSignature($data))[1]; - } - - /** - * Get self username info. - * - * @return array - * Username data - */ - public function getSelfUsernameInfo() - { - return $this->getUsernameInfo($this->usernameId); - } - - /** - * Get username info. - * - * @param string $usernameId - * Username id - * - * @return array - * Username data - */ - public function getUsernameInfo($usernameId) - { - return $this->request("users/$usernameId/info/")[1]; - } - - /** - * Get recent activity. - * - * @return array - * Recent activity data - * @throws \Exception - */ - public function getRecentActivity() - { - $activity = $this->request('news/inbox/?')[1]; - - if ($activity['status'] !== 'ok') { - throw new \Exception($activity['message'] . "\n"); - } - - return $activity; - } - - /** - * Get recent activity from accounts followed. - * - * @return array - * Recent activity data of follows - * @throws \Exception - */ - public function getFollowingRecentActivity() - { - $activity = $this->request('news/?')[1]; - - if ($activity['status'] !== 'ok') { - throw new \Exception($activity['message'] . "\n"); - } - - return $activity; - } - - /** - * I dont know this yet. - * - * @return array - * v2 inbox data - * @throws \Exception - */ - public function getv2Inbox() - { - $inbox = $this->request('direct_v2/inbox/?')[1]; - - if ($inbox['status'] !== 'ok') { - throw new \Exception($inbox['message'] . "\n"); - } - - return $inbox; - } - - /** - * Get self user tags. - * - * @return array - * self user tags data - */ - public function getSelfUserTags() - { - return $this->getUserTags($this->usernameId); - } - - /** - * Get user tags. - * - * @param string $usernameId - * - * @return array - * user tags data - * @throws \Exception - */ - public function getUserTags($usernameId) - { - $tags = $this->request("usertags/$usernameId/feed/?rank_token=$this->rankToken&ranked_content=true&")[1]; - - if ($tags['status'] !== 'ok') { - throw new \Exception($tags['message'] . "\n"); - } - - return $tags; - } - - /** - * Get tagged media. - * - * @param string $tag - * - * @return array - * @throws \Exception - */ - - public function tagFeed($tag) - { - $userFeed = $this->request("feed/tag/$tag/?rank_token=$this->rankToken&ranked_content=true&")[1]; - - if ($userFeed['status'] !== 'ok') { - throw new \Exception($userFeed['message'] . "\n"); - } - - return $userFeed; - } - - /** - * Get media likers. - * - * @param string $mediaId - * - * @return array - * @throws \Exception - */ - public function getMediaLikers($mediaId) - { - $likers = $this->request("media/$mediaId/likers/?")[1]; - if ($likers['status'] !== 'ok') { - throw new \Exception($likers['message'] . "\n"); - } - - return $likers; - } - - /** - * Get self user locations media. - * - * @return array - * Geo Media data - */ - public function getSelfGeoMedia() - { - return $this->getGeoMedia($this->usernameId); - } - - /** - * Get user locations media. - * - * @param string $usernameId - * Username id - * - * @return array - * Geo Media data - * @throws \Exception - */ - public function getGeoMedia($usernameId) - { - $locations = $this->request("maps/user/$usernameId/")[1]; - - if ($locations['status'] !== 'ok') { - throw new \Exception($locations['message'] . "\n"); - } - - return $locations; - } - - /** - * facebook user search. - * - * @param string $query - * - * @return array - * query data - * @throws \Exception - */ - public function fbUserSearch($query) - { - $query = rawurlencode($query); - $query = $this->request("fbsearch/topsearch/?context=blended&query=$query&rank_token=$this->rankToken")[1]; - - if ($query['status'] !== 'ok') { - throw new \Exception($query['message'] . "\n"); - } - - return $query; - } - - /** - * Search users. - * - * @param string $query - * - * @return array - * query data - * @throws \Exception - */ - public function searchUsers($query) - { - $query = $this->request('users/search/?ig_sig_key_version=' . self::SIG_KEY_VERSION . "&is_typeahead=true&query=$query&rank_token=$this->rankToken")[1]; - - if ($query['status'] !== 'ok') { - throw new \Exception($query['message'] . "\n"); - } - - return $query; - } - - /** - * Search exact username - * - * @param string usernameName username as STRING not an id - * - * @return array - * query data - * @throws \Exception - * - */ - public function searchUsername($usernameName) - { - $query = $this->request("users/$usernameName/usernameinfo/")[1]; - - if ($query['status'] !== 'ok') { - throw new \Exception($query['message'] . "\n"); - } - - return $query; - } - - /** - * Search users using addres book. - * - * @param array $contacts - * - * @return array - * query data - */ - public function syncFromAdressBook($contacts) - { - $data = 'contacts=' . json_encode($contacts, true); - - return $this->request('address_book/link/?include=extra_display_name,thumbnails', $data)[1]; - } - - /** - * Search tags. - * - * @param string $query - * - * @return array - * query data - * @throws \Exception - */ - public function searchTags($query) - { - $query = $this->request("tags/search/?is_typeahead=true&q=$query&rank_token=$this->rankToken")[1]; - - if ($query['status'] !== 'ok') { - throw new \Exception($query['message'] . "\n"); - } - - return $query; - } - - /** - * Get timeline data. - * - * @return array - * timeline data - * @throws \Exception - */ - public function getTimeline($maxid = null) - { - $timeline = $this->request( - "feed/timeline/?rank_token=$this->rankToken&ranked_content=true" - . (!is_null($maxid) ? "&max_id=" . $maxid : '') - )[1]; - - if ($timeline['status'] !== 'ok') { - throw new \Exception($timeline['message'] . "\n"); - } - - return $timeline; - } - - /** - * Get hashtag feed. - * - * @param string $hashtagString - * Hashtag string, not including the # - * - * @return array - * Hashtag feed data - * @throws \Exception - */ - public function getHashtagFeed($hashtagString, $maxid = null) - { - if (is_null($maxid)) { - $endpoint = "feed/tag/$hashtagString/?rank_token=$this->rankToken&ranked_content=true&"; - } else { - $endpoint = "feed/tag/$hashtagString/?max_id=" . $maxid . "&rank_token=$this->rankToken&ranked_content=true&"; - } - - $hashtagFeed = $this->request($endpoint)[1]; - - if ($hashtagFeed['status'] !== 'ok') { - throw new \Exception($hashtagFeed['message'] . "\n"); - } - - return $hashtagFeed; - } - - /** - * Get locations. - * - * @param string $query - * search query - * - * @return array - * Location location data - * @throws \Exception - */ - public function searchLocation($query) - { - $query = rawurlencode($query); - $endpoint = "fbsearch/places/?rank_token=$this->rankToken&query=" . $query; - - $locationFeed = $this->request($endpoint)[1]; - - if ($locationFeed['status'] !== 'ok') { - throw new \Exception($locationFeed['message'] . "\n"); - } - - return $locationFeed; - } - - /** - * Get location feed. - * - * @param string $locationId - * location id - * - * @return array - * Location feed data - * @throws \Exception - */ - public function getLocationFeed($locationId, $maxid = null) - { - if (is_null($maxid)) { - $endpoint = "feed/location/$locationId/?rank_token=$this->rankToken&ranked_content=true&"; - } else { - $endpoint = "feed/location/$locationId/?max_id=" . $maxid . "&rank_token=$this->rankToken&ranked_content=true&"; - } - - $locationFeed = $this->request($endpoint)[1]; - - if ($locationFeed['status'] !== 'ok') { - throw new \Exception($locationFeed['message'] . "\n"); - } - - return $locationFeed; - } - - /** - * Get popular feed. - * - * @return array - * popular feed data - * @throws \Exception - */ - public function getPopularFeed() - { - $popularFeed = $this->request("feed/popular/?people_teaser_supported=1&rank_token=$this->rankToken&ranked_content=true&")[1]; - - if ($popularFeed['status'] !== 'ok') { - throw new \Exception($popularFeed['message'] . "\n"); - } - - return $popularFeed; - } - - /** - * Get user followings. - * - * @param string $usernameId - * Username id - * - * @return array - * followers data - */ - public function getUserFollowings($usernameId, $maxid = null) - { - return $this->request("friendships/$usernameId/following/?max_id=$maxid&ig_sig_key_version=" . self::SIG_KEY_VERSION . "&rank_token=$this->rankToken")[1]; - } - - /** - * Get self user followers. - * - * @return array - * followers data - */ - public function getSelfUserFollowers() - { - return $this->getUserFollowers($this->usernameId); - } - - /** - * Get user followers. - * - * @param string $usernameId - * Username id - * - * @return array - * followers data - */ - public function getUserFollowers($usernameId, $maxid = null) - { - return $this->request("friendships/$usernameId/followers/?max_id=$maxid&ig_sig_key_version=" . self::SIG_KEY_VERSION . "&rank_token=$this->rankToken")[1]; - } - - /** - * Get self users we are following. - * - * @return array - * users we are following data - */ - public function getSelfUsersFollowing() - { - return $this->request('friendships/following/?ig_sig_key_version=' . self::SIG_KEY_VERSION . "&rank_token=$this->rankToken")[1]; - } - - /** - * Like photo or video. - * - * @param string $mediaId - * Media id - * - * @return array - * status request - */ - public function like($mediaId) - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - '_csrftoken' => $this->token, - 'media_id' => $mediaId, - ]); - - return $this->request("media/$mediaId/like/", $this->generateSignature($data))[1]; - } - - /** - * Unlike photo or video. - * - * @param string $mediaId - * Media id - * - * @return array - * status request - */ - public function unlike($mediaId) - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - '_csrftoken' => $this->token, - 'media_id' => $mediaId, - ]); - - return $this->request("media/$mediaId/unlike/", $this->generateSignature($data))[1]; - } - - /** - * Get media comments. - * - * @param string $mediaId - * Media id - * - * @return array - * Media comments data - */ - public function getMediaComments($mediaId) - { - return $this->request("media/$mediaId/comments/?")[1]; - } - - /** - * Set name and phone (Optional). - * - * @param string $name - * @param string $phone - * - * @return array - * Set status data - */ - public function setNameAndPhone($name = '', $phone = '') - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - 'first_name' => $name, - 'phone_number' => $phone, - '_csrftoken' => $this->token, - ]); - - return $this->request('accounts/set_phone_and_name/', $this->generateSignature($data))[1]; - } - - /** - * Get direct share. - * - * @return array - * Direct share data - */ - public function getDirectShare() - { - return $this->request('direct_share/inbox/?')[1]; - } - - /** - * Backups all your uploaded photos :). - */ - public function backup() - { - $myUploads = $this->getSelfUserFeed(); - foreach ($myUploads['items'] as $item) { - if (!is_dir($this->IGDataPath . 'backup/' . "$this->username-" . date('Y-m-d'))) { - mkdir($this->IGDataPath . 'backup/' . "$this->username-" . date('Y-m-d')); - } - file_put_contents($this->IGDataPath . 'backup/' . "$this->username-" . date('Y-m-d') . '/' . $item['id'] . '.jpg', - file_get_contents($item['image_versions2']['candidates'][0]['url'])); - } - } - - /** - * Get self user feed. - * - * @return array - * User feed data - */ - public function getSelfUserFeed() - { - return $this->getUserFeed($this->usernameId); - } - - /** - * Get user feed. - * @param string $usernameId - * Username id - * @param null $maxid - * Max Id - * @param null $minTimestamp - * Min timestamp - * @return array User feed data - * User feed data - * @throws \Exception - */ - public function getUserFeed($usernameId, $maxid = null, $minTimestamp = null) - { - $userFeed = $this->request( - "feed/user/$usernameId/?rank_token=$this->rankToken" - . (!is_null($maxid) ? "&max_id=" . $maxid : '') - . (!is_null($minTimestamp) ? "&min_timestamp=" . $minTimestamp : '') - . "&ranked_content=true" - )[1]; - - if ($userFeed['status'] !== 'ok') { - throw new \Exception($userFeed['message'] . "\n"); - } - - return $userFeed; - } - - /** - * Follow. - * - * @param string $userId - * - * @return array - * Friendship status data - */ - public function follow($userId) - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - 'user_id' => $userId, - '_csrftoken' => $this->token, - ]); - - return $this->request("friendships/create/$userId/", $this->generateSignature($data))[1]; - } - - /** - * Unfollow. - * - * @param string $userId - * - * @return array - * Friendship status data - */ - public function unfollow($userId) - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - 'user_id' => $userId, - '_csrftoken' => $this->token, - ]); - - return $this->request("friendships/destroy/$userId/", $this->generateSignature($data))[1]; - } - - /** - * Block. - * - * @param string $userId - * - * @return array - * Friendship status data - */ - public function block($userId) - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - 'user_id' => $userId, - '_csrftoken' => $this->token, - ]); - - return $this->request("friendships/block/$userId/", $this->generateSignature($data))[1]; - } - - /** - * Unblock. - * - * @param string $userId - * - * @return array - * Friendship status data - */ - public function unblock($userId) - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - 'user_id' => $userId, - '_csrftoken' => $this->token, - ]); - - return $this->request("friendships/unblock/$userId/", $this->generateSignature($data))[1]; - } - - /** - * Show User Friendship. - * - * @param string $userId - * - * @return array - * Friendship relationship data - */ - public function userFriendship($userId) - { - $data = json_encode([ - '_uuid' => $this->uuid, - '_uid' => $this->usernameId, - 'user_id' => $userId, - '_csrftoken' => $this->token, - ]); - return $this->request("friendships/show/$userId/", $this->generateSignature($data))[1]; - } - - /** - * Get liked media. - * - * @return array - * Liked media data - */ - public function getLikedMedia() - { - return $this->request('feed/liked/?')[1]; - } - - protected function megaphoneLog() - { - return $this->request('megaphone/log/')[1]; - } } diff --git a/Model/Instagram/Worker.php b/Model/Instagram/Worker.php index d897d3a..14b34da 100644 --- a/Model/Instagram/Worker.php +++ b/Model/Instagram/Worker.php @@ -14,8 +14,9 @@ use Psr\Log\LoggerInterface; /** + * Instagram Worker + * * Class Worker - * @package GhoSter\AutoInstagramPost\Model\Instagram */ class Worker implements WorkerInterface { diff --git a/Model/Item.php b/Model/Item.php index 1ad1e87..0650bde 100644 --- a/Model/Item.php +++ b/Model/Item.php @@ -6,8 +6,9 @@ use GhoSter\AutoInstagramPost\Api\Data\ItemInterface; /** + * Item Model + * * Class Item - * @package GhoSter\AutoInstagramPost\Model */ class Item extends AbstractModel implements ItemInterface { diff --git a/Model/Logger.php b/Model/Logger.php index 8d958c5..e424ef2 100644 --- a/Model/Logger.php +++ b/Model/Logger.php @@ -7,8 +7,9 @@ use GhoSter\AutoInstagramPost\Model\ItemFactory; /** + * Logger for AutoInstagramPost + * * Class Logger - * @package GhoSter\AutoInstagramPost\Model */ class Logger { diff --git a/Model/ResourceModel/Item.php b/Model/ResourceModel/Item.php index f7141c1..bdeb221 100644 --- a/Model/ResourceModel/Item.php +++ b/Model/ResourceModel/Item.php @@ -7,8 +7,9 @@ use Magento\Framework\Stdlib\DateTime\DateTime; /** + * Instagram Item ResourceModel + * * Class Item - * @package GhoSter\AutoInstagramPost\Model\ResourceModel */ class Item extends AbstractDb { diff --git a/Model/ResourceModel/Item/Collection.php b/Model/ResourceModel/Item/Collection.php index e38bfcd..e519acb 100644 --- a/Model/ResourceModel/Item/Collection.php +++ b/Model/ResourceModel/Item/Collection.php @@ -5,8 +5,9 @@ use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection; /** + * Instagram Item Collection + * * Class Collection - * @package GhoSter\AutoInstagramPost\Model\ResourceModel\Item */ class Collection extends AbstractCollection { diff --git a/Model/Serialize/Serializer.php b/Model/Serialize/Serializer.php index bc8c8f9..57e031b 100644 --- a/Model/Serialize/Serializer.php +++ b/Model/Serialize/Serializer.php @@ -3,8 +3,9 @@ namespace GhoSter\AutoInstagramPost\Model\Serialize; /** + * Serializer for deprecated Magento version + * * Class Serializer - * @package GhoSter\AutoInstagramPost\Model\Serialize */ //@codingStandardsIgnoreFile class Serializer @@ -92,4 +93,4 @@ private function _isSerialized($value, &$result = null) } return true; } -} \ No newline at end of file +} diff --git a/Model/Source/PostStatus.php b/Model/Source/PostStatus.php index 1a94ccd..2d691c0 100644 --- a/Model/Source/PostStatus.php +++ b/Model/Source/PostStatus.php @@ -7,8 +7,9 @@ use Magento\Framework\Data\OptionSourceInterface; /** + * Source PostStatus + * * Class PostStatus - * @package GhoSter\AutoInstagramPost\Model\Source */ class PostStatus extends AbstractSource implements SourceInterface, OptionSourceInterface { diff --git a/Observer/Catalog/ProductSaveAfter.php b/Observer/Catalog/ProductSaveAfter.php index 38f90d0..58941a3 100644 --- a/Observer/Catalog/ProductSaveAfter.php +++ b/Observer/Catalog/ProductSaveAfter.php @@ -14,8 +14,9 @@ use GhoSter\AutoInstagramPost\Helper\Data as InstagramHelper; /** + * Observer for Product + * * Class ProductSaveAfter - * @package GhoSter\AutoInstagramPost\Observer\Catalog */ class ProductSaveAfter implements ObserverInterface { diff --git a/Plugin/Model/Menu/BuilderPlugin.php b/Plugin/Model/Menu/BuilderPlugin.php index aea3b19..6694e19 100644 --- a/Plugin/Model/Menu/BuilderPlugin.php +++ b/Plugin/Model/Menu/BuilderPlugin.php @@ -7,8 +7,9 @@ use GhoSter\AutoInstagramPost\Model\Config as InstagramConfig; /** + * Plugin for Menu + * * Class BuilderPlugin - * @package GhoSter\AutoInstagramPost\Plugin\Model\Menu */ class BuilderPlugin { diff --git a/Plugin/Ui/DataProvider/Product/DataProviderPlugin.php b/Plugin/Ui/DataProvider/Product/DataProviderPlugin.php index 9cc3393..162329e 100644 --- a/Plugin/Ui/DataProvider/Product/DataProviderPlugin.php +++ b/Plugin/Ui/DataProvider/Product/DataProviderPlugin.php @@ -7,8 +7,9 @@ use GhoSter\AutoInstagramPost\Ui\DataProvider\Product\DataProvider; /** + * Data Provider for Grid + * * Class DataProviderPlugin - * @package GhoSter\AutoInstagramPost\Plugin\Ui\DataProvider\Product */ class DataProviderPlugin { diff --git a/README.md b/README.md index eb79f18..d726047 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This Magento 2 extension Auto Instagram Post allows you add your products immedi [![Codacy Badge](https://api.codacy.com/project/badge/Grade/bf0757d0063e489eb3bff2479964fce2)](https://www.codacy.com/app/GhoSterInc/AutoInstagramPost?utm_source=github.com&utm_medium=referral&utm_content=tuyennn/AutoInstagramPost&utm_campaign=Badge_Grade) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/thinghost) [![Build Status](https://travis-ci.org/tuyennn/AutoInstagramPost.svg?branch=master)](https://travis-ci.org/tuyennn/AutoInstagramPost) -![Version 1.1.8](https://img.shields.io/badge/Version-1.1.8-green.svg) +![Version 1.1.9](https://img.shields.io/badge/Version-1.1.9-green.svg) --- ## [![Alt GhoSter](http://thinghost.info/wp-content/uploads/2015/12/ghoster.png "thinghost.info")](http://thinghost.info) Overview diff --git a/Ui/Component/Listing/Columns/PostStatusOptions.php b/Ui/Component/Listing/Columns/PostStatusOptions.php index 4903d4e..41a4dee 100644 --- a/Ui/Component/Listing/Columns/PostStatusOptions.php +++ b/Ui/Component/Listing/Columns/PostStatusOptions.php @@ -5,10 +5,11 @@ use Magento\Ui\Component\Listing\Columns\Column; /** + * PostStatusOptions Renderer + * * Class PostStatusOptions - * @package GhoSter\AutoInstagramPost\Ui\Component\Listing\Columns + * @codeCoverageIgnore */ -// @codingStandardsIgnoreFile class PostStatusOptions extends Column { diff --git a/Ui/Component/Listing/Columns/ProductActions.php b/Ui/Component/Listing/Columns/ProductActions.php index 9e5d325..4f40056 100644 --- a/Ui/Component/Listing/Columns/ProductActions.php +++ b/Ui/Component/Listing/Columns/ProductActions.php @@ -8,6 +8,8 @@ use GhoSter\AutoInstagramPost\Model\Config as InstagramConfig; /** + * Product Actions Renderer + * * Class ProductActions * * @api @@ -71,7 +73,9 @@ public function prepareDataSource(array $dataSource) 'label' => $item['is_posted_to_instagram'] === true ? __('RePost') : __('Post'), 'confirm' => [ 'title' => __('Post "${ $.$data.name }" to Instagram'), - 'message' => $item['is_posted_to_instagram'] === true ? __('Are you sure you wan\'t to re-post this product to Instagram?') : __('Are you sure you wan\'t to post this product to Instagram?') + 'message' => $item['is_posted_to_instagram'] === true + ? __('Are you sure you wan\'t to re-post this product to Instagram?') + : __('Are you sure you wan\'t to post this product to Instagram?') ], 'hidden' => false, ]; diff --git a/Ui/DataProvider/Product/DataProvider.php b/Ui/DataProvider/Product/DataProvider.php index ec3da7a..f9cbfcb 100644 --- a/Ui/DataProvider/Product/DataProvider.php +++ b/Ui/DataProvider/Product/DataProvider.php @@ -5,8 +5,9 @@ use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; /** + * DataProvider for Grid + * * Class DataProvider - * @package GhoSter\AutoInstagramPost\Ui\DataProvider\Product */ class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider { diff --git a/composer.json b/composer.json index 1a2d0c9..f98bf8c 100644 --- a/composer.json +++ b/composer.json @@ -8,9 +8,10 @@ "magento 2 auto instagram post" ], "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0|~7.1.3|~7.2.0", + "php": "~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0", "magento/module-backend": "100.0.*|100.1.*|100.2.*|100.3.*|101.0.*", - "magento/framework": "100.0.*|100.1.*|100.2.*|100.3.*|101.0.*" + "magento/framework": "*", + "ext-json": "*" }, "require-dev": { "phpmd/phpmd": "@stable", @@ -31,7 +32,7 @@ } ], "type": "magento2-module", - "version": "1.1.8", + "version": "1.1.9", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 8f6fedd..5e21852 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -24,6 +24,7 @@ + required-entry Magento\Config\Model\Config\Backend\Encrypted 1 @@ -55,6 +56,10 @@ 1 + + + Magento\Config\Model\Config\Source\Yesno + diff --git a/etc/config.xml b/etc/config.xml index f2108aa..1111813 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -7,6 +7,7 @@ 1 + 0 0