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; } // 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->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;
	}
}