From 34ee983becfa088d0c39c4f0d9b35f038b351a78 Mon Sep 17 00:00:00 2001 From: Developer Date: Sat, 27 Jun 2026 02:47:40 +0200 Subject: feat: add cinema module for browsing movies from hncrawler DB - Add 'cinema' database connection (hncrawler DB) to config/database.php - Create CinemaController with cinema(), show(), search() methods - Add /cinema, /cinema/movie/{imdb_id}, /cinema/search routes - Create cinema.blade.php (grid listing with posters, ratings, pagination) - Create cinema-show.blade.php (detail page with cast, genres, synopsis) - Add Cinema link to navbar - Update page title logic for cinema routes --- app/Libraries/Helper.php | 303 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 app/Libraries/Helper.php (limited to 'app/Libraries/Helper.php') diff --git a/app/Libraries/Helper.php b/app/Libraries/Helper.php new file mode 100644 index 0000000..fcf7e5b --- /dev/null +++ b/app/Libraries/Helper.php @@ -0,0 +1,303 @@ +format("Y-m-d"); + } + + public static function makeFeed($model, $title, $cache = 60) { + + switch($title) { + case("new"): + $feed_title = 'Newest Articles'; + $feed_description = 'Newest interesting articles from Wikipedia. Keep exploring.'; + break; + case( "popular"): + $feed_title = 'Popular Articles'; + $feed_description = 'The most popular articles. Keep exploring.'; + break; + case( "mastodon"): + $feed_title = 'Feed for Mastodon'; + $feed_description = 'New articles are published automatically to Mastodon.'; + break; + default: + $feed_title = 'Search for: ' . $title; + $feed_description = 'All articles for "' . $title . '".'; + break; + } + $feed_title .= " | mostdiscussed.com"; + + // create new feed + $feed = FeedFactory::create(); + + // multiple feeds are supported + // if you are using caching you should set different cache keys for your feeds + + // cache the feed for $cache minutes (second parameter is optional) + $feed->setCache($cache, 'feed_' . $title); + + // check if there is cached feed and build new only if is not + if (!$feed->isCached()) + { + + // set your feed's title, description, link, pubdate and language + $feed->setTitle($feed_title); + $feed->setDescription($feed_description); + $feed->setSubtitle($feed_description); + #$feed->setLogo('http://yoursite.tld/logo.jpg'); + $feed->setLink(url('feed/' . $title)); + $feed->setDateFormat('datetime'); // 'datetime', 'timestamp' or 'carbon' + $feed->setPubdate($model[0]->created_at); + $feed->setLang('en'); + $feed->setShortening(false); // true or false + + if ( "mastodon" == $title || "mastodon_test" == $title ) { + $feed->setTextLimit(500); // maximum length of description text + } else { + $feed->setTextLimit(100); // maximum length of description text + } + + foreach ($model as $post) + { + + $desc = ($post->excerpt_html); + $categories = null; + + if ( "mastodon" == $title || "mastodon_test" == $title ) { + + $cat_len= 0; + + if ( ! $post->getCategories()->get()->isEmpty() ) { + + $categories_ar = array("#MostDiscussed"); + + foreach( $post->getCategories()->get() as $cat ) { + + // uppercase for every word in a possible multi worded hashtag + $tmp_cat = ucwords($cat->name); + + // strip everything after / for brevity + if ( false !== strpos($tmp_cat, "/") ) + $tmp_cat = substr($tmp_cat, 0, strpos($tmp_cat, "/")); + + // replace any non-alphanumeric character except underscore, because + // it's not allowed to be used in a hashtag + $tmp_cat = preg_replace("/[^A-Za-z0-9_]/", '', $tmp_cat); + + // trim just in case + $tmp_cat = trim($tmp_cat); + + // if it's not empty, add it to the hashtag array + if ( "" != $tmp_cat ) + $categories_ar[] = "#". $tmp_cat; + } + + // remove possible duplicates (because stripping after "/") + $categories_ar = array_unique($categories_ar); + + // join to one string + $categories = implode(" ", $categories_ar); + + $cat_counter = $post->getCategories()->get()->count(); + $cat_len = mb_strlen($categories, "UTF-8"); + } + + $link = env('APP_URL') . "/article/" . $post->id; + + // max desc length is 500 - 23 (Link) - $cat_len - 2 (white spaces) + $max_len = 500 - 23 - $cat_len - 2; + + if ( "mastodon_test" == $title ) { + $desc = Helper::mastodon_summary($desc, $max_len); + }else { + $desc = Helper::first_sentence($desc, $max_len); + #$desc = Helper::mastodon_summary($desc, $max_len); + } + + $desc .= " " . $categories;# . $discussions; + + // set item's title, author, url, pubdate, description, content, enclosure (optional)* + $feed->addItem([ + 'title' => $desc, // mastofeed.org seems to ignore the description field + 'author' => env('APP_NAME'), + 'url' => $link, + 'link' => $link, + 'pubdate' => $post->created_at, + 'description' => $desc, + 'content' => $desc + ]); + + } else { + if ( ! $post->getCategories()->get()->isEmpty() ) { + $categories = "
"; + foreach( $post->getCategories()->get() as $cat ) { + $categories .= "name) ."'>". $cat->name . " | "; + } + $categories = rtrim($categories, " | "); + $desc .= "
Topics:"; + $desc .= $categories; + } + + $discussions = "
"; + foreach( $post->getDiscussions()->orderBy('comments', 'desc')->get() as $dis ) { + $discussions .= "" . $dis->title . " "; + $discussions .= $dis->upvotes . " Upvotes | " . $dis->comments . " Comments
"; + } + $desc .= "

