Eligijus
Eligijus

Reputation: 643

A cleaner way to go with my controller method

I am making an app that translates a word from one language to English and gets information about it (e.g. definition, use in a sentence, synonyms, sound representation)

What my function does:

  1. Searches for the translation in the database. If it is found, we return it.
  2. If it is not found we translate a word using google translate, or Yandex translate API.
  3. If translation is found we download it's sound representation, save the translation to the database and add additional information from other API's
  4. We return a json response with all of the information.

Now my controllers method is really big and I can't find a cleaner way to go about it.

Any help is appreciated.

public function store(Request $request)
{
    $translated = $request->get('translated');
    $translation = $this->translation->findBy('translated', $translated)->first();

    if ($translation) {
        return Response::json(['translation' => $this->translation->with(['examples', 'definitions', 'synonyms', 'images'])->find($translation->id)], ResponseCode::HTTP_CREATED);
    }

    $data = $request->all();
    $data['translation'] = $this->translate($translated);

    if ($translated == $data['translation']) {
        Log::info('Translation not found: ' . $data['translation']);
        return $this->translationNotFound();
    }

    $downloader = new Downloader(new GoogleSpeechDownloader());
    $filename = $downloader->download($data['translation']);

    if ($filename) $data['sound_name'] = $filename;

    $translation = $this->translation->create($data);

    $this->createDefinition($translation);
    $this->createExample($translation);
    $this->createSynonym($translation);

    return Response::json(['translation' => $this->translation->with(['examples', 'definitions', 'synonyms', 'images'])->find($translation->id)], ResponseCode::HTTP_CREATED);
}

private function translationNotFound()
{
    return Response::json(['error' => 'Vertimas nerastas.'], ResponseCode::HTTP_NOT_FOUND);
}

private function createDefinition($translation)
{
    $definition = new Definition();
    $definer = new Definer(new DictionaryApiDefiner());
    try {
        $definition->definition = $definer->getDefinition($translation->translation);
        $definition->approved = true;
        $translation->definitions()->save($definition);
    } catch (\Exception $e) {
        Log::alert('Definition for word ' . $translation->translation . ' not found.');
    }
}

private function createExample($translation)
{
    $example = new Example();
    $exampler = new ExampleCreator(new YourDictionaryGouteParserExampler());
    try {
        $example->example = $exampler->getExample($translation->translation);
        $example->approved = true;
        $translation->examples()->save($example);
    } catch (\Exception $e) {
        Log::alert('Example for word ' . $translation->translation . ' not found.');
    }
}

private function createSynonym($translation)
{
    $creator = new SynonymCreator(new BigHugeLabsSynonymCreator());
    foreach ($creator->getSynonyms($translation->translation) as $s) {
        $synonym = new Synonym();
        $synonym->synonym = $s;
        $synonym->approved = true;
        $translation->synonyms()->save($synonym);
    }
}

private function translate($translated)
{
    $translator = new Translator(new GoogleTranslator());

    try {
        return $translator->translate($translated);
    } catch (\Exception $e) {
        Log::critical($e->getMessage());
    }

    $translator = new Translator(new YandexTranslator());
    return $translator->translate($translated);
}

Upvotes: 2

Views: 69

Answers (1)

ivant87
ivant87

Reputation: 70

If you want cleaner code, just make a class for this job. Two classes for this two API's and in the controller make the check for the word, if not exist in the database, check in the other two API's, just split every action to method in the new two classes that you will make.

Upvotes: 2

Related Questions