<?php
namespace App\Controller;
use App\Entity\Author;
use App\Entity\Follow;
use App\Entity\Journal;
use App\Entity\User;
use App\Manager\PublicationManager;
use App\Service\Sortpublication;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\PaginatorInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
class SearchAuthorsController extends AbstractController
{
/** @var EntityManagerInterface */
private $entityManager;
/** @var LoggerInterface */
private $logger;
/**
* SearchAuthorsController constructor.
*
* @param EntityManagerInterface $entityManager
* @param LoggerInterface $logger
*/
public function __construct(EntityManagerInterface $entityManager, LoggerInterface $logger)
{
$this->entityManager = $entityManager;
$this->logger = $logger;
}
/**
* @Route("/authors" ,name="get_authors")
*
* find the authors
*/
public function callapi(Request $request,PaginatorInterface $paginator)
{
ini_set('max_execution_time', -1);
$exist=null;
$followers=[];
$manyRequests=false;
$entityManager = $this->getDoctrine()->getManager();
$auteur = trim($request->get('authorValue'));
if($auteur==''){
$requestUri=$request->getRequestUri();
if (strpos($requestUri, 'authorValue') !== false) {
return $this->redirect('/');
}
}
$checkFollowing=$entityManager->getRepository(Follow::class)->findOneBy(['following'=>trim($auteur)]);
$author_db=$entityManager->getRepository(User::class)->findBy(['fullName'=>$auteur]);
if($author_db){
$author_db=$author_db[0];
}
if($checkFollowing){
$followers=$checkFollowing->getFollowers()->getValues();
foreach ($followers as $follower){
if ($follower && $this->getUser() && $follower->getId() == $this->getUser()->getId()) {
$exist = 1;
}
}
}
$countFollowers=count($followers);
$allFollowers=$entityManager->getRepository(Follow::class)->findAll();
$test=false;
if (strpos($request->getUri(), 'authorValue') !== false){
$test=true;
}
$param = urlencode($auteur); // str_replace(' ','+',$auteur);
$data = null;
$authors=[];
$array_crossref = array();
$total=0;
$param = urlencode($auteur);
//---------------------------------------------
$checkAuteur=$entityManager->getRepository(Author::class)->searchAuteurByName($auteur);
if($checkAuteur) {
foreach ($checkAuteur as $auteur){
$auteurName=$auteur->getName();
$count=0;
$checkFollowingAuteurName=$entityManager->getRepository(Follow::class)->findOneBy(['following'=>trim($auteurName)]);
if($checkFollowingAuteurName) {
$count = count($checkFollowingAuteurName->getFollowers()->getValues());
}
$array_crossref[]=['name'=>strtolower($auteurName),'count'=>$count];
}
$array_crossref = array_map("unserialize", array_unique(array_map("serialize", $array_crossref)));
}
else {
$urlOpenAlex = "https://api.openalex.org/authors?per-page=100&page=1&search=$auteur";
$rawData = HttpClient::create()
->request('GET', $urlOpenAlex);
if ($rawData->getStatusCode() === 200) {
$rawData = $rawData->getContent();
$data = \json_decode($rawData);
if ($data) {
$data = $data->results;
foreach ($data as $author){
$auteurName=$author->display_name;
$count=0;
$checkFollowingAuteurName=$entityManager->getRepository(Follow::class)->findOneBy(['following'=>trim($auteurName)]);
if($checkFollowingAuteurName) {
$count = count($checkFollowingAuteurName->getFollowers()->getValues());
}
$array_crossref[]=['name'=>strtolower($auteurName),'count'=>$count];
// delete doublons in array crossref by name
}
$array_crossref = array_map("unserialize", array_unique(array_map("serialize", $array_crossref)));
}
}else{
try {
$rawData = HttpClient::create()
->request('GET', "https://api.crossref.org/works?query.author=$auteur&rows=40");
if ($rawData->getStatusCode() === 200) {
$rawData = $rawData->getContent();
$data = \json_decode($rawData);
if (isset($data->message->items)) {
$articles = $data->message->items;
foreach ($articles as $article) {
$auteurs = $article->author;
foreach ($auteurs as $aut) {
$family = '';
$firstname = '';
$auteurName = '';
$total = 0;
if (isset($aut->given)) {
$firstname = $aut->given;
}
if (isset($aut->family) && strtolower($aut->family) != strtolower($firstname)) {
$family = $aut->family;
}
if ($family != '' && $firstname != '') {
$auteurName = $firstname . ' ' . $family;
} elseif ($family != '') {
$auteurName = $family;
} elseif ($firstname != '') {
$auteurName = $firstname;
}
if ($auteurName
&& !in_array(strtolower($auteurName), array_column($array_crossref, 'name'))
&& strpos(strtolower($auteurName), strtolower($auteur)) !== false) {
$count = 0;
$checkFollowingAuteurName = $entityManager->getRepository(Follow::class)->findOneBy(['following' => trim($auteurName)]);
if ($checkFollowingAuteurName) {
$count = count($checkFollowingAuteurName->getFollowers()->getValues());
}
$array_crossref[] = ['name' => strtolower($auteurName), 'count' => $count];
}
}
}
}
}
} catch (TransportExceptionInterface $e) {
}
}
}
//---------------------------------------------
sort($array_crossref);
$page = $request->get("p", 1);
$perpage = 10;
$authors = $paginator->paginate($array_crossref, $page, 10);
$total = count($array_crossref);
// sort array_crossref by name
usort($array_crossref, function($a, $b) {
return $a['name'] <=> $b['name'];
});
$pages=ceil($total/$perpage);
return $this->render('refonte/authors/authors-crossref.html.twig',
[
'data'=> $data,
'parametre'=>$test,
'exist'=>$exist,
'countFollowers'=>$countFollowers,
'allFollowers'=>$allFollowers,
'array_crossref'=>$authors,
'total'=>$total,
'author_db'=>$author_db,
'manyRequests'=>$manyRequests,
"auteur"=>$auteur,
"pages"=>$pages,
"page"=>$page
]);
}
/**
* @Route("/authors/publication" ,name="get_authors_publication")
*
* find a publications of author
*/
public function callpubapi(Request $request,PublicationManager $publicationManager){
if(!$this->getUser()){
$this->addFlash('info', 'You must be logged in to access this page');
return $this->redirectToRoute('registre_user');
}
ini_set('default_socket_timeout', -1);
$exist=null;$followers=[];
$auteur = trim($request->get('auteur'));
$checkFollowing=$this->entityManager->getRepository(Follow::class)->findOneBy(['following'=>$auteur]);
$authorDB = $this->entityManager->getRepository(User::class)->findOneBy(['fullName'=>$auteur]);
$publications=[];
$suggestedJournals=[];
$selectedAuthors=[];
$authorList=[];
if($checkFollowing){
$followers=$checkFollowing->getFollowers()->getValues();
foreach ($followers as $follower){
if ($follower && $this->getUser() ){
if($follower->getId() == $this->getUser()->getId()) {
$exist=1;
}
}
}
}
$countFollowers=count($followers);
$param=str_replace(' ','+',$auteur);
$param = urlencode($auteur); // str_replace(' ','+',$auteur);
$search=false;
$data = null;
$authors1=[];
$authors2=[];
$dd1 = [];
$array = [];
$author_db = [];
$co_authors = [];
$fullName = [];
$manyRequests=false;
$gender='';
$institution='';
$country='';
$topics=[];
if(isset($data->result->hits->hit)){
$search=true;
}
// get gender of author
// $client = HttpClient::create();
// $response = $client->request('GET', 'https://api.genderize.io', [
// 'query' => [
// 'name' => $auteur
// ]
// ]);
// $statusCode = $response->getStatusCode();
// if ($statusCode === 200) {
// $content = $response->toArray();
// $gender = $content['gender'];
// }
// get gender of author end
$worksData = HttpClient::create()
->request('GET', "https://api.crossref.org/works?query.author=$auteur");
// ->request('GET', "https://api.crossref.org/works?query.bibliographic=$auteur&query.author=$auteur");
$urlOpenAlex = "https://api.openalex.org/authors?search=$auteur&per-page=100&page=1";
$rawData = HttpClient::create()
->request('GET', $urlOpenAlex);
if ($rawData->getStatusCode() === 200) {
$authorOpenAlex = [];
// if ($rawData->getStatusCode() === 200) {
$rawData = $rawData->getContent();
$data = \json_decode($rawData);
if ($data) {
$data = $data->results;
foreach ($data as $authortop) {
$auteurName = strtolower($authortop->display_name);
if($auteurName==strtolower($auteur) && !in_array($auteurName,$authorOpenAlex)){
$authorOpenAlex = $authortop;
break;
}
}
if($authorOpenAlex){
$works=$authorOpenAlex->works_api_url."&per-page=200";
$rawData = HttpClient::create()
->request('GET', $works);
if ($rawData->getStatusCode() === 200) {
$rawData = $rawData->getContent();
$data = \json_decode($rawData);
if ($data) {
$data = $data->results;
foreach ($data as $publication) {
$pages=0;
$authorsz=[];
$publicationName = $publication->display_name;
$year=$publication->publication_year;
$type=$publication->type;
$volume=$publication->biblio->volume;
$authors=$publication->authorships;
$link=$publication->id;
if($publication->biblio->last_page && $publication->biblio->first_page)
{
$pages=intval($publication->biblio->last_page)-intval($publication->biblio->first_page);
}
foreach ($authors as $a){
if(isset($a->raw_author_name)){
$authorsz[]=$a->raw_author_name;
if(!in_array($a->raw_author_name,$selectedAuthors) && strtolower($auteur)!==strtolower($a->raw_author_name)){
$selectedAuthors[]=$a->raw_author_name;
}
}
}
$publications[] = [
'title' => $publicationName,
'url' => $link,
'authors' => $authorsz,
'year' => $year,
'type' => $type,
'page' => $pages,
'volume' => $volume,
'subject' => [],
'journal' => "",
'reference_count' => 0];
}
//dd('end',$publications);
}
}
}
}
// }
usort($publications, function ($a, $b) {
return (int) $b['year'] <=> (int) $a['year'];
});
$suggestedJournals = array_filter($suggestedJournals);
$selectedAuthors = array_values($selectedAuthors);
// remove empty values from array journals
$selectedAuthors = array_filter(array_map('trim', $selectedAuthors), function($value) {
return $value !== "" && $value !== null;
});
// appliquer la fonction strtolower sur chaque élément du tableau
$selectedAuthors = array_map('strtolower', $selectedAuthors);
$selectedAuthors = array_map('trim', $selectedAuthors);
$selectedAuthors = array_unique($selectedAuthors);
if (($key = array_search(strtolower($auteur), $selectedAuthors)) !== false) {
unset($selectedAuthors[$key]);
}
// 4 items from the array of selectedAuthors
$selectedAuthors = array_slice($selectedAuthors, 0, 4);
foreach ($selectedAuthors as $a) {
// get gender of author
// $client = HttpClient::create();
// $response = $client->request('GET', 'https://api.genderize.io', [
// 'query' => [
// 'name' => $a
// ]
// ]);
// $statusCode = $response->getStatusCode();
// if ($statusCode === 200) {
// $content = $response->toArray();
// $gender = $content['gender'];
// }
// get gender of author end
$authorList[] = ['name' => $a, 'gender' => $gender];
}
}
else {
$rawData = $worksData->getContent();
if ($rawData->getStatusCode() === 200) {
$data = \json_decode($rawData);
$message = $data->message->items;
foreach ($message as $item) {
if (isset($item->title) && isset($item->type) && $item->type == "journal-article") {
$article = $item->title[0];
$url = $item->URL;
$authors = $item->author;
// get given and family name of authors
foreach ($authors as $author) {
$given = '';
$family = '';
if (isset($author->family)) {
$family = $author->family;
}
if (isset($author->given)) {
$given = $author->given;
}
$fullName[] = $given . ' ' . $family;
}
$published = ((get_object_vars($item->published)));
$year = $published['date-parts'][0];
$year = $year[0];
$title = "";
$reference_count = 0;
if (isset($item->{'container-title'}) && is_array($item->{'container-title'})) {
// Access the first element of the 'short-container-title' array
$title = $item->{'container-title'}[0];
} elseif (isset($item->{'short-container-title'}) && is_array($item->{'short-container-title'})) {
// Access the first element of the 'container-title' array
$title = $item->{'short-container-title'}[0];
}
if (isset($item->{'reference-count'})) {
$reference_count = $item->{'reference-count'};
}
$page = $item->page ?? '';
$volume = $item->volume ?? '';
$subject = $item->subject ?? '';
if ($subject) $subject = implode(',', $subject);
if (in_array($given . ' ' . $family, $fullName)) {
$publications[] = ['title' => $article, 'url' => $url, 'authors' => $fullName, 'year' => $year, 'page' => $page, 'volume' => $volume, 'subject' => $subject, 'journal' => $title, 'reference_count' => $reference_count];
}
if (!in_array($title, $suggestedJournals)) {
$suggestedJournals[] = $this->entityManager->getRepository(Journal::class)->findOneBy(['title' => $title]);
}
if (!in_array($fullName, $selectedAuthors)) {
$selectedAuthors[] = $fullName;
}
$fullName = [];
}
}
}
}
// check if the author exists in the database
$author_db=$this->entityManager->getRepository(Author::class)->findOneBy(['name'=>$auteur]);
if($author_db){
if($author_db->getLastKnownInstitutions() && count($author_db->getLastKnownInstitutions())>0){
$institution=$author_db->getLastKnownInstitutions()[0]->display_name;
$country=$author_db->getLastKnownInstitutions()[0]->country_code;
}
if($author_db->getTopics()){
foreach ($author_db->getTopics() as $topic){
$topics[]=$topic['field']['display_name'];
}
}
$topics=array_unique($topics);
// get 10 items from the array of topics
$topics = array_slice($topics, 0, 6);
}
return $this->render('refonte/authors/publications-crossref.html.twig',
[
'dataissn'=>$dd1,
'auteur'=> $auteur,
'authorDB'=>$authorDB,
'co_authors'=> $co_authors,
'exist'=> $exist,
'countFollowers'=> $countFollowers,
'author_db'=> $author_db,
'search'=> $search,
'manyRequests'=>$manyRequests,
'publications'=>$publications,
"followers"=>count($followers),
"gender"=>$gender,
"suggestedJournals"=>$suggestedJournals,
"selectedAuthors"=>$authorList,
"institution"=>$institution,
"country"=>$country,
"topics"=>$topics
]);
}
/**
* sort by date data gived by dblp api
* @param $a
* @param $b
* @return mixed
*/
public function sortdblp($a,$b){
$temp=[];
for($i=0;$i<$b;$i++){
for ($j=0;$j<$b;$j++){
if ($a[$i]->info->year > $a[$j]->info->year)
{
$temp=$a[$i];
$a[$i]=$a[$j];
$a[$j]=$temp;
}
}
}
return $a;
}
}