Discussions:"; + $desc .= $discussions; + + // set item's title, author, url, pubdate, description, content, enclosure (optional)* + $feed->addItem([ + 'title' => $post->title, + 'author' => env('APP_NAME'), + 'url' => \URL::to($post->url), + 'link' => \URL::to($post->url), + 'pubdate' => $post->created_at, + 'description' => $desc, + 'content' => $desc + ]); + } + } + + } + + // first param is the feed format + // optional: second param is cache duration (value of 0 turns off caching) + // optional: you can set custom cache key with 3rd param as string + $xml = $feed->render('atom', $cache, 'feed_' . $title); + return response($xml, 200, [ + 'Content-Type' => 'application/xml' + ]); + } + + public static function first_sentence($content, $max_len = NULL) { + + $content = html_entity_decode(strip_tags($content)); + $content = ltrim($content); + $pos = strpos($content, '.'); + + if($pos === false) { + if ( is_null($max_len) ) { + return $content; + } else { + return substr($content, 0, $max_len); + } + } + else { + return substr($content, 0, $pos+1); + } + + } + + private static function next_sentence($content, $max_len = NULL) { + + $content = ltrim($content); + $pos = strpos($content, '.'); + + if($pos === false) { + if ( is_null($max_len) ) { + return $content; + } else { + return substr($content, 0, $max_len); + } + } else { + return substr($content, 0, $pos+1); + } + + } + + /** + * Make sure to toot as much text as possible while still staying below the limit of 500 chars -link (23 chars) - 2 (white spaces) - possible hashtags + */ + public static function mastodon_summary($excerpt, $max_len = 475){ + + /** + * Strip HTML from Wikipedia excerpt + */ + $excerpt = ltrim(html_entity_decode(strip_tags($excerpt))); + + /** + * The toot to be returned + */ + $content = ""; + + /** + * https://stackoverflow.com/questions/16377437/split-a-text-into-sentences + */ + $sentences = preg_split('/(?<=[.?!])\s+(?=[a-z])/i', $excerpt); + echo "
";
+		echo "-----------------------";
+		var_dump($excerpt);
+		var_dump($sentences);
+
+		for ( $i = 0; $i < count($sentences); $i++ ) {
+			#if ( mb_strlen($content) < $max_len && (mb_strlen($content) + mb_strlen($sentences) ) {
+			if ( mb_strlen($content) < $max_len && (mb_strlen($content) + mb_strlen($sentences) ) < $max_len ){
+
+				//var_dump(rtrim(ltrim($sentences[$i])));
+				$content .= rtrim(ltrim($sentences[$i]));
+				var_dump("ok", $max_len);
+
+				$max_len = $max_len - mb_strlen($sentences[$i]);
+				var_dump("ok", $max_len);
+
+			} else {
+				var_dump("fail", mb_strlen($content), $max_len);
+				break;
+			}
+		}
+		return $content;
+
+		echo "
";
+		while ( mb_strlen($content) < $max_len ) {
+
+			/**
+			 * Get next sentence
+			 */
+			$next_sentence = Helper::next_sentence($excerpt, $max_len);
+			var_dump($next_sentence);
+
+			if ( "" == $next_sentence ) {
+				break;
+			}
+
+			/**
+			 * Check if $content + $next_sentence is still under $max_len
+			 */
+			if ( (mb_strlen($content) + mb_strlen($next_sentence)) < $max_len ) {
+
+				/**
+				 * add text
+				 */
+				$content .= $next_sentence;
+
+				/**
+				 * Recalc $max_len
+				 */
+				$max_len = $max_len - mb_strlen($next_sentence);
+
+				/**
+				 * Remove sentence from excerpt
+				 */
+				$excerpt = substr($excerpt, mb_strlen($next_sentence));
+
+			} else {
+				break;
+			}
+		}
+
+		return $content;
+	}
+}
-- 
cgit v1.2.3