'Check recursively if an xblock has a path to the course root
:param block_key: BlockKey of the component whose path is to be checked
:param course: actual db json of course from structures
:param path_cache: a dictionary that records which modules have a path to the root so that we don\'t have to
double count modules if we\'re computing this for a list of modules in a course.
:param parents_cache: a dictionary containing mapping of block_key to list of its parents. Optionally, this
should be built for course structure to make this method faster.
:return Bool: whether or not component has path to the root'

def has_path_to_root(self, block_key, course, path_cache=None, parents_cache=None):

    if (path_cache and (block_key in path_cache)):
        return path_cache[block_key]
    if (parents_cache is None):
        xblock_parents = self._get_parents_from_structure(block_key, course.structure)
    else:
        xblock_parents = parents_cache[block_key]
    if ((len(xblock_parents) == 0) and (block_key.type in ['course', 'library'])):
        if (path_cache is not None):
            path_cache[block_key] = True
        return True
    has_path = any((self.has_path_to_root(xblock_parent, course, path_cache, parents_cache) for xblock_parent in xblock_parents))
    if (path_cache is not None):
        path_cache[block_key] = has_path
    return has_path